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_internal.h" 35 #include "cil_log.h" 36 #include "cil_strpool.h" 37 #include "cil_symtab.h" 38 39 struct cil_fqn_args { 40 char prefix[CIL_MAX_NAME_LENGTH]; 41 int len; 42 struct cil_tree_node *node; 43 }; 44 45 static int __cil_fqn_qualify_decls(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 46 { 47 struct cil_fqn_args *fqn_args = args; 48 struct cil_symtab_datum *datum = (struct cil_symtab_datum *)d; 49 int newlen; 50 char prefix[CIL_MAX_NAME_LENGTH]; 51 int rc = SEPOL_OK; 52 53 if (fqn_args->len == 0) { 54 goto exit; 55 } 56 57 newlen = fqn_args->len + strlen(datum->name); 58 if (newlen >= CIL_MAX_NAME_LENGTH) { 59 cil_log(CIL_INFO, "Fully qualified name for %s is too long\n", datum->name); 60 rc = SEPOL_ERR; 61 goto exit; 62 } 63 strcpy(prefix, fqn_args->prefix); 64 strcat(prefix, datum->name); 65 datum->fqn = cil_strpool_add(prefix); 66 67 exit: 68 return rc; 69 } 70 71 static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 72 { 73 struct cil_fqn_args *fqn_args = args; 74 struct cil_fqn_args child_args; 75 struct cil_block *block = (struct cil_block *)d; 76 struct cil_symtab_datum *datum = (struct cil_symtab_datum *)block; 77 struct cil_tree_node *node = NODE(datum); 78 int i; 79 int rc = SEPOL_OK; 80 81 if (node->flavor != CIL_BLOCK) { 82 goto exit; 83 } 84 85 int newlen = fqn_args->len + strlen(datum->name) + 1; 86 if (newlen >= CIL_MAX_NAME_LENGTH) { 87 cil_log(CIL_INFO, "Fully qualified name for block %s is too long\n", datum->name); 88 rc = SEPOL_ERR; 89 goto exit; 90 } 91 92 child_args.node = node; 93 child_args.len = newlen; 94 strcpy(child_args.prefix, fqn_args->prefix); 95 strcat(child_args.prefix, datum->name); 96 strcat(child_args.prefix, "."); 97 98 for (i=1; i<CIL_SYM_NUM; i++) { 99 switch (i) { 100 case CIL_SYM_CLASSPERMSETS: 101 case CIL_SYM_CONTEXTS: 102 case CIL_SYM_LEVELRANGES: 103 case CIL_SYM_IPADDRS: 104 case CIL_SYM_NAMES: 105 case CIL_SYM_PERMX: 106 /* These do not show up in the kernal policy */ 107 break; 108 case CIL_SYM_POLICYCAPS: 109 /* Valid policy capability names are defined in libsepol */ 110 break; 111 default: 112 rc = cil_symtab_map(&(block->symtab[i]), __cil_fqn_qualify_decls, &child_args); 113 if (rc != SEPOL_OK) { 114 goto exit; 115 } 116 break; 117 } 118 } 119 120 rc = cil_symtab_map(&(block->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &child_args); 121 122 exit: 123 if (rc != SEPOL_OK) { 124 cil_tree_log(node, CIL_ERR,"Problem qualifying names in block"); 125 } 126 127 return rc; 128 } 129 130 int cil_fqn_qualify(struct cil_tree_node *root_node) 131 { 132 struct cil_root *root = root_node->data; 133 struct cil_fqn_args fqn_args; 134 135 fqn_args.prefix[0] = '\0'; 136 fqn_args.len = 0; 137 fqn_args.node = root_node; 138 139 return cil_symtab_map(&(root->symtab[CIL_SYM_BLOCKS]), __cil_fqn_qualify_blocks, &fqn_args); 140 } 141 142