1/* 2 * Copyright 2011 Tresys Technology, LLC. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * The views and conclusions contained in the software and documentation are those 26 * of the authors and should not be interpreted as representing official policies, 27 * either expressed or implied, of Tresys Technology, LLC. 28 */ 29 30#include <stdlib.h> 31#include <stdio.h> 32#include <string.h> 33 34#include "cil_fqn.h" 35#include "cil_internal.h" 36#include "cil_log.h" 37#include "cil_strpool.h" 38#include "cil_symtab.h" 39 40struct cil_fqn_args { 41 char prefix[CIL_MAX_NAME_LENGTH]; 42 int len; 43 struct cil_tree_node *node; 44}; 45 46static int __cil_fqn_qualify_decls(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 47{ 48 struct cil_fqn_args *fqn_args = args; 49 struct cil_symtab_datum *datum = (struct cil_symtab_datum *)d; 50 int newlen; 51 char prefix[CIL_MAX_NAME_LENGTH]; 52 int rc = SEPOL_OK; 53 54 if (fqn_args->len == 0) { 55 goto exit; 56 } 57 58 newlen = fqn_args->len + strlen(datum->name); 59 if (newlen >= CIL_MAX_NAME_LENGTH) { 60 cil_log(CIL_INFO, "Fully qualified name for %s is too long\n", datum->name); 61 rc = SEPOL_ERR; 62 goto exit; 63 } 64 strcpy(prefix, fqn_args->prefix); 65 strcat(prefix, datum->name); 66 datum->fqn = cil_strpool_add(prefix); 67 68exit: 69 return rc; 70} 71 72static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 73{ 74 struct cil_fqn_args *fqn_args = args; 75 struct cil_fqn_args child_args; 76 struct cil_block *block = (struct cil_block *)d; 77 struct cil_symtab_datum *datum = (struct cil_symtab_datum *)block; 78 struct cil_tree_node *node = NODE(datum); 79 int i; 80 int rc = SEPOL_OK; 81 int newlen; 82 83 if (node->flavor != CIL_BLOCK) { 84 goto exit; 85 } 86 87 newlen = fqn_args->len + strlen(datum->name) + 1; 88 if (newlen >= CIL_MAX_NAME_LENGTH) { 89 cil_log(CIL_INFO, "Fully qualified name for block %s is too long\n", datum->name); 90 rc = SEPOL_ERR; 91 goto exit; 92 } 93 94 child_args.node = node; 95 child_args.len = newlen; 96 strcpy(child_args.prefix, fqn_args->prefix); 97 strcat(child_args.prefix, datum->name); 98 strcat(child_args.prefix, "."); 99 100 for (i=1; i<CIL_SYM_NUM; i++) { 101 switch (i) { 102 case CIL_SYM_CLASSPERMSETS: 103 case CIL_SYM_CONTEXTS: 104 case CIL_SYM_LEVELRANGES: 105 case CIL_SYM_IPADDRS: 106 case CIL_SYM_NAMES: 107 case CIL_SYM_PERMX: 108 /* These do not show up in the kernel policy */ 109 break; 110 case CIL_SYM_POLICYCAPS: 111 /* Valid policy capability names are defined in libsepol */ 112 break; 113 default: 114 rc = cil_symtab_map(&(block->symtab[i]), __cil_fqn_qualify_decls, &child_args); 115 if (rc != SEPOL_OK) { 116 goto exit; 117 } 118 break; 119 } 120 } 121 122 rc = cil_symtab_map(&(block->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &child_args); 123 124exit: 125 if (rc != SEPOL_OK) { 126 cil_tree_log(node, CIL_ERR,"Problem qualifying names in block"); 127 } 128 129 return rc; 130} 131 132int cil_fqn_qualify(struct cil_tree_node *root_node) 133{ 134 struct cil_root *root = root_node->data; 135 struct cil_fqn_args fqn_args; 136 137 fqn_args.prefix[0] = '\0'; 138 fqn_args.len = 0; 139 fqn_args.node = root_node; 140 141 return cil_symtab_map(&(root->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &fqn_args); 142} 143 144