113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Authors: Jason Tang <jtang@tresys.com> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Functions that manipulate a logical block (conditional, optional, 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * or global scope) for a policy module. 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2005 Tresys Technology, LLC 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is free software; you can redistribute it and/or 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * modify it under the terms of the GNU Lesser General Public 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License as published by the Free Software Foundation; either 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * version 2.1 of the License, or (at your option) any later version. 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is distributed in the hope that it will be useful, 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * but WITHOUT ANY WARRANTY; without even the implied warranty of 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Lesser General Public License for more details. 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * You should have received a copy of the GNU Lesser General Public 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License along with this library; if not, write to the Free Software 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/policydb.h> 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/conditional.h> 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/avrule_block.h> 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <assert.h> 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* It is anticipated that there be less declarations within an avrule 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * block than the global policy. Thus the symbol table sizes are 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * smaller than those listed in policydb.c */ 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic unsigned int symtab_sizes[SYM_NUM] = { 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2, 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4, 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8, 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32, 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16, 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4, 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2, 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2, 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}; 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleavrule_block_t *avrule_block_create(void) 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *block; 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((block = calloc(1, sizeof(*block))) == NULL) { 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return block; 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleavrule_decl_t *avrule_decl_create(uint32_t decl_id) 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i; 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((decl = calloc(1, sizeof(*decl))) == NULL) { 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->decl_id = decl_id; 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symtab_init(&decl->symtab[i], symtab_sizes[i])) { 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_destroy(decl); 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&decl->required.scope[i]); 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&decl->declared.scope[i]); 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return decl; 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* note that unlike the other destroy functions, this one does /NOT/ 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * destroy the pointer itself */ 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void scope_index_destroy(scope_index_t * scope) 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope == NULL) { 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return; 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(scope->scope + i); 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < scope->class_perms_len; i++) { 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(scope->class_perms_map + i); 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(scope->class_perms_map); 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid avrule_decl_destroy(avrule_decl_t * x) 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (x == NULL) { 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return; 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_list_destroy(x->cond_list); 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_list_destroy(x->avrules); 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_trans_rule_list_destroy(x->role_tr_rules); 1006eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris filename_trans_rule_list_destroy(x->filename_trans_rules); 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_rule_list_destroy(x->role_allow_rules); 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_rule_list_destroy(x->range_tr_rules); 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_index_destroy(&x->required); 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_index_destroy(&x->declared); 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtabs_destroy(x->symtab); 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(x->module_name); 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(x); 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid avrule_block_destroy(avrule_block_t * x) 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (x == NULL) { 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return; 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl = x->branch_list; 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (decl != NULL) { 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *next_decl = decl->next; 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_destroy(decl); 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl = next_decl; 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(x); 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlevoid avrule_block_list_destroy(avrule_block_t * x) 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (x != NULL) { 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *next = x->next; 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_destroy(x); 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle x = next; 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Get a conditional node from a avrule_decl with the same expression. 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * If that expression does not exist then create one. */ 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlecond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl, 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_list_t * cond) 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_list_t *result; 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int was_created; 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle result = cond_node_find(p, cond, decl->cond_list, &was_created); 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (result != NULL && was_created) { 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle result->next = decl->cond_list; 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->cond_list = result; 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return result; 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Look up an identifier in a policy's scoping table. If it is there, 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * marked as SCOPE_DECL, and any of its declaring block has been enabled, 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * then return 1. Otherwise return 0. Can only be called after the 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * decl_val_to_struct index has been created */ 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint is_id_enabled(char *id, policydb_t * p, int symbol_table) 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *scope = 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id); 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t i; 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope == NULL) { 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope->scope != SCOPE_DECL) { 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < scope->decl_ids_len; i++) { 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->decl_val_to_struct[scope->decl_ids[i] - 1]; 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (decl != NULL && decl->enabled) { 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Check if a particular permission is present within the given class, 17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * and that the class is enabled. Returns 1 if both conditions are 17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * true, 0 if neither could be found or if the class id disabled. */ 17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint is_perm_enabled(char *class_id, char *perm_id, policydb_t * p) 17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *cladatum; 18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_datum_t *perm; 18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(class_id, p, SYM_CLASSES)) { 18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cladatum = 18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (class_datum_t *) hashtab_search(p->p_classes.table, class_id); 18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cladatum == NULL) { 18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm = hashtab_search(cladatum->permissions.table, perm_id); 19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (perm == NULL && cladatum->comdatum != 0) { 19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* permission was not in this class. before giving 19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * up, check the class's parent */ 19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm = 19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(cladatum->comdatum->permissions.table, 19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_id); 19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (perm == NULL) { 19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 202