1 /* Authors: Jason Tang <jtang (at) tresys.com> 2 * 3 * Functions that manipulate a logical block (conditional, optional, 4 * or global scope) for a policy module. 5 * 6 * Copyright (C) 2005 Tresys Technology, LLC 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include <sepol/policydb/policydb.h> 24 #include <sepol/policydb/conditional.h> 25 #include <sepol/policydb/avrule_block.h> 26 27 #include <assert.h> 28 #include <stdlib.h> 29 30 /* It is anticipated that there be less declarations within an avrule 31 * block than the global policy. Thus the symbol table sizes are 32 * smaller than those listed in policydb.c */ 33 static unsigned int symtab_sizes[SYM_NUM] = { 34 2, 35 4, 36 8, 37 32, 38 16, 39 4, 40 2, 41 2, 42 }; 43 44 avrule_block_t *avrule_block_create(void) 45 { 46 avrule_block_t *block; 47 if ((block = calloc(1, sizeof(*block))) == NULL) { 48 return NULL; 49 } 50 return block; 51 } 52 53 avrule_decl_t *avrule_decl_create(uint32_t decl_id) 54 { 55 avrule_decl_t *decl; 56 int i; 57 if ((decl = calloc(1, sizeof(*decl))) == NULL) { 58 return NULL; 59 } 60 decl->decl_id = decl_id; 61 for (i = 0; i < SYM_NUM; i++) { 62 if (symtab_init(&decl->symtab[i], symtab_sizes[i])) { 63 avrule_decl_destroy(decl); 64 return NULL; 65 } 66 } 67 68 for (i = 0; i < SYM_NUM; i++) { 69 ebitmap_init(&decl->required.scope[i]); 70 ebitmap_init(&decl->declared.scope[i]); 71 } 72 return decl; 73 } 74 75 /* note that unlike the other destroy functions, this one does /NOT/ 76 * destroy the pointer itself */ 77 static void scope_index_destroy(scope_index_t * scope) 78 { 79 unsigned int i; 80 if (scope == NULL) { 81 return; 82 } 83 for (i = 0; i < SYM_NUM; i++) { 84 ebitmap_destroy(scope->scope + i); 85 } 86 for (i = 0; i < scope->class_perms_len; i++) { 87 ebitmap_destroy(scope->class_perms_map + i); 88 } 89 free(scope->class_perms_map); 90 } 91 92 void avrule_decl_destroy(avrule_decl_t * x) 93 { 94 if (x == NULL) { 95 return; 96 } 97 cond_list_destroy(x->cond_list); 98 avrule_list_destroy(x->avrules); 99 role_trans_rule_list_destroy(x->role_tr_rules); 100 filename_trans_rule_list_destroy(x->filename_trans_rules); 101 role_allow_rule_list_destroy(x->role_allow_rules); 102 range_trans_rule_list_destroy(x->range_tr_rules); 103 scope_index_destroy(&x->required); 104 scope_index_destroy(&x->declared); 105 symtabs_destroy(x->symtab); 106 free(x->module_name); 107 free(x); 108 } 109 110 void avrule_block_destroy(avrule_block_t * x) 111 { 112 avrule_decl_t *decl; 113 if (x == NULL) { 114 return; 115 } 116 decl = x->branch_list; 117 while (decl != NULL) { 118 avrule_decl_t *next_decl = decl->next; 119 avrule_decl_destroy(decl); 120 decl = next_decl; 121 } 122 free(x); 123 } 124 125 void avrule_block_list_destroy(avrule_block_t * x) 126 { 127 while (x != NULL) { 128 avrule_block_t *next = x->next; 129 avrule_block_destroy(x); 130 x = next; 131 } 132 } 133 134 /* Get a conditional node from a avrule_decl with the same expression. 135 * If that expression does not exist then create one. */ 136 cond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl, 137 cond_list_t * cond) 138 { 139 cond_list_t *result; 140 int was_created; 141 result = cond_node_find(p, cond, decl->cond_list, &was_created); 142 if (result != NULL && was_created) { 143 result->next = decl->cond_list; 144 decl->cond_list = result; 145 } 146 return result; 147 } 148 149 /* Look up an identifier in a policy's scoping table. If it is there, 150 * marked as SCOPE_DECL, and any of its declaring block has been enabled, 151 * then return 1. Otherwise return 0. Can only be called after the 152 * decl_val_to_struct index has been created */ 153 int is_id_enabled(char *id, policydb_t * p, int symbol_table) 154 { 155 scope_datum_t *scope = 156 (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id); 157 uint32_t i; 158 if (scope == NULL) { 159 return 0; 160 } 161 if (scope->scope != SCOPE_DECL) { 162 return 0; 163 } 164 for (i = 0; i < scope->decl_ids_len; i++) { 165 avrule_decl_t *decl = 166 p->decl_val_to_struct[scope->decl_ids[i] - 1]; 167 if (decl != NULL && decl->enabled) { 168 return 1; 169 } 170 } 171 return 0; 172 } 173 174 /* Check if a particular permission is present within the given class, 175 * and that the class is enabled. Returns 1 if both conditions are 176 * true, 0 if neither could be found or if the class id disabled. */ 177 int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p) 178 { 179 class_datum_t *cladatum; 180 perm_datum_t *perm; 181 if (!is_id_enabled(class_id, p, SYM_CLASSES)) { 182 return 0; 183 } 184 cladatum = 185 (class_datum_t *) hashtab_search(p->p_classes.table, class_id); 186 if (cladatum == NULL) { 187 return 0; 188 } 189 perm = hashtab_search(cladatum->permissions.table, perm_id); 190 if (perm == NULL && cladatum->comdatum != 0) { 191 /* permission was not in this class. before giving 192 * up, check the class's parent */ 193 perm = 194 hashtab_search(cladatum->comdatum->permissions.table, 195 perm_id); 196 } 197 if (perm == NULL) { 198 return 0; 199 } 200 return 1; 201 } 202