113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Joshua Brindle <jbrindle@tresys.com> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Jason Tang <jtang@tresys.com> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2004-2005 Tresys Technology, LLC 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2007 Red Hat, Inc. 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/hashtab.h> 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/avrule_block.h> 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/link.h> 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/util.h> 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdarg.h> 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h> 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h> 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <assert.h> 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "debug.h" 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#undef min 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define min(a,b) (((a) < (b)) ? (a) : (b)) 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct policy_module { 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *policy; 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t num_decls; 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *map[SYM_NUM]; 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *avdecl_map; 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t **perm_map; 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *perm_map_len; 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* a pointer to within the base module's avrule_block chain to 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * where this module's global now resides */ 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *base_global; 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} policy_module_t; 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct link_state { 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int verbose; 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *base; 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *last_avrule_block, *last_base_avrule_block; 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t next_decl_id, current_decl_id; 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* temporary variables, used during hashtab_map() calls */ 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t *cur; 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *cur_mod_name; 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *dest_decl; 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *src_class, *dest_class; 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *dest_class_name; 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char dest_class_req; /* flag indicating the class was not declared */ 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t symbol_num; 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* used to report the name of the module if dependancy error occurs */ 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t **decl_to_mod; 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* error reporting fields */ 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_handle_t *handle; 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} link_state_t; 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct missing_requirement { 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t symbol_type; 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t symbol_value; 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t perm_value; 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} missing_requirement_t; 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic const char *symtab_names[SYM_NUM] = { 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "common", "class", "role", "type/attribute", "user", 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "bool", "level", "category" 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}; 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Deallocates all elements within a module, but NOT the policydb_t 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * structure within, as well as the pointer itself. */ 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void policy_module_destroy(policy_module_t * mod) 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mod == NULL) { 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return; 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->map[i]); 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; mod->perm_map != NULL && i < mod->policy->p_classes.nprim; 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i++) { 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->perm_map[i]); 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->perm_map); 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->perm_map_len); 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->avdecl_map); 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod); 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/***** functions that copy identifiers from a module to base *****/ 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Note: there is currently no scoping for permissions, which causes some 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * strange side-effects. The current approach is this: 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * a) perm is required and the class _and_ perm are declared in base: only add a mapping. 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * b) perm is required and the class and perm are _not_ declared in base: simply add the permissions 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to the object class. This means that the requirements for the decl are the union of the permissions 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * required for all decls, but who cares. 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * c) perm is required, the class is declared in base, but the perm is not present. Nothing we can do 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * here because we can't mark a single permission as required, so we bail with a requirement error 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * _even_ if we are in an optional. 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * A is correct behavior, b is wrong but not too bad, c is totall wrong for optionals. Fixing this requires 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * a format change. 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int permission_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *perm_id = key, *new_id = NULL; 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_datum_t *perm, *new_perm = NULL, *dest_perm; 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *src_class = state->src_class; 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *dest_class = state->dest_class; 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t *mod = state->cur; 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t sclassi = src_class->s.value - 1; 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm = (perm_datum_t *) datum; 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_perm = hashtab_search(dest_class->permissions.table, perm_id); 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (dest_perm == NULL && dest_class->comdatum != NULL) { 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_perm = 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(dest_class->comdatum->permissions.table, 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_id); 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (dest_perm == NULL) { 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* If the object class was not declared in the base, add the perm 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to the object class. */ 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->dest_class_req) { 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* If the class was required (not declared), insert the new permission */ 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(perm_id); 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_id == NULL) { 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Memory error"); 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ERR; 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm = 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (perm_datum_t *) calloc(1, sizeof(perm_datum_t)); 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_perm == NULL) { 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Memory error"); 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ERR; 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(dest_class->permissions.table, 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_perm); 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "could not insert permission into class\n"); 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm->s.value = dest_class->permissions.nprim + 1; 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_perm = new_perm; 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this is case c from above */ 17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Module %s depends on permission %s in class %s, not satisfied", 17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, perm_id, 17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_class_name); 17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_EREQ; 17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* build the mapping for permissions encompassing this class. 18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * unlike symbols, the permission map translates between 18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * module permission bit to target permission bit. that bit 18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * may have originated from the class -or- it could be from 18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the class's common parent.*/ 18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (perm->s.value > mod->perm_map_len[sclassi]) { 18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *newmap = calloc(perm->s.value, sizeof(*newmap)); 18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (newmap == NULL) { 19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memcpy(newmap, mod->perm_map[sclassi], 19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->perm_map_len[sclassi] * sizeof(*newmap)); 19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(mod->perm_map[sclassi]); 19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->perm_map[sclassi] = newmap; 19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->perm_map_len[sclassi] = perm->s.value; 19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->perm_map[sclassi][perm->s.value - 1] = dest_perm->s.value; 20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_perm); 20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20809c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Parisstatic int class_copy_default_new_object(link_state_t *state, 20909c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris class_datum_t *olddatum, 21009c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris class_datum_t *newdatum) 21109c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris{ 21209c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris if (olddatum->default_user) { 21309c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { 21409c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris ERR(state->handle, "Found conflicting default user definitions"); 21509c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris return SEPOL_ENOTSUP; 21609c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris } 21709c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris newdatum->default_user = olddatum->default_user; 21809c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris } 21909c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris if (olddatum->default_role) { 22009c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { 22109c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris ERR(state->handle, "Found conflicting default role definitions"); 22209c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris return SEPOL_ENOTSUP; 22309c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris } 22409c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris newdatum->default_role = olddatum->default_role; 22509c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris } 226693f5241fdd5ae7e89d4312b85443c0fc1b1a57dEric Paris if (olddatum->default_type) { 227693f5241fdd5ae7e89d4312b85443c0fc1b1a57dEric Paris if (newdatum->default_type && olddatum->default_type != newdatum->default_type) { 228693f5241fdd5ae7e89d4312b85443c0fc1b1a57dEric Paris ERR(state->handle, "Found conflicting default type definitions"); 229693f5241fdd5ae7e89d4312b85443c0fc1b1a57dEric Paris return SEPOL_ENOTSUP; 230693f5241fdd5ae7e89d4312b85443c0fc1b1a57dEric Paris } 231693f5241fdd5ae7e89d4312b85443c0fc1b1a57dEric Paris newdatum->default_type = olddatum->default_type; 232693f5241fdd5ae7e89d4312b85443c0fc1b1a57dEric Paris } 23309c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris if (olddatum->default_range) { 23409c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { 23509c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris ERR(state->handle, "Found conflicting default range definitions"); 23609c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris return SEPOL_ENOTSUP; 23709c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris } 23809c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris newdatum->default_range = olddatum->default_range; 23909c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris } 24009c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris return 0; 24109c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris} 24209c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris 24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key, *new_id = NULL; 24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *cladatum, *new_class = NULL; 24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *scope = NULL; 25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cladatum = (class_datum_t *) datum; 25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_class_req = 0; 25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class = hashtab_search(state->base->p_classes.table, id); 25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* If there is not an object class already in the base symtab that means 25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * that either a) a module is trying to declare a new object class (which 25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the compiler should prevent) or b) an object class was required that is 25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * not in the base. 26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_class == NULL) { 26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope = 26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(state->cur->policy->p_classes_scope.table, 26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id); 26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope == NULL) { 26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ERR; 26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope->scope == SCOPE_DECL) { 27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* disallow declarations in modules */ 27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Modules may not yet declare new classes.", 27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name); 27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ENOTSUP; 27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* It would be nice to error early here because the requirement is 27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * not met, but we cannot because the decl might be optional (in which 27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * case we should record the requirement so that it is just turned 28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * off). Note: this will break horribly if modules can declare object 28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * classes because the class numbers will be all wrong (i.e., they 28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * might be assigned in the order they were required rather than the 28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * current scheme which ensures correct numbering by ordering the 28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * declarations properly). This can't be fixed until some infrastructure 28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * for querying the object class numbers is in place. */ 28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_class_req = 1; 28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class = 28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (class_datum_t *) calloc(1, sizeof(class_datum_t)); 28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_class == NULL) { 29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Memory error\n"); 29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ERR; 29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symtab_init 29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&new_class->permissions, PERM_SYMTAB_SIZE)) { 29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ERR; 29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_id == NULL) { 30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Memory error\n"); 30292788715dc793f805b0ae56844216b844a34ea22Alice Chu symtab_destroy(&new_class->permissions); 30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ERR; 30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->base->p_classes.table, 30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_class); 30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "could not insert new class into symtab"); 31292788715dc793f805b0ae56844216b844a34ea22Alice Chu symtab_destroy(&new_class->permissions); 31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->s.value = ++(state->base->p_classes.nprim); 31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur->map[SYM_CLASSES][cladatum->s.value - 1] = 32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->s.value; 32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy permissions */ 32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->src_class = cladatum; 32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_class = new_class; 32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_class_name = (char *)key; 32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32709c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris /* copy default new object rules */ 32809c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris ret = class_copy_default_new_object(state, cladatum, new_class); 32909c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris if (ret) 33009c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris return ret; 33109c783c9a36cd47216df827c5d2c21ec8cd613e2Eric Paris 33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_map(cladatum->permissions.table, permission_copy_callback, 33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state); 33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret != 0) { 33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_class); 34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key, *new_id = NULL; 35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_t *role, *base_role, *new_role = NULL; 35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role = (role_datum_t *) datum; 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_role = hashtab_search(state->base->p_roles.table, id); 357bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao if (base_role != NULL) { 358bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao /* role already exists. check that it is what this 359bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao * module expected. duplicate declarations (e.g., two 360bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao * modules both declare role foo_r) is checked during 361bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao * scope_copy_callback(). */ 362bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao if (role->flavor == ROLE_ATTRIB 363bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao && base_role->flavor != ROLE_ATTRIB) { 364bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao ERR(state->handle, 365bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao "%s: Expected %s to be a role attribute, but it was already declared as a regular role.", 366bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao state->cur_mod_name, id); 367bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao return -1; 368bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } else if (role->flavor != ROLE_ATTRIB 369bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao && base_role->flavor == ROLE_ATTRIB) { 370bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao ERR(state->handle, 371bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao "%s: Expected %s to be a regular role, but it was already declared as a role attribute.", 372bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao state->cur_mod_name, id); 373bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao return -1; 374bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } 375bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } else { 37613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying role %s", id); 37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_role = 38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (role_datum_t *) malloc(sizeof(*new_role))) == NULL) { 38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_init(new_role); 38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 389bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao /* new_role's dominates, types and roles field will be copied 39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * during role_fix_callback() */ 391bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao new_role->flavor = role->flavor; 39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_role->s.value = state->base->p_roles.nprim + 1; 39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->base->p_roles.table, 39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_role); 39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->p_roles.nprim++; 40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_role = new_role; 40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->dest_decl) { 40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = NULL; 40613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_role = malloc(sizeof(*new_role))) == NULL) { 40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_init(new_role); 410bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao new_role->flavor = base_role->flavor; 41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_role->s.value = base_role->s.value; 41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert 41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->dest_decl->p_roles.table, new_id, new_role)) { 41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_decl->p_roles.nprim++; 42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur->map[SYM_ROLES][role->s.value - 1] = base_role->s.value; 42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_destroy(new_role); 42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_role); 43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Copy types and attributes from a module into the base module. The 43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * attributes are copied, but the types that make up this attribute 43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * are delayed type_fix_callback(). */ 43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key, *new_id = NULL; 44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *type, *base_type, *new_type = NULL; 44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type = (type_datum_t *) datum; 44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((type->flavor == TYPE_TYPE && !type->primary) 44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || type->flavor == TYPE_ALIAS) { 44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* aliases are handled later, in alias_copy_callback() */ 44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type = hashtab_search(state->base->p_types.table, id); 45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_type != NULL) { 45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* type already exists. check that it is what this 45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * module expected. duplicate declarations (e.g., two 45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * modules both declare type foo_t) is checked during 45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * scope_copy_callback(). */ 45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type->flavor == TYPE_ATTRIB 45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle && base_type->flavor != TYPE_ATTRIB) { 45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Expected %s to be an attribute, but it was already declared as a type.", 46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, id); 46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (type->flavor != TYPE_ATTRIB 46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle && base_type->flavor == TYPE_ATTRIB) { 46513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 46613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Expected %s to be a type, but it was already declared as an attribute.", 46713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, id); 46813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 46913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 47013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* permissive should pass to the base type */ 47113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); 47213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 47313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 47413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying type %s", id); 47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 47713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 47813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 47913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_type = 48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) { 48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 48313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 48413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->primary = type->primary; 48513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flags = type->flags; 48613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flavor = type->flavor; 48713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* for attributes, the writing of new_type->types is 48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle done in type_fix_callback() */ 48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->s.value = state->base->p_types.nprim + 1; 49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->base->p_types.table, 49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_type); 49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->p_types.nprim++; 49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type = new_type; 50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 50213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->dest_decl) { 50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = NULL; 50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_type = calloc(1, sizeof(*new_type))) == NULL) { 50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->primary = type->primary; 50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flavor = type->flavor; 50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flags = type->flags; 51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->s.value = base_type->s.value; 51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert 51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->dest_decl->p_types.table, new_id, new_type)) { 51613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 51813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_decl->p_types.nprim++; 51913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 52013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 52113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur->map[SYM_TYPES][type->s.value - 1] = base_type->s.value; 52213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 52313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_type); 52813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 52913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 53013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 53113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 53213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 53313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 53413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 53513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key, *new_id = NULL; 53613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_t *user, *base_user, *new_user = NULL; 53713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 53813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 53913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user = (user_datum_t *) datum; 54013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 54113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_user = hashtab_search(state->base->p_users.table, id); 54213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_user == NULL) { 54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 54413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying user %s", id); 54513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 54613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 54713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 54813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 54913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_user = 55113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (user_datum_t *) malloc(sizeof(*new_user))) == NULL) { 55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 55313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 55413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_init(new_user); 55513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* new_users's roles and MLS fields will be copied during 55613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_fix_callback(). */ 55713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_user->s.value = state->base->p_users.nprim + 1; 55913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 56013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->base->p_users.table, 56113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 56213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_user); 56313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 56413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 56513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 56613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->p_users.nprim++; 56713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_user = new_user; 56813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 56913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 57013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->dest_decl) { 57113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = NULL; 57213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_user = malloc(sizeof(*new_user))) == NULL) { 57313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 57413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 57513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_init(new_user); 57613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_user->s.value = base_user->s.value; 57713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 57813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 57913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 58013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert 58113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->dest_decl->p_users.table, new_id, new_user)) { 58213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 58313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 58413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_decl->p_users.nprim++; 58513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 58613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 58713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur->map[SYM_USERS][user->s.value - 1] = base_user->s.value; 58813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 58913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 59013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 59113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 59213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_destroy(new_user); 59313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 59413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_user); 59513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 59613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 59713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 59813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 59913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 60013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 60113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 60213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key, *new_id = NULL; 60313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_bool_datum_t *booldatum, *base_bool, *new_bool = NULL; 60413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 6053df79fc5ebf08a35aaa095b2ee3fd24b3ece6ae5Joshua Brindle scope_datum_t *scope; 60613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 60713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle booldatum = (cond_bool_datum_t *) datum; 60813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 60913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_bool = hashtab_search(state->base->p_bools.table, id); 61013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_bool == NULL) { 61113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 61213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying boolean %s", id); 61313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 61413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 61513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 61613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 61713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 61813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_bool = 61913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (cond_bool_datum_t *) malloc(sizeof(*new_bool))) == NULL) { 62013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 62113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 62213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_bool->s.value = state->base->p_bools.nprim + 1; 62313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 62413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->base->p_bools.table, 62513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 62613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_bool); 62713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 62813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 62913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 63013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->p_bools.nprim++; 63113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_bool = new_bool; 632d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao base_bool->flags = booldatum->flags; 633c046d974c5513c5bc1c29f964177e2fac4004544Thomas Hurd base_bool->state = booldatum->state; 634d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao } else if ((booldatum->flags & COND_BOOL_FLAGS_TUNABLE) != 635d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao (base_bool->flags & COND_BOOL_FLAGS_TUNABLE)) { 636d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao /* A mismatch between boolean/tunable declaration 637d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao * and usage(for example a boolean used in the 638d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao * tunable_policy() or vice versa). 639d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao * 640d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao * This is not allowed and bail out with errors */ 641d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao ERR(state->handle, 642d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao "%s: Mismatch between boolean/tunable definition " 643d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao "and usage for %s", state->cur_mod_name, id); 644d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao return -1; 64513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 64613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6473df79fc5ebf08a35aaa095b2ee3fd24b3ece6ae5Joshua Brindle /* Get the scope info for this boolean to see if this is the declaration, 6483df79fc5ebf08a35aaa095b2ee3fd24b3ece6ae5Joshua Brindle * if so set the state */ 6493df79fc5ebf08a35aaa095b2ee3fd24b3ece6ae5Joshua Brindle scope = hashtab_search(state->cur->policy->p_bools_scope.table, id); 6503df79fc5ebf08a35aaa095b2ee3fd24b3ece6ae5Joshua Brindle if (!scope) 6513df79fc5ebf08a35aaa095b2ee3fd24b3ece6ae5Joshua Brindle return SEPOL_ERR; 652d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao if (scope->scope == SCOPE_DECL) { 6533df79fc5ebf08a35aaa095b2ee3fd24b3ece6ae5Joshua Brindle base_bool->state = booldatum->state; 654d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao /* Only the declaration rather than requirement 655d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao * decides if it is a boolean or tunable. */ 656d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao base_bool->flags = booldatum->flags; 657d9d583759595e522a0ebfb56f74ee2a274d48d19Harry Ciao } 65813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur->map[SYM_BOOLS][booldatum->s.value - 1] = base_bool->s.value; 65913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 66013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 66113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 66213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 66313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_destroy_bool(new_id, new_bool, NULL); 66413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 66513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 66613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 66713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 66813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 66913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 67013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key; 67113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_t *level, *base_level; 67213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 67313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *scope; 67413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 67513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level = (level_datum_t *) datum; 67613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 67713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_level = hashtab_search(state->base->p_levels.table, id); 67813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!base_level) { 67913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope = 68013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(state->cur->policy->p_sens_scope.table, id); 68113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!scope) 68213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ERR; 68313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope->scope == SCOPE_DECL) { 68413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* disallow declarations in modules */ 68513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 68613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Modules may not declare new sensitivities.", 68713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name); 68813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ENOTSUP; 689afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris } else if (scope->scope == SCOPE_REQ) { 69013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* unmet requirement */ 69113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 69213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Sensitivity %s not declared by base.", 69313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, id); 69413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ENOTSUP; 695afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris } else { 696afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris ERR(state->handle, 697afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris "%s: has an unknown scope: %d\n", 698afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris state->cur_mod_name, scope->scope); 699afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return SEPOL_ENOTSUP; 70013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 70113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 70213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 70313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur->map[SYM_LEVELS][level->level->sens - 1] = 70413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_level->level->sens; 70513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 70613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 70713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 70813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 70913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 71013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 71113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 71213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key; 71313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_datum_t *cat, *base_cat; 71413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 71513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *scope; 71613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 71713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat = (cat_datum_t *) datum; 71813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 71913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_cat = hashtab_search(state->base->p_cats.table, id); 72013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!base_cat) { 721afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris scope = hashtab_search(state->cur->policy->p_cat_scope.table, id); 72213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!scope) 72313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ERR; 72413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope->scope == SCOPE_DECL) { 72513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* disallow declarations in modules */ 72613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 72713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Modules may not declare new categories.", 72813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name); 72913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ENOTSUP; 730afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris } else if (scope->scope == SCOPE_REQ) { 73113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* unmet requirement */ 73213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 73313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Category %s not declared by base.", 73413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, id); 73513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ENOTSUP; 736afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris } else { 737afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris /* unknown scope? malformed policy? */ 738afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris ERR(state->handle, 739afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris "%s: has an unknown scope: %d\n", 740afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris state->cur_mod_name, scope->scope); 741afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris return SEPOL_ENOTSUP; 74213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 74313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 74413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 74513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur->map[SYM_CATS][cat->s.value - 1] = base_cat->s.value; 74613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 74713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 74813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 74913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 75013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int (*copy_callback_f[SYM_NUM]) (hashtab_key_t key, 75113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_datum_t datum, void *datap) = { 75213cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleNULL, class_copy_callback, role_copy_callback, type_copy_callback, 75313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_copy_callback, bool_copy_callback, sens_copy_callback, 75413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_copy_callback}; 75513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 756f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle/* 757f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle * The boundaries have to be copied after the types/roles/users are copied, 758f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle * because it refers hashtab to lookup destinated objects. 759f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle */ 760f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindlestatic int type_bounds_copy_callback(hashtab_key_t key, 761f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle hashtab_datum_t datum, void *data) 762f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle{ 763f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle link_state_t *state = (link_state_t *) data; 764f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle type_datum_t *type = (type_datum_t *) datum; 765f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle type_datum_t *dest; 766f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle uint32_t bounds_val; 767f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 768f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (!type->bounds) 769f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return 0; 770f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 771f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle bounds_val = state->cur->map[SYM_TYPES][type->bounds - 1]; 772f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 773f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle dest = hashtab_search(state->base->p_types.table, key); 774f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (!dest) { 775f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle ERR(state->handle, 776f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle "Type lookup failed for %s", (char *)key); 777f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 778f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle } 779f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (dest->bounds != 0 && dest->bounds != bounds_val) { 780f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle ERR(state->handle, 781f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle "Inconsistent boundary for %s", (char *)key); 782f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 783f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle } 784f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle dest->bounds = bounds_val; 785f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 786f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return 0; 787f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle} 788f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 789f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindlestatic int role_bounds_copy_callback(hashtab_key_t key, 790f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle hashtab_datum_t datum, void *data) 791f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle{ 792f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle link_state_t *state = (link_state_t *) data; 793f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle role_datum_t *role = (role_datum_t *) datum; 794f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle role_datum_t *dest; 795f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle uint32_t bounds_val; 796f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 797f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (!role->bounds) 798f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return 0; 799f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 800f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle bounds_val = state->cur->map[SYM_ROLES][role->bounds - 1]; 801f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 802f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle dest = hashtab_search(state->base->p_roles.table, key); 803f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (!dest) { 804f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle ERR(state->handle, 805f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle "Role lookup failed for %s", (char *)key); 806f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 807f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle } 808f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (dest->bounds != 0 && dest->bounds != bounds_val) { 809f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle ERR(state->handle, 810f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle "Inconsistent boundary for %s", (char *)key); 811f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 812f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle } 813f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle dest->bounds = bounds_val; 814f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 815f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return 0; 816f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle} 817f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 818f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindlestatic int user_bounds_copy_callback(hashtab_key_t key, 819f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle hashtab_datum_t datum, void *data) 820f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle{ 821f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle link_state_t *state = (link_state_t *) data; 822f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle user_datum_t *user = (user_datum_t *) datum; 823f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle user_datum_t *dest; 824f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle uint32_t bounds_val; 825f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 826f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (!user->bounds) 827f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return 0; 828f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 829f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle bounds_val = state->cur->map[SYM_USERS][user->bounds - 1]; 830f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 831f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle dest = hashtab_search(state->base->p_users.table, key); 832f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (!dest) { 833f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle ERR(state->handle, 834f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle "User lookup failed for %s", (char *)key); 835f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 836f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle } 837f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (dest->bounds != 0 && dest->bounds != bounds_val) { 838f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle ERR(state->handle, 839f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle "Inconsistent boundary for %s", (char *)key); 840f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 841f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle } 842f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle dest->bounds = bounds_val; 843f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 844f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return 0; 845f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle} 846f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 84713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* The aliases have to be copied after the types and attributes to be 84813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * certain that the base symbol table will have the type that the 84913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * alias refers. Otherwise, we won't be able to find the type value 85013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * for the alias. We can't depend on the declaration ordering because 85113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * of the hash table. 85213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 85313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 85413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 85513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 85613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key, *new_id = NULL, *target_id; 85713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *type, *base_type, *new_type = NULL, *target_type; 85813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 85913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t *mod = state->cur; 86013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int primval; 86113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 86213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type = (type_datum_t *) datum; 86313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* there are 2 kinds of aliases. Ones with their own value (TYPE_ALIAS) 86413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * and ones with the value of their primary (TYPE_TYPE && type->primary = 0) 86513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 86613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (! 86713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (type->flavor == TYPE_ALIAS 86813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || (type->flavor == TYPE_TYPE && !type->primary))) { 86913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* ignore types and attributes -- they were handled in 87013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * type_copy_callback() */ 87113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 87213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 87313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type->flavor == TYPE_ALIAS) 87513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle primval = type->primary; 87613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 87713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle primval = type->s.value; 87813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle target_id = mod->policy->p_type_val_to_name[primval - 1]; 88013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle target_type = hashtab_search(state->base->p_types.table, target_id); 88113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (target_type == NULL) { 88213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "%s: Could not find type %s for alias %s.", 88313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, target_id, id); 88413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 88513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 88613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 88713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!strcmp(id, target_id)) { 88813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "%s: Self aliasing of %s.", 88913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, id); 89013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 89113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 89213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 89313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle target_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); 89413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 89513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type = hashtab_search(state->base->p_types.table, id); 89613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_type == NULL) { 89713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 89813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying alias %s", id); 89913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 90013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_type = 90113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) { 90213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 90313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 90413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* the linked copy always has TYPE_ALIAS style aliases */ 90513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->primary = target_type->s.value; 90613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flags = target_type->flags; 90713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flavor = TYPE_ALIAS; 90813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->s.value = state->base->p_types.nprim + 1; 90913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 91013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 91113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 91213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert 91313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->base->p_types.table, new_id, new_type)) { 91413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 91513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 91613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->p_types.nprim++; 91713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type = new_type; 91813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 91913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* if this already exists and isn't an alias it was required by another module (or base) 92113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * and inserted into the hashtable as a type, fix it up now */ 92213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_type->flavor == TYPE_ALIAS) { 92413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* error checking */ 92513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(base_type->primary == target_type->s.value); 92613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(base_type->primary == 92713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->map[SYM_TYPES][primval - 1]); 92813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_TYPES][type->s.value - 1] == 92913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type->primary); 93013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 93113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 93213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 93313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_type->flavor == TYPE_ATTRIB) { 93413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 93513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s is an alias of an attribute, not allowed", id); 93613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 93713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 93813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 93913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type->flavor = TYPE_ALIAS; 94013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type->primary = target_type->s.value; 94113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_type->flags |= (target_type->flags & TYPE_FLAGS_PERMISSIVE); 94213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 94313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 94413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* the aliases map points from its value to its primary so when this module 94513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * references this type the value it gets back from the map is the primary */ 94613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->map[SYM_TYPES][type->s.value - 1] = base_type->primary; 94713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 94813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 94913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 95013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 95113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 95213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 95313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_type); 95413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 95513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 95613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 95713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*********** callbacks that fix bitmaps ***********/ 95813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 95913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int type_set_convert(type_set_t * types, type_set_t * dst, 96013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * mod, link_state_t * state 96113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle __attribute__ ((unused))) 96213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 96313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 96413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *tnode; 96513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&types->types, tnode, i) { 96613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(tnode, i)) { 96713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_TYPES][i]); 96813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 96913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&dst->types, mod->map[SYM_TYPES][i] - 1, 1)) { 97013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 97113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 97213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 97313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 97413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&types->negset, tnode, i) { 97513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(tnode, i)) { 97613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_TYPES][i]); 97713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 97813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&dst->negset, mod->map[SYM_TYPES][i] - 1, 1)) { 97913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 98013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 98113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 98213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 98313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->flags = types->flags; 98413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 98513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 98613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 98713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 98813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 98913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 99013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* OR 2 typemaps together and at the same time map the src types to 99113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the correct values in the dst typeset. 99213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 99313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int type_set_or_convert(type_set_t * types, type_set_t * dst, 99413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * mod, link_state_t * state) 99513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 99613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_t ts_tmp; 99713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 99813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_init(&ts_tmp); 99913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_convert(types, &ts_tmp, mod, state) == -1) { 100013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 100113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 100213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_or_eq(dst, &ts_tmp)) { 100313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 100413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 100513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_destroy(&ts_tmp); 100613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 100713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 100813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 100913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 101013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_destroy(&ts_tmp); 101113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 101213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 101313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 101413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int role_set_or_convert(role_set_t * roles, role_set_t * dst, 101513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * mod, link_state_t * state) 101613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 101713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 101813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t tmp; 101913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *rnode; 102013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 102113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&tmp); 102213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&roles->roles, rnode, i) { 102313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(rnode, i)) { 102413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_ROLES][i]); 102513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 102613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&tmp, mod->map[SYM_ROLES][i] - 1, 1)) { 102713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 102813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 102913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 103013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 103113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(&dst->roles, &tmp)) { 103213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 103313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 103413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->flags |= roles->flags; 103513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp); 103613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 103713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 103813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 103913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp); 104013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 104113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 104213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 104313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int mls_level_convert(mls_semantic_level_t * src, mls_semantic_level_t * dst, 104413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * mod, link_state_t * state) 104513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 104613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_semantic_cat_t *src_cat, *new_cat; 104713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 104813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mod->policy->mls) 104913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 105013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 105113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Required not declared. */ 105213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!src->sens) 105313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 105413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 105513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_LEVELS][src->sens - 1]); 105613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->sens = mod->map[SYM_LEVELS][src->sens - 1]; 105713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 105813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (src_cat = src->cat; src_cat; src_cat = src_cat->next) { 105913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_cat = 106013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 106113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_cat) { 106213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory"); 106313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 106413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 106513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_semantic_cat_init(new_cat); 106613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 106713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_cat->next = dst->cat; 106813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->cat = new_cat; 106913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 107013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_CATS][src_cat->low - 1]); 107113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->cat->low = mod->map[SYM_CATS][src_cat->low - 1]; 107213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_CATS][src_cat->high - 1]); 107313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->cat->high = mod->map[SYM_CATS][src_cat->high - 1]; 107413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 107513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 107613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 107713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 107813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 107913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int mls_range_convert(mls_semantic_range_t * src, mls_semantic_range_t * dst, 108013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * mod, link_state_t * state) 108113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 108213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 108313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = mls_level_convert(&src->level[0], &dst->level[0], mod, state); 108413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) 108513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 108613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = mls_level_convert(&src->level[1], &dst->level[1], mod, state); 108713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) 108813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 108913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 109013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 109113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 109213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 109313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 109413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 109513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 109613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key; 109713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_t *role, *dest_role = NULL; 109813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 109913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t e_tmp; 110013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t *mod = state->cur; 110113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *rnode; 110213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_t role_tab; 110313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 110413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role = (role_datum_t *) datum; 110513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->dest_decl == NULL) 110613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_tab = state->base->p_roles.table; 110713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 110813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_tab = state->dest_decl->p_roles.table; 110913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 111013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_role = hashtab_search(role_tab, id); 111113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(dest_role != NULL); 111213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 111313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) { 111413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "fixing role %s", id); 111513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 111613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 111713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&e_tmp); 111813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&role->dominates, rnode, i) { 111913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(rnode, i)) { 112013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_ROLES][i]); 112113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 112213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { 112313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 112413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 112513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 112613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 112713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(&dest_role->dominates, &e_tmp)) { 112813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 112913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 113013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_or_convert(&role->types, &dest_role->types, mod, state)) { 113113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 113213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 113313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&e_tmp); 1134bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao 1135bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao if (role->flavor == ROLE_ATTRIB) { 1136bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao ebitmap_init(&e_tmp); 1137bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao ebitmap_for_each_bit(&role->roles, rnode, i) { 1138bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao if (ebitmap_node_get_bit(rnode, i)) { 1139bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao assert(mod->map[SYM_ROLES][i]); 1140bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao if (ebitmap_set_bit 1141bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { 1142bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao goto cleanup; 1143bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } 1144bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } 1145bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } 1146bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao if (ebitmap_union(&dest_role->roles, &e_tmp)) { 1147bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao goto cleanup; 1148bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } 1149bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao ebitmap_destroy(&e_tmp); 1150bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao } 1151bff13595230dbd41692a98482ff3323078ae7d03Harry Ciao 115213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 115313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 115413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 115513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 115613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&e_tmp); 115713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 115813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 115913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 116013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int type_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 116113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 116213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 116313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 116413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key; 116513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *type, *new_type = NULL; 116613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 116713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t e_tmp; 116813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t *mod = state->cur; 116913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *tnode; 117013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_t *typetab; 117113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 117213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type = (type_datum_t *) datum; 117313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 117413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->dest_decl == NULL) 117513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typetab = &state->base->p_types; 117613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 117713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typetab = &state->dest_decl->p_types; 117813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 117913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* only fix attributes */ 118013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type->flavor != TYPE_ATTRIB) { 118113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 118213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 118313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 118413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type = hashtab_search(typetab->table, id); 118513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(new_type != NULL && new_type->flavor == TYPE_ATTRIB); 118613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 118713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) { 118813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "fixing attribute %s", id); 118913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 119013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 119113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&e_tmp); 119213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&type->types, tnode, i) { 119313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(tnode, i)) { 119413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_TYPES][i]); 119513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 119613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&e_tmp, mod->map[SYM_TYPES][i] - 1, 1)) { 119713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 119813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 119913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 120013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 120113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(&new_type->types, &e_tmp)) { 120213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 120313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 120413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&e_tmp); 120513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 120613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 120713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 120813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 120913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&e_tmp); 121013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 121113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 121213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 121313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int user_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 121413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 121513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 121613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key; 121713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_t *user, *new_user = NULL; 121813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 121913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t *mod = state->cur; 122013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_t *usertab; 122113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 122213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user = (user_datum_t *) datum; 122313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 122413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->dest_decl == NULL) 122513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle usertab = &state->base->p_users; 122613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 122713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle usertab = &state->dest_decl->p_users; 122813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 122913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_user = hashtab_search(usertab->table, id); 123013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(new_user != NULL); 123113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 123213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) { 123313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "fixing user %s", id); 123413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 123513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 123613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (role_set_or_convert(&user->roles, &new_user->roles, mod, state)) { 123713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 123813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 123913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_range_convert(&user->range, &new_user->range, mod, state)) 124113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 124213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_level_convert(&user->dfltlevel, &new_user->dfltlevel, mod, state)) 124413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 124513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 124713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 124913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 125013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 125113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 125213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 125313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int (*fix_callback_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 125413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *datap) = { 125513cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleNULL, NULL, role_fix_callback, type_fix_callback, user_fix_callback, 125613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL, NULL, NULL}; 125713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 125813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*********** functions that copy AV rules ***********/ 125913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 126013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_avrule_list(avrule_t * list, avrule_t ** dst, 126113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * module, link_state_t * state) 126213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 126313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 126413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t *cur, *new_rule = NULL, *tail; 126513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_perm_node_t *cur_perm, *new_perm, *tail_perm = NULL; 126613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 126713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = *dst; 126813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (tail && tail->next) { 126913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = tail->next; 127013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 127113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 127213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = list; 127313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 127413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_rule = (avrule_t *) malloc(sizeof(avrule_t))) == NULL) { 127513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 127613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 127713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_init(new_rule); 127813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 127913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_rule->specified = cur->specified; 128013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_rule->flags = cur->flags; 128113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_convert 128213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&cur->stypes, &new_rule->stypes, module, state) == -1 128313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || type_set_convert(&cur->ttypes, &new_rule->ttypes, module, 128413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state) == -1) { 128513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 128613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 128713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 128813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_perm = cur->perms; 128913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail_perm = NULL; 129013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur_perm) { 129113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_perm = (class_perm_node_t *) 129213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle malloc(sizeof(class_perm_node_t))) == NULL) { 129313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 129413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 129513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_perm_node_init(new_perm); 129613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1297ed7a6ba24ad3241e696fa7bc9bb56bb4f373147bdcashman new_perm->tclass = 1298ed7a6ba24ad3241e696fa7bc9bb56bb4f373147bdcashman module->map[SYM_CLASSES][cur_perm->tclass - 1]; 1299ed7a6ba24ad3241e696fa7bc9bb56bb4f373147bdcashman assert(new_perm->tclass); 130013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 130113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_rule->specified & AVRULE_AV) { 130213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; 130313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i < 1304ed7a6ba24ad3241e696fa7bc9bb56bb4f373147bdcashman module->perm_map_len[cur_perm->tclass - 1]; 130513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle i++) { 130613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(cur_perm->data & (1U << i))) 130713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 130813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm->data |= 130913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (1U << 131013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (module-> 1311ed7a6ba24ad3241e696fa7bc9bb56bb4f373147bdcashman perm_map[cur_perm->tclass - 1][i] - 131213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1)); 131313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 131413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 131513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm->data = 131613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->map[SYM_TYPES][cur_perm->data - 1]; 131713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 131813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 131913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_rule->perms == NULL) { 132013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_rule->perms = new_perm; 132113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 132292788715dc793f805b0ae56844216b844a34ea22Alice Chu assert(tail_perm); 132313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail_perm->next = new_perm; 132413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 132513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail_perm = new_perm; 132613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_perm = cur_perm->next; 132713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 132813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_rule->line = cur->line; 1329ef24ade029329a6e9981bd1de2ba7b9ea48e1c79Stephen Smalley new_rule->source_line = cur->source_line; 1330a80a48cb1907162b1fce8f0af38d062fca39a635Stephen Smalley if (cur->source_filename) { 1331a80a48cb1907162b1fce8f0af38d062fca39a635Stephen Smalley new_rule->source_filename = strdup(cur->source_filename); 1332a80a48cb1907162b1fce8f0af38d062fca39a635Stephen Smalley if (!new_rule->source_filename) 1333a80a48cb1907162b1fce8f0af38d062fca39a635Stephen Smalley goto cleanup; 1334a80a48cb1907162b1fce8f0af38d062fca39a635Stephen Smalley } 133513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 133613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 133713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 133813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*dst == NULL) { 133913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dst = new_rule; 134013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 134113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail->next = new_rule; 134213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 134313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = new_rule; 134413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 134513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 134613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 134713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 134813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 134913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_destroy(new_rule); 135013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_rule); 135113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 135213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 135313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 135413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_role_trans_list(role_trans_rule_t * list, 135513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_trans_rule_t ** dst, 135613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * module, link_state_t * state) 135713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 135813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_trans_rule_t *cur, *new_rule = NULL, *tail; 13596db9b74210197f792a52038abbd10e946e99e49dHarry Ciao unsigned int i; 13606db9b74210197f792a52038abbd10e946e99e49dHarry Ciao ebitmap_node_t *cnode; 136113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 136213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = list; 136313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = *dst; 136413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (tail && tail->next) { 136513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = tail->next; 136613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 136713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 136813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_rule = 136913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (role_trans_rule_t *) malloc(sizeof(role_trans_rule_t))) == 137013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL) { 137113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 137213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 137313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_trans_rule_init(new_rule); 137413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 137513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (role_set_or_convert 137613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&cur->roles, &new_rule->roles, module, state) 137713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || type_set_or_convert(&cur->types, &new_rule->types, 137813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module, state)) { 137913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 138013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 138113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13826db9b74210197f792a52038abbd10e946e99e49dHarry Ciao ebitmap_for_each_bit(&cur->classes, cnode, i) { 13836db9b74210197f792a52038abbd10e946e99e49dHarry Ciao if (ebitmap_node_get_bit(cnode, i)) { 13846db9b74210197f792a52038abbd10e946e99e49dHarry Ciao assert(module->map[SYM_CLASSES][i]); 13856db9b74210197f792a52038abbd10e946e99e49dHarry Ciao if (ebitmap_set_bit(&new_rule->classes, 13866db9b74210197f792a52038abbd10e946e99e49dHarry Ciao module-> 13876db9b74210197f792a52038abbd10e946e99e49dHarry Ciao map[SYM_CLASSES][i] - 1, 13886db9b74210197f792a52038abbd10e946e99e49dHarry Ciao 1)) { 13896db9b74210197f792a52038abbd10e946e99e49dHarry Ciao goto cleanup; 13906db9b74210197f792a52038abbd10e946e99e49dHarry Ciao } 13916db9b74210197f792a52038abbd10e946e99e49dHarry Ciao } 13926db9b74210197f792a52038abbd10e946e99e49dHarry Ciao } 13936db9b74210197f792a52038abbd10e946e99e49dHarry Ciao 139413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_rule->new_role = module->map[SYM_ROLES][cur->new_role - 1]; 139513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 139613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*dst == NULL) { 139713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dst = new_rule; 139813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 139913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail->next = new_rule; 140013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 140113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = new_rule; 140213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 140313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 140413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 140513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 140613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 140713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_trans_rule_list_destroy(new_rule); 140813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 140913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 141013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 141113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_role_allow_list(role_allow_rule_t * list, 141213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_rule_t ** dst, 141313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * module, link_state_t * state) 141413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 141513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_rule_t *cur, *new_rule = NULL, *tail; 141613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 141713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = list; 141813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = *dst; 141913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (tail && tail->next) { 142013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = tail->next; 142113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 142213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 142313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 142413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_rule = 142513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (role_allow_rule_t *) malloc(sizeof(role_allow_rule_t))) == 142613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL) { 142713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 142813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 142913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_rule_init(new_rule); 143013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 143113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (role_set_or_convert 143213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&cur->roles, &new_rule->roles, module, state) 143313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || role_set_or_convert(&cur->new_roles, 143413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_rule->new_roles, module, 143513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state)) { 143613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 143713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 143813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*dst == NULL) { 143913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dst = new_rule; 144013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 144113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail->next = new_rule; 144213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 144313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = new_rule; 144413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 144513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 144613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 144713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 144813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 144913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_rule_list_destroy(new_rule); 145013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 145113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 145213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14536eeb71538ea29b639ac7549831cd1aa4da32722aEric Parisstatic int copy_filename_trans_list(filename_trans_rule_t * list, 14546eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris filename_trans_rule_t ** dst, 14556eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris policy_module_t * module, 14566eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris link_state_t * state) 14576eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris{ 14586eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris filename_trans_rule_t *cur, *new_rule, *tail; 14596eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14606eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris cur = list; 14616eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris tail = *dst; 14626eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris while (tail && tail->next) 14636eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris tail = tail->next; 14646eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14656eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris while (cur) { 14666eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris new_rule = malloc(sizeof(*new_rule)); 14676eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris if (!new_rule) 14686eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris goto err; 14696eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14706eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris filename_trans_rule_init(new_rule); 14716eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14726eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris if (*dst == NULL) 14736eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris *dst = new_rule; 14746eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris else 14756eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris tail->next = new_rule; 14766eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris tail = new_rule; 14776eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14786eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris new_rule->name = strdup(cur->name); 14796eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris if (!new_rule->name) 14806eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris goto err; 14816eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14826eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module, state) || 14836eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module, state)) 14846eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris goto err; 14856eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14866eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris new_rule->tclass = module->map[SYM_CLASSES][cur->tclass - 1]; 14876eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris new_rule->otype = module->map[SYM_TYPES][cur->otype - 1]; 14886eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 14896eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris cur = cur->next; 14906eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris } 14916eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris return 0; 14926eeb71538ea29b639ac7549831cd1aa4da32722aEric Pariserr: 14936eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris ERR(state->handle, "Out of memory!"); 14946eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris return -1; 14956eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris} 14966eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 149713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_range_trans_list(range_trans_rule_t * rules, 149813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_rule_t ** dst, 149913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * mod, link_state_t * state) 150013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 150113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_rule_t *rule, *new_rule = NULL; 150213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 150313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *cnode; 150413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 150513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (rule = rules; rule; rule = rule->next) { 150613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_rule = 150713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (range_trans_rule_t *) malloc(sizeof(range_trans_rule_t)); 150813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_rule) 150913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 151013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 151113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_rule_init(new_rule); 151213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 151313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_rule->next = *dst; 151413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dst = new_rule; 151513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 151613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_convert(&rule->stypes, &new_rule->stypes, 151713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod, state)) 151813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 151913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 152013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_convert(&rule->ttypes, &new_rule->ttypes, 152113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod, state)) 152213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 152313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 152413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&rule->tclasses, cnode, i) { 152513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(cnode, i)) { 152613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(mod->map[SYM_CLASSES][i]); 152713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 152813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&new_rule->tclasses, 152913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod->map[SYM_CLASSES][i] - 1, 1)) { 153013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 153113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 153213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 153313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 153413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 153513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_range_convert(&rule->trange, &new_rule->trange, mod, state)) 153613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 153713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 153813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 153913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 154013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 154113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 154213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_rule_list_destroy(new_rule); 154313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 154413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 154513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 154613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_cond_list(cond_node_t * list, cond_node_t ** dst, 154713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * module, link_state_t * state) 154813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 154913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned i; 155013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_node_t *cur, *new_node = NULL, *tail; 155113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_expr_t *cur_expr; 155213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = *dst; 155313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (tail && tail->next) 155413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = tail->next; 155513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 155613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = list; 155713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 155813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_node = (cond_node_t *) malloc(sizeof(cond_node_t)); 155913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_node) { 156013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 156113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 156213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_node, 0, sizeof(cond_node_t)); 156313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 156413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_node->cur_state = cur->cur_state; 156513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_node->expr = cond_copy_expr(cur->expr); 156613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_node->expr) 156713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 156813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* go back through and remap the expression */ 156913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (cur_expr = new_node->expr; cur_expr != NULL; 157013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_expr = cur_expr->next) { 157113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* expression nodes don't have a bool value of 0 - don't map them */ 157213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur_expr->expr_type != COND_BOOL) 157313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 157413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(module->map[SYM_BOOLS][cur_expr->bool - 1] != 0); 157513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_expr->bool = 157613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->map[SYM_BOOLS][cur_expr->bool - 1]; 157713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 157813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_node->nbools = cur->nbools; 157913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* FIXME should COND_MAX_BOOLS be used here? */ 158013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < min(cur->nbools, COND_MAX_BOOLS); i++) { 158113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t remapped_id = 158213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->map[SYM_BOOLS][cur->bool_ids[i] - 1]; 158313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(remapped_id != 0); 158413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_node->bool_ids[i] = remapped_id; 158513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 158613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_node->expr_pre_comp = cur->expr_pre_comp; 158713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 158813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_avrule_list 158913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (cur->avtrue_list, &new_node->avtrue_list, module, state) 159013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || copy_avrule_list(cur->avfalse_list, 159113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_node->avfalse_list, module, 159213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state)) { 159313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 159413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 159513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 159613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*dst == NULL) { 159713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dst = new_node; 159813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 159913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail->next = new_node; 160013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 160113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail = new_node; 160213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 160313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 160413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 160513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 160613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 160713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_node_destroy(new_node); 160813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_node); 160913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 161013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 161113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 161213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 161313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*********** functions that copy avrule_decls from module to base ***********/ 161413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 161513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_identifiers(link_state_t * state, symtab_t * src_symtab, 161613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t * dest_decl) 161713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 161813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i, ret; 161913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 162013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->dest_decl = dest_decl; 162113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 162213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_callback_f[i] != NULL) { 162313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 162413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_map(src_symtab[i].table, copy_callback_f[i], 162513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state); 162613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 162713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 162813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 162913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 163013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 163113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1632f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (hashtab_map(src_symtab[SYM_TYPES].table, 1633f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle type_bounds_copy_callback, state)) 1634f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 1635f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 1636f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (hashtab_map(src_symtab[SYM_TYPES].table, 1637f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle alias_copy_callback, state)) 1638f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 1639f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 1640f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (hashtab_map(src_symtab[SYM_ROLES].table, 1641f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle role_bounds_copy_callback, state)) 1642f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle return -1; 1643f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle 1644f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle if (hashtab_map(src_symtab[SYM_USERS].table, 1645f470207454f5f6ce539aa543e5168a07d667254bJoshua Brindle user_bounds_copy_callback, state)) 164613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 164713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 164813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* then fix bitmaps associated with those newly copied identifiers */ 164913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 165013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fix_callback_f[i] != NULL && 165113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_map(src_symtab[i].table, fix_callback_f[i], 165213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state)) { 165313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 165413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 165513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 165613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 165713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 165813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 165913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_scope_index(scope_index_t * src, scope_index_t * dest, 166013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t * module, link_state_t * state) 166113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 166213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 166313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t largest_mapped_class_value = 0; 166413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *node; 166513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy the scoping information for this avrule decl block */ 166613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 166713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *srcmap = src->scope + i; 166813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *destmap = dest->scope + i; 166913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_callback_f[i] == NULL) { 167013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 167113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 167213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(srcmap, node, j) { 167313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(node, j)) { 167413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(module->map[i][j] != 0); 167513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit 167613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (destmap, module->map[i][j] - 1, 1) != 0) { 167713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 167813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 167913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 168013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (i == SYM_CLASSES && 168113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle largest_mapped_class_value < 168213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->map[SYM_CLASSES][j]) { 168313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle largest_mapped_class_value = 168413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->map[SYM_CLASSES][j]; 168513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 168613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 168713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 168813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 168913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 169013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* next copy the enabled permissions data */ 169113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((dest->class_perms_map = malloc(largest_mapped_class_value * 169213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(*dest->class_perms_map))) == 169313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL) { 169413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 169513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 169613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < largest_mapped_class_value; i++) { 169713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(dest->class_perms_map + i); 169813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 169913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest->class_perms_len = largest_mapped_class_value; 170013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < src->class_perms_len; i++) { 170113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *srcmap = src->class_perms_map + i; 170213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *destmap = 170313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest->class_perms_map + module->map[SYM_CLASSES][i] - 1; 170413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(srcmap, node, j) { 170513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(node, j) && 170613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_set_bit(destmap, module->perm_map[i][j] - 1, 170713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1)) { 170813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 170913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 171013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 171113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 171213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 171313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 171413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 171513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 171613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 171713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 171813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 171913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 172013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_avrule_decl(link_state_t * state, policy_module_t * module, 172113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t * src_decl, avrule_decl_t * dest_decl) 172213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 172313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 172413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 172513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy all of the RBAC and TE rules */ 172613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_avrule_list 172713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (src_decl->avrules, &dest_decl->avrules, module, state) == -1 172813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || copy_role_trans_list(src_decl->role_tr_rules, 172913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &dest_decl->role_tr_rules, module, 173013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state) == -1 173113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || copy_role_allow_list(src_decl->role_allow_rules, 173213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &dest_decl->role_allow_rules, module, 173313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state) == -1 173413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || copy_cond_list(src_decl->cond_list, &dest_decl->cond_list, 173513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module, state) == -1) { 173613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 173713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 173813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17396eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris if (copy_filename_trans_list(src_decl->filename_trans_rules, 17406eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris &dest_decl->filename_trans_rules, 17416eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris module, state)) 17426eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris return -1; 17436eeb71538ea29b639ac7549831cd1aa4da32722aEric Paris 174413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_range_trans_list(src_decl->range_tr_rules, 174513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &dest_decl->range_tr_rules, module, state)) 174613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 174713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 174813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* finally copy any identifiers local to this declaration */ 174913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = copy_identifiers(state, src_decl->symtab, dest_decl); 175013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret < 0) { 175113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 175213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 175313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 175413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* then copy required and declared scope indices here */ 175513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_scope_index(&src_decl->required, &dest_decl->required, 175613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module, state) == -1 || 175713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle copy_scope_index(&src_decl->declared, &dest_decl->declared, 175813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module, state) == -1) { 175913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 176013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 176113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 176213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 176313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 176413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 176513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_avrule_block(link_state_t * state, policy_module_t * module, 176613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t * block) 176713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 176813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *new_block = avrule_block_create(); 176913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl, *last_decl = NULL; 177013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 177113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 177213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_block == NULL) { 177313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 177413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = -1; 177513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 177613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 177713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 177813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_block->flags = block->flags; 177913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 178013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (decl = block->branch_list; decl != NULL; decl = decl->next) { 178113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *new_decl = 178213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_create(state->next_decl_id); 178313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_decl == NULL) { 178413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 178513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = -1; 178613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 178713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 178813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 178913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (module->policy->name != NULL) { 179013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_decl->module_name = strdup(module->policy->name); 179113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_decl->module_name == NULL) { 179213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory\n"); 179392788715dc793f805b0ae56844216b844a34ea22Alice Chu avrule_decl_destroy(new_decl); 179413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = -1; 179513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 179613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 179713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 179813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 179913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (last_decl == NULL) { 180013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_block->branch_list = new_decl; 180113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 180213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle last_decl->next = new_decl; 180313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 180413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle last_decl = new_decl; 180513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->decl_val_to_struct[state->next_decl_id - 1] = 180613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_decl; 180713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->decl_to_mod[state->next_decl_id] = module->policy; 180813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 180913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->avdecl_map[decl->decl_id] = new_decl->decl_id; 181013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 181113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = copy_avrule_decl(state, module, decl, new_decl); 181213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 181392788715dc793f805b0ae56844216b844a34ea22Alice Chu avrule_decl_destroy(new_decl); 181413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 181513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 181613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 181713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->next_decl_id++; 181813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 181913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->last_avrule_block->next = new_block; 182013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->last_avrule_block = new_block; 182113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 182213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 182313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 182413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_list_destroy(new_block); 182513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 182613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 182713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 182813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int scope_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 182913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 183013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 183113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 183213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 183313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = key, *new_id = NULL; 183413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *scope, *base_scope; 183513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t *state = (link_state_t *) data; 183613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t symbol_num = state->symbol_num; 183713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *avdecl_map = state->cur->avdecl_map; 183813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 183913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope = (scope_datum_t *) datum; 184013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 184113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check if the base already has a scope entry */ 184213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_scope = hashtab_search(state->base->scope[symbol_num].table, id); 184313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_scope == NULL) { 184413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *new_scope; 184513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_id = strdup(id)) == NULL) { 184613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 184713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 184813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 184913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_scope = 185013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (scope_datum_t *) calloc(1, sizeof(*new_scope))) == NULL) { 185113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 185213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 185313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 185413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->base->scope[symbol_num].table, 185513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 185613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_scope); 185713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 185813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 185913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_scope); 186013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 186113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 186213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_scope->scope = SCOPE_REQ; /* this is reset further down */ 186313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_scope = new_scope; 186413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 186513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_DECL) { 186613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this module declared symbol, so overwrite the old 186713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * list with the new decl ids */ 186813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_scope->scope = SCOPE_DECL; 186913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(base_scope->decl_ids); 187013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_scope->decl_ids = NULL; 187113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle base_scope->decl_ids_len = 0; 187213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < scope->decl_ids_len; i++) { 187313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (add_i_to_a(avdecl_map[scope->decl_ids[i]], 187413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &base_scope->decl_ids_len, 187513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &base_scope->decl_ids) == -1) { 187613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 187713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 187813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 187913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (base_scope->scope == SCOPE_DECL && scope->scope == SCOPE_REQ) { 188013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this module depended on a symbol that now exists, 188113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * so don't do anything */ 188213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_REQ) { 188313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* symbol is still required, so add to the list */ 188413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < scope->decl_ids_len; i++) { 188513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (add_i_to_a(avdecl_map[scope->decl_ids[i]], 188613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &base_scope->decl_ids_len, 188713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &base_scope->decl_ids) == -1) { 188813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 188913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 189013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 189113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 189213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this module declared a symbol, and it was already 189313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * declared. only roles and users may be multiply 189413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * declared; for all others this is an error. */ 189513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symbol_num != SYM_ROLES && symbol_num != SYM_USERS) { 189613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 189713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s: Duplicate declaration in module: %s %s", 189813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name, 189913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_names[state->symbol_num], id); 190013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 190113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 190213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < scope->decl_ids_len; i++) { 190313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (add_i_to_a(avdecl_map[scope->decl_ids[i]], 190413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &base_scope->decl_ids_len, 190513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &base_scope->decl_ids) == -1) { 190613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 190713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 190813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 190913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 191013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 191113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 191213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 191313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 191413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 191513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 191613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 191713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Copy a module over to a base, remapping all values within. After 191813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * all identifiers and rules are done, copy the scoping information. 191913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This is when it checks for duplicate declarations. */ 192013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_module(link_state_t * state, policy_module_t * module) 192113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 192213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i, ret; 192313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *cur; 192413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur = module; 192513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->cur_mod_name = module->policy->name; 192613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 192713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* first copy all of the identifiers */ 192813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = copy_identifiers(state, module->policy->symtab, NULL); 192913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 193013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 193113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 193213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 193313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* next copy all of the avrule blocks */ 193413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (cur = module->policy->global; cur != NULL; cur = cur->next) { 193513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = copy_avrule_block(state, module, cur); 193613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 193713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 193813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 193913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 194013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 194113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* then copy the scoping tables */ 194213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 194313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->symbol_num = i; 194413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 194513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (module->policy->scope[i].table, scope_copy_callback, 194613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state)) { 194713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 194813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 194913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 195013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 195113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 195213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 195313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 195413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/***** functions that check requirements and enable blocks in a module ******/ 195513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 195613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* borrowed from checkpolicy.c */ 195713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 195813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestruct find_perm_arg { 195913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int valuep; 196013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_key_t key; 196113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}; 196213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 196313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *varg) 196413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 196513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 196613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct find_perm_arg *arg = varg; 196713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 196813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_datum_t *perdatum = (perm_datum_t *) datum; 196913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (arg->valuep == perdatum->s.value) { 197013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle arg->key = key; 197113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 197213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 197313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 197413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 197513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 197613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 197713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Check if the requirements are met for a single declaration. If all 197813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * are met return 1. For the first requirement found to be missing, 197913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * if 'missing_sym_num' and 'missing_value' are both not NULL then 198013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * write to them the symbol number and value for the missing 198113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * declaration. Then return 0 to indicate a missing declaration. 198213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Note that if a declaration had no requirement at all (e.g., an ELSE 198313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * block) this returns 1. */ 198413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int is_decl_requires_met(link_state_t * state, 198513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t * decl, 198613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct missing_requirement *req) 198713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 198813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* (This algorithm is very unoptimized. It performs many 198913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * redundant checks. A very obvious improvement is to cache 199013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * which symbols have been verified, so that they do not need 199113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to be re-checked.) */ 199213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 199313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *bitmap; 199413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *perm_id; 199513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *pol = state->base; 199613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *node; 199713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 199813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check that all symbols have been satisfied */ 199913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 200013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (i == SYM_CLASSES) { 200113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* classes will be checked during permissions 200213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * checking phase below */ 200313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 200413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 200513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle bitmap = &decl->required.scope[i]; 200613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(bitmap, node, j) { 200713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(node, j)) { 200813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 200913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 201013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 201113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check base's scope table */ 201213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = pol->sym_val_to_name[i][j]; 201313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, i)) { 201413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this symbol was not found */ 201513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (req != NULL) { 201613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle req->symbol_type = i; 201713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle req->symbol_value = j + 1; 201813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 201913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 202013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 202113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 202213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 202313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check that all classes and permissions have been satisfied */ 202413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < decl->required.class_perms_len; i++) { 202513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 202613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle bitmap = decl->required.class_perms_map + i; 202713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(bitmap, node, j) { 202813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct find_perm_arg fparg; 202913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *cladatum; 203013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t perm_value = j + 1; 2031afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris int rc; 203213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope_datum_t *scope; 203313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 203413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(node, j)) { 203513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 203613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 203713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = pol->p_class_val_to_name[i]; 203813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cladatum = pol->class_val_to_struct[i]; 203913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 204013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle scope = 204113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(state->base->p_classes_scope.table, 204213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id); 204313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (scope == NULL) { 204413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 204513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Could not find scope information for class %s", 204613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id); 204713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 204813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 204913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 205013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.valuep = perm_value; 205113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.key = NULL; 205213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2053afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris (void)hashtab_map(cladatum->permissions.table, find_perm, 205413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &fparg); 2055afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris if (fparg.key == NULL && cladatum->comdatum != NULL) { 2056afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris rc = hashtab_map(cladatum->comdatum->permissions.table, 2057afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris find_perm, &fparg); 2058afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris assert(rc == 1); 2059afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris } 206013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_id = fparg.key; 206113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 206213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(perm_id != NULL); 206313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_perm_enabled(id, perm_id, state->base)) { 206413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (req != NULL) { 206513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle req->symbol_type = SYM_CLASSES; 206613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle req->symbol_value = i + 1; 206713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle req->perm_value = perm_value; 206813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 206913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 207013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 207113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 207213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 207313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 207413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* all requirements have been met */ 207513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 207613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 207713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 207813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int debug_requirements(link_state_t * state, policydb_t * p) 207913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 208013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 208113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *cur; 208213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle missing_requirement_t req; 2083afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris memset(&req, 0, sizeof(req)); 208413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 208513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (cur = p->global; cur != NULL; cur = cur->next) { 208613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur->enabled != NULL) 208713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 208813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 208913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = is_decl_requires_met(state, cur->branch_list, &req); 209013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret < 0) { 209113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 209213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (ret == 0) { 209314c0564641e6c8be386f117c2b0f09434121226fNicolas Iooss const char *mod_name = cur->branch_list->module_name ? 209413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur->branch_list->module_name : "BASE"; 209513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (req.symbol_type == SYM_CLASSES) { 209613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct find_perm_arg fparg; 209713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 209813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *cladatum; 2099afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris cladatum = p->class_val_to_struct[req.symbol_value - 1]; 210013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 210113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.valuep = req.perm_value; 210213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.key = NULL; 2103afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris (void)hashtab_map(cladatum->permissions.table, 2104afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris find_perm, &fparg); 210513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 210613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur->flags & AVRULE_OPTIONAL) { 210713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 210813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s[%d]'s optional requirements were not met: class %s, permission %s", 210913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_name, cur->branch_list->decl_id, 2110afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris p->p_class_val_to_name[req.symbol_value - 1], 211113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.key); 211213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 211313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 211413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s[%d]'s global requirements were not met: class %s, permission %s", 211513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_name, cur->branch_list->decl_id, 2116afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris p->p_class_val_to_name[req.symbol_value - 1], 211713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.key); 211813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 211913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 212013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur->flags & AVRULE_OPTIONAL) { 212113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 212213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s[%d]'s optional requirements were not met: %s %s", 212313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_name, cur->branch_list->decl_id, 212413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_names[req.symbol_type], 212513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->sym_val_to_name[req. 212613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symbol_type][req. 212713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symbol_value 212813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle - 212913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1]); 213013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 213113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 213213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s[%d]'s global requirements were not met: %s %s", 213313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_name, cur->branch_list->decl_id, 213413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_names[req.symbol_type], 213513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->sym_val_to_name[req. 213613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symbol_type][req. 213713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symbol_value 213813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle - 213913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1]); 214013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 214113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 214213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 214313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 214413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 214513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 214613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 214713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void print_missing_requirements(link_state_t * state, 214813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t * cur, 214913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle missing_requirement_t * req) 215013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 215113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *p = state->base; 215214c0564641e6c8be386f117c2b0f09434121226fNicolas Iooss const char *mod_name = cur->branch_list->module_name ? 215313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur->branch_list->module_name : "BASE"; 215413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 215513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (req->symbol_type == SYM_CLASSES) { 215613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 215713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct find_perm_arg fparg; 215813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 215913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *cladatum; 216013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cladatum = p->class_val_to_struct[req->symbol_value - 1]; 216113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 216213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.valuep = req->perm_value; 216313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fparg.key = NULL; 2164afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris (void)hashtab_map(cladatum->permissions.table, find_perm, &fparg); 216513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 216613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 216713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s's global requirements were not met: class %s, permission %s", 216813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_name, 216913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_class_val_to_name[req->symbol_value - 1], fparg.key); 217013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 217113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 217213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "%s's global requirements were not met: %s %s", 217313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_name, 217413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_names[req->symbol_type], 2175afe88d8c69543b2ebd6e25efdaab76f40ea4d3c7Eric Paris p->sym_val_to_name[req->symbol_type][req->symbol_value - 1]); 217613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 217713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 217813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 217913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Enable all of the avrule_decl blocks for the policy. This simple 218013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * algorithm is the following: 218113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 218213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1) Enable all of the non-else avrule_decls for all blocks. 218313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 2) Iterate through the non-else decls looking for decls whose requirements 218413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * are not met. 218513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 2a) If the decl is non-optional, return immediately with an error. 218613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 2b) If the decl is optional, disable the block and mark changed = 1 218713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 3) If changed == 1 goto 2. 218813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 4) Iterate through all blocks looking for those that have no enabled 218913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * decl. If the block has an else decl, enable. 219013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 219113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This will correctly handle all dependencies, including mutual and 219213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * cicular. The only downside is that it is slow. 219313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 219413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int enable_avrules(link_state_t * state, policydb_t * pol) 219513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 219613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int changed = 1; 219713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *block; 219813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 219913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle missing_requirement_t req; 220013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret = 0, rc; 220113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 220213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) { 220313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "Determining which avrules to enable."); 220413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 220513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 220613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* 1) enable all of the non-else blocks */ 220713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (block = pol->global; block != NULL; block = block->next) { 220813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->enabled = block->branch_list; 220913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->enabled->enabled = 1; 221013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (decl = block->branch_list->next; decl != NULL; 221113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl = decl->next) 221213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->enabled = 0; 221313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 221413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 221513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* 2) Iterate */ 221613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (changed) { 221713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle changed = 0; 221813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (block = pol->global; block != NULL; block = block->next) { 221913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (block->enabled == NULL) { 222013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 222113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 222213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl = block->branch_list; 222313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) { 222414c0564641e6c8be386f117c2b0f09434121226fNicolas Iooss const char *mod_name = decl->module_name ? 222513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->module_name : "BASE"; 222613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "check module %s decl %d\n", 222713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mod_name, decl->decl_id); 222813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 222913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = is_decl_requires_met(state, decl, &req); 223013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc < 0) { 223113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_ERR; 223213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 223313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (rc == 0) { 223413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl->enabled = 0; 223513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->enabled = NULL; 223613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle changed = 1; 223713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(block->flags & AVRULE_OPTIONAL)) { 223813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle print_missing_requirements(state, block, 223913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &req); 224013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = SEPOL_EREQ; 224113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 224213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 224313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 224413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 224513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 224613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 224713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* 4) else handling 224813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 224913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Iterate through all of the blocks skipping the first (which is the 225013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * global block, is required to be present, and cannot have an else). 225113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * If the block is disabled and has an else decl, enable that. 225213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 225313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This code assumes that the second block in the branch list is the else 225413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * block. This is currently supported by the compiler. 225513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 225613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (block = pol->global->next; block != NULL; block = block->next) { 225713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (block->enabled == NULL) { 225813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (block->branch_list->next != NULL) { 225913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->enabled = block->branch_list->next; 226013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle block->branch_list->next->enabled = 1; 226113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 226213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 226313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 226413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 226513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out: 226613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 226713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle debug_requirements(state, pol); 226813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 226913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 227013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 227113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 227213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*********** the main linking functions ***********/ 227313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 227413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Given a module's policy, normalize all conditional expressions 227513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * within. Return 0 on success, -1 on error. */ 227613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int cond_normalize(policydb_t * p) 227713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 227813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *block; 227913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (block = p->global; block != NULL; block = block->next) { 228013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 228113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (decl = block->branch_list; decl != NULL; decl = decl->next) { 228213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_list_t *cond = decl->cond_list; 228313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cond) { 228413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_normalize_expr(p, cond) < 0) 228513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 228613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond = cond->next; 228713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 228813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 228913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 229013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 229113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 229213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 229313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Allocate space for the various remapping arrays. */ 229413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int prepare_module(link_state_t * state, policy_module_t * module) 229513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 229613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i; 229713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t items, num_decls = 0; 229813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *cur; 229913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 230013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* allocate the maps */ 230113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < SYM_NUM; i++) { 230213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle items = module->policy->symtab[i].nprim; 230313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((module->map[i] = 230413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (uint32_t *) calloc(items, 230513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(*module->map[i]))) == NULL) { 230613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 230713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 230813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 230913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 231013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 231113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* allocate the permissions remap here */ 231213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle items = module->policy->p_classes.nprim; 231313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((module->perm_map_len = 231413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle calloc(items, sizeof(*module->perm_map_len))) == NULL) { 231513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 231613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 231713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 231813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((module->perm_map = 231913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle calloc(items, sizeof(*module->perm_map))) == NULL) { 232013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 232113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 232213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 232313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 232413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* allocate a map for avrule_decls */ 232513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (cur = module->policy->global; cur != NULL; cur = cur->next) { 232613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 232713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 232813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (decl->decl_id > num_decls) { 232913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle num_decls = decl->decl_id; 233013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 233113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 233213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 233313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle num_decls++; 233413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((module->avdecl_map = calloc(num_decls, sizeof(uint32_t))) == NULL) { 233513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 233613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 233713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 233813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->num_decls = num_decls; 233913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 234013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* normalize conditionals within */ 234113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_normalize(module->policy) < 0) { 234213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 234313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Error while normalizing conditionals within the module %s.", 234413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle module->policy->name); 234513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 234613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 234713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 234813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 234913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 235013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int prepare_base(link_state_t * state, uint32_t num_mod_decls) 235113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 235213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *cur = state->base->global; 235313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(cur != NULL); 235413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->next_decl_id = 0; 235513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 235613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* iterate through all of the declarations in the base, to 235713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle determine what the next decl_id should be */ 235813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur != NULL) { 235913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl; 236013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 236113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (decl->decl_id > state->next_decl_id) { 236213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->next_decl_id = decl->decl_id; 236313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 236413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 236513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->last_avrule_block = cur; 236613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 236713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 236813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->last_base_avrule_block = state->last_avrule_block; 236913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->next_decl_id++; 237013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 237113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* allocate the table mapping from base's decl_id to its 237213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * avrule_decls and set the initial mappings */ 237313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(state->base->decl_val_to_struct); 237413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((state->base->decl_val_to_struct = 237513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle calloc(state->next_decl_id + num_mod_decls, 237613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(*(state->base->decl_val_to_struct)))) == NULL) { 237713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 237813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 237913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 238013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* This allocates the decl block to module mapping used for error reporting */ 238113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((state->decl_to_mod = calloc(state->next_decl_id + num_mod_decls, 238213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(*(state->decl_to_mod)))) == 238313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL) { 238413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 238513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 238613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 238713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = state->base->global; 238813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur != NULL) { 238913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = cur->branch_list; 239013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (decl != NULL) { 239113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->decl_val_to_struct[decl->decl_id - 1] = 239213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl; 239313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->decl_to_mod[decl->decl_id] = state->base; 239413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle decl = decl->next; 239513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 239613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 239713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 239813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 239913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* normalize conditionals within */ 240013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_normalize(state->base) < 0) { 240113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 240213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Error while normalizing conditionals within the base module."); 240313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 240413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 240513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 240613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 240713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2408c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciaostatic int expand_role_attributes(hashtab_key_t key, hashtab_datum_t datum, 2409c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao void * data) 2410c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao{ 2411c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao char *id; 2412c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao role_datum_t *role, *sub_attr; 2413c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao link_state_t *state; 2414c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao unsigned int i; 2415c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao ebitmap_node_t *rnode; 2416c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2417c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao id = key; 2418c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao role = (role_datum_t *)datum; 2419c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao state = (link_state_t *)data; 2420c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2421c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (strcmp(id, OBJECT_R) == 0){ 2422c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* object_r is never a role attribute by far */ 2423c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return 0; 2424c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2425c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2426c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (role->flavor != ROLE_ATTRIB) 2427c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return 0; 2428c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2429c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (state->verbose) 2430c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao INFO(state->handle, "expanding role attribute %s", id); 2431c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2432c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciaorestart: 2433c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao ebitmap_for_each_bit(&role->roles, rnode, i) { 2434c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (ebitmap_node_get_bit(rnode, i)) { 2435c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao sub_attr = state->base->role_val_to_struct[i]; 2436c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (sub_attr->flavor != ROLE_ATTRIB) 2437c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao continue; 2438c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2439c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* remove the sub role attribute from the parent 2440c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * role attribute's roles ebitmap */ 2441c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (ebitmap_set_bit(&role->roles, i, 0)) 2442c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return -1; 2443c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2444c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* loop dependency of role attributes */ 2445c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (sub_attr->s.value == role->s.value) 2446c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao continue; 2447c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2448c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* now go on to expand a sub role attribute 2449c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * by escalating its roles ebitmap */ 2450c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (ebitmap_union(&role->roles, &sub_attr->roles)) { 2451c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao ERR(state->handle, "Out of memory!"); 2452c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return -1; 2453c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2454c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2455c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* sub_attr->roles may contain other role attributes, 2456c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * re-scan the parent role attribute's roles ebitmap */ 2457c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao goto restart; 2458c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2459c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2460c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2461c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return 0; 2462c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao} 2463c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2464c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao/* For any role attribute in a declaration's local symtab[SYM_ROLES] table, 2465c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * copy its roles ebitmap into its duplicate's in the base->p_roles.table. 2466c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao */ 2467c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciaostatic int populate_decl_roleattributes(hashtab_key_t key, 2468c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao hashtab_datum_t datum, 2469c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao void *data) 2470c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao{ 2471c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao char *id = key; 2472c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao role_datum_t *decl_role, *base_role; 2473c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao link_state_t *state = (link_state_t *)data; 2474c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2475c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao decl_role = (role_datum_t *)datum; 2476c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2477c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (strcmp(id, OBJECT_R) == 0) { 2478c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* object_r is never a role attribute by far */ 2479c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return 0; 2480c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2481c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2482c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (decl_role->flavor != ROLE_ATTRIB) 2483c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return 0; 2484c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2485c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao base_role = (role_datum_t *)hashtab_search(state->base->p_roles.table, 2486c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao id); 2487c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao assert(base_role != NULL && base_role->flavor == ROLE_ATTRIB); 2488c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2489c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (ebitmap_union(&base_role->roles, &decl_role->roles)) { 2490c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao ERR(state->handle, "Out of memory!"); 2491c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return -1; 2492c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2493c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2494c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return 0; 2495c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao} 2496c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2497c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciaostatic int populate_roleattributes(link_state_t *state, policydb_t *pol) 2498c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao{ 2499c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao avrule_block_t *block; 2500c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao avrule_decl_t *decl; 2501c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2502c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (state->verbose) 2503c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao INFO(state->handle, "Populating role-attribute relationship " 2504c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao "from enabled declarations' local symtab."); 2505c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2506c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* Iterate through all of the blocks skipping the first(which is the 2507c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * global block, is required to be present and can't have an else). 2508c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * If the block is disabled or not having an enabled decl, skip it. 2509c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao */ 2510c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao for (block = pol->global->next; block != NULL; block = block->next) 2511c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao { 2512c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao decl = block->enabled; 2513c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (decl == NULL || decl->enabled == 0) 2514c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao continue; 2515c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2516c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (hashtab_map(decl->symtab[SYM_ROLES].table, 2517c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao populate_decl_roleattributes, state)) 2518c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return -1; 2519c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2520c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2521c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao return 0; 2522c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao} 2523c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 252413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Link a set of modules into a base module. This process is somewhat 252513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * similar to an actual compiler: it requires a set of order dependent 252613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * steps. The base and every module must have been indexed prior to 252713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * calling this function. 252813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 252913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint link_modules(sepol_handle_t * handle, 253013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * b, policydb_t ** mods, int len, int verbose) 253113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 253213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i, ret, retval = -1; 253313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_t **modules = NULL; 253413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle link_state_t state; 253513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t num_mod_decls = 0; 253613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 253713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(&state, 0, sizeof(state)); 253813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.base = b; 253913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.verbose = verbose; 254013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.handle = handle; 254113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 254213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (b->policy_type != POLICY_BASE) { 254313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, "Target of link was not a base policy."); 254413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 254513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 254613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 254713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* first allocate some space to hold the maps from module 254813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * symbol's value to the destination symbol value; then do 254913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * other preparation work */ 255013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((modules = 255113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (policy_module_t **) calloc(len, sizeof(*modules))) == NULL) { 255213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, "Out of memory!"); 255313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 255413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 255513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < len; i++) { 255613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mods[i]->policy_type != POLICY_MOD) { 255713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, 255813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Tried to link in a policy that was not a module."); 255913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 256013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 256113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 256213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mods[i]->mls != b->mls) { 256313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (b->mls) 256413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, 256513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Tried to link in a non-MLS module with an MLS base."); 256613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 256713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, 256813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Tried to link in an MLS module with a non-MLS base."); 256913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 257013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 257113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 257213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((modules[i] = 257313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (policy_module_t *) calloc(1, 257413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(policy_module_t))) == 257513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL) { 257613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, "Out of memory!"); 257713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 257813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 257913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle modules[i]->policy = mods[i]; 258013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (prepare_module(&state, modules[i]) == -1) { 258113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 258213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 258313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle num_mod_decls += modules[i]->num_decls; 258413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 258513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (prepare_base(&state, num_mod_decls) == -1) { 258613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 258713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 258813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 258913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy all types, declared and required */ 259013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < len; i++) { 259113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.cur = modules[i]; 259213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.cur_mod_name = modules[i]->policy->name; 259313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 259413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_map(modules[i]->policy->p_types.table, 259513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_copy_callback, &state); 259613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 259713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = ret; 259813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 259913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 260013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 260113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 260213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* then copy everything else, including aliases, and fixup attributes */ 260313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < len; i++) { 260413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.cur = modules[i]; 260513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.cur_mod_name = modules[i]->policy->name; 260613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 260713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle copy_identifiers(&state, modules[i]->policy->symtab, NULL); 260813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 260913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = ret; 261013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 261113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 261213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 261313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 261413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_others(state.handle, state.base, 0)) { 261513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, "Error while indexing others"); 261613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 261713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 261813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 261913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy and remap the module's data over to base */ 262013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < len; i++) { 262113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.cur = modules[i]; 262213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = copy_module(&state, modules[i]); 262313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 262413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = ret; 262513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 262613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 262713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 262813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 262913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* re-index base, for symbols were added to symbol tables */ 263013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_classes(state.base)) { 263113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, "Error while indexing classes"); 263213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 263313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 263413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_others(state.handle, state.base, 0)) { 263513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state.handle, "Error while indexing others"); 263613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 263713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 263813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 263913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (enable_avrules(&state, state.base)) { 264013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = SEPOL_EREQ; 264113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 264213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 264313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2644c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* Now that all role attribute's roles ebitmap have been settled, 2645c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * escalate sub role attribute's roles ebitmap into that of parent. 2646c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * 2647c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * First, since some role-attribute relationships could be recorded 2648c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * in some decl's local symtab(see get_local_role()), we need to 2649c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao * populate them up to the base.p_roles table. */ 2650c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (populate_roleattributes(&state, state.base)) { 2651c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao retval = SEPOL_EREQ; 2652c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao goto cleanup; 2653c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao } 2654c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 2655c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao /* Now do the escalation. */ 2656c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao if (hashtab_map(state.base->p_roles.table, expand_role_attributes, 2657c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao &state)) 2658c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao goto cleanup; 2659c3f5d75c3234ea2b03c7eba9eb18b550efcc1605Harry Ciao 266013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 0; 266113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 266213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; modules != NULL && i < len; i++) { 266313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policy_module_destroy(modules[i]); 266413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 266513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(modules); 266613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(state.decl_to_mod); 266713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 266813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 2669