1255e72915d4cbddceb435e13d81601755714e9fSE Android/* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 2255e72915d4cbddceb435e13d81601755714e9fSE Android * Joshua Brindle <jbrindle@tresys.com> 3255e72915d4cbddceb435e13d81601755714e9fSE Android * Jason Tang <jtang@tresys.com> 4255e72915d4cbddceb435e13d81601755714e9fSE Android * 5255e72915d4cbddceb435e13d81601755714e9fSE Android * Copyright (C) 2004-2005 Tresys Technology, LLC 6255e72915d4cbddceb435e13d81601755714e9fSE Android * Copyright (C) 2007 Red Hat, Inc. 7255e72915d4cbddceb435e13d81601755714e9fSE Android * 8255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is free software; you can redistribute it and/or 9255e72915d4cbddceb435e13d81601755714e9fSE Android * modify it under the terms of the GNU Lesser General Public 10255e72915d4cbddceb435e13d81601755714e9fSE Android * License as published by the Free Software Foundation; either 11255e72915d4cbddceb435e13d81601755714e9fSE Android * version 2.1 of the License, or (at your option) any later version. 12255e72915d4cbddceb435e13d81601755714e9fSE Android * 13255e72915d4cbddceb435e13d81601755714e9fSE Android * This library is distributed in the hope that it will be useful, 14255e72915d4cbddceb435e13d81601755714e9fSE Android * but WITHOUT ANY WARRANTY; without even the implied warranty of 15255e72915d4cbddceb435e13d81601755714e9fSE Android * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16255e72915d4cbddceb435e13d81601755714e9fSE Android * Lesser General Public License for more details. 17255e72915d4cbddceb435e13d81601755714e9fSE Android * 18255e72915d4cbddceb435e13d81601755714e9fSE Android * You should have received a copy of the GNU Lesser General Public 19255e72915d4cbddceb435e13d81601755714e9fSE Android * License along with this library; if not, write to the Free Software 20255e72915d4cbddceb435e13d81601755714e9fSE Android * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21255e72915d4cbddceb435e13d81601755714e9fSE Android */ 22255e72915d4cbddceb435e13d81601755714e9fSE Android 23255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 24255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/conditional.h> 25255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/hashtab.h> 26255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/avrule_block.h> 27255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/link.h> 28255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/util.h> 29255e72915d4cbddceb435e13d81601755714e9fSE Android 30255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 31255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdarg.h> 32255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdio.h> 33255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h> 34255e72915d4cbddceb435e13d81601755714e9fSE Android#include <assert.h> 35255e72915d4cbddceb435e13d81601755714e9fSE Android 36255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 37255e72915d4cbddceb435e13d81601755714e9fSE Android 38255e72915d4cbddceb435e13d81601755714e9fSE Android#undef min 39255e72915d4cbddceb435e13d81601755714e9fSE Android#define min(a,b) (((a) < (b)) ? (a) : (b)) 40255e72915d4cbddceb435e13d81601755714e9fSE Android 41255e72915d4cbddceb435e13d81601755714e9fSE Androidtypedef struct policy_module { 42255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *policy; 43255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t num_decls; 44255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *map[SYM_NUM]; 45255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *avdecl_map; 46255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t **perm_map; 47255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *perm_map_len; 48255e72915d4cbddceb435e13d81601755714e9fSE Android 49255e72915d4cbddceb435e13d81601755714e9fSE Android /* a pointer to within the base module's avrule_block chain to 50255e72915d4cbddceb435e13d81601755714e9fSE Android * where this module's global now resides */ 51255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *base_global; 52255e72915d4cbddceb435e13d81601755714e9fSE Android} policy_module_t; 53255e72915d4cbddceb435e13d81601755714e9fSE Android 54255e72915d4cbddceb435e13d81601755714e9fSE Androidtypedef struct link_state { 55255e72915d4cbddceb435e13d81601755714e9fSE Android int verbose; 56255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *base; 57255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *last_avrule_block, *last_base_avrule_block; 58255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t next_decl_id, current_decl_id; 59255e72915d4cbddceb435e13d81601755714e9fSE Android 60255e72915d4cbddceb435e13d81601755714e9fSE Android /* temporary variables, used during hashtab_map() calls */ 61255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t *cur; 62255e72915d4cbddceb435e13d81601755714e9fSE Android char *cur_mod_name; 63255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *dest_decl; 64255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *src_class, *dest_class; 65255e72915d4cbddceb435e13d81601755714e9fSE Android char *dest_class_name; 66255e72915d4cbddceb435e13d81601755714e9fSE Android char dest_class_req; /* flag indicating the class was not declared */ 67255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t symbol_num; 68255e72915d4cbddceb435e13d81601755714e9fSE Android /* used to report the name of the module if dependancy error occurs */ 69255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t **decl_to_mod; 70255e72915d4cbddceb435e13d81601755714e9fSE Android 71255e72915d4cbddceb435e13d81601755714e9fSE Android /* error reporting fields */ 72255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_handle_t *handle; 73255e72915d4cbddceb435e13d81601755714e9fSE Android} link_state_t; 74255e72915d4cbddceb435e13d81601755714e9fSE Android 75255e72915d4cbddceb435e13d81601755714e9fSE Androidtypedef struct missing_requirement { 76255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t symbol_type; 77255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t symbol_value; 78255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t perm_value; 79255e72915d4cbddceb435e13d81601755714e9fSE Android} missing_requirement_t; 80255e72915d4cbddceb435e13d81601755714e9fSE Android 81255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic const char *symtab_names[SYM_NUM] = { 82255e72915d4cbddceb435e13d81601755714e9fSE Android "common", "class", "role", "type/attribute", "user", 83255e72915d4cbddceb435e13d81601755714e9fSE Android "bool", "level", "category" 84255e72915d4cbddceb435e13d81601755714e9fSE Android}; 85255e72915d4cbddceb435e13d81601755714e9fSE Android 86255e72915d4cbddceb435e13d81601755714e9fSE Android/* Deallocates all elements within a module, but NOT the policydb_t 87255e72915d4cbddceb435e13d81601755714e9fSE Android * structure within, as well as the pointer itself. */ 88255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic void policy_module_destroy(policy_module_t * mod) 89255e72915d4cbddceb435e13d81601755714e9fSE Android{ 90255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 91255e72915d4cbddceb435e13d81601755714e9fSE Android if (mod == NULL) { 92255e72915d4cbddceb435e13d81601755714e9fSE Android return; 93255e72915d4cbddceb435e13d81601755714e9fSE Android } 94255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < SYM_NUM; i++) { 95255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->map[i]); 96255e72915d4cbddceb435e13d81601755714e9fSE Android } 97255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; mod->perm_map != NULL && i < mod->policy->p_classes.nprim; 98255e72915d4cbddceb435e13d81601755714e9fSE Android i++) { 99255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->perm_map[i]); 100255e72915d4cbddceb435e13d81601755714e9fSE Android } 101255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->perm_map); 102255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->perm_map_len); 103255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->avdecl_map); 104255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod); 105255e72915d4cbddceb435e13d81601755714e9fSE Android} 106255e72915d4cbddceb435e13d81601755714e9fSE Android 107255e72915d4cbddceb435e13d81601755714e9fSE Android/***** functions that copy identifiers from a module to base *****/ 108255e72915d4cbddceb435e13d81601755714e9fSE Android 109255e72915d4cbddceb435e13d81601755714e9fSE Android/* Note: there is currently no scoping for permissions, which causes some 110255e72915d4cbddceb435e13d81601755714e9fSE Android * strange side-effects. The current approach is this: 111255e72915d4cbddceb435e13d81601755714e9fSE Android * 112255e72915d4cbddceb435e13d81601755714e9fSE Android * a) perm is required and the class _and_ perm are declared in base: only add a mapping. 113255e72915d4cbddceb435e13d81601755714e9fSE Android * b) perm is required and the class and perm are _not_ declared in base: simply add the permissions 114255e72915d4cbddceb435e13d81601755714e9fSE Android * to the object class. This means that the requirements for the decl are the union of the permissions 115255e72915d4cbddceb435e13d81601755714e9fSE Android * required for all decls, but who cares. 116255e72915d4cbddceb435e13d81601755714e9fSE Android * c) perm is required, the class is declared in base, but the perm is not present. Nothing we can do 117255e72915d4cbddceb435e13d81601755714e9fSE Android * here because we can't mark a single permission as required, so we bail with a requirement error 118255e72915d4cbddceb435e13d81601755714e9fSE Android * _even_ if we are in an optional. 119255e72915d4cbddceb435e13d81601755714e9fSE Android * 120255e72915d4cbddceb435e13d81601755714e9fSE Android * A is correct behavior, b is wrong but not too bad, c is totall wrong for optionals. Fixing this requires 121255e72915d4cbddceb435e13d81601755714e9fSE Android * a format change. 122255e72915d4cbddceb435e13d81601755714e9fSE Android */ 123255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int permission_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 124255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 125255e72915d4cbddceb435e13d81601755714e9fSE Android{ 126255e72915d4cbddceb435e13d81601755714e9fSE Android char *perm_id = key, *new_id = NULL; 127255e72915d4cbddceb435e13d81601755714e9fSE Android perm_datum_t *perm, *new_perm = NULL, *dest_perm; 128255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 129255e72915d4cbddceb435e13d81601755714e9fSE Android 130255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *src_class = state->src_class; 131255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *dest_class = state->dest_class; 132255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t *mod = state->cur; 133255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t sclassi = src_class->s.value - 1; 134255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 135255e72915d4cbddceb435e13d81601755714e9fSE Android 136255e72915d4cbddceb435e13d81601755714e9fSE Android perm = (perm_datum_t *) datum; 137255e72915d4cbddceb435e13d81601755714e9fSE Android dest_perm = hashtab_search(dest_class->permissions.table, perm_id); 138255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest_perm == NULL && dest_class->comdatum != NULL) { 139255e72915d4cbddceb435e13d81601755714e9fSE Android dest_perm = 140255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(dest_class->comdatum->permissions.table, 141255e72915d4cbddceb435e13d81601755714e9fSE Android perm_id); 142255e72915d4cbddceb435e13d81601755714e9fSE Android } 143255e72915d4cbddceb435e13d81601755714e9fSE Android 144255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest_perm == NULL) { 145255e72915d4cbddceb435e13d81601755714e9fSE Android /* If the object class was not declared in the base, add the perm 146255e72915d4cbddceb435e13d81601755714e9fSE Android * to the object class. */ 147255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->dest_class_req) { 148255e72915d4cbddceb435e13d81601755714e9fSE Android /* If the class was required (not declared), insert the new permission */ 149255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(perm_id); 150255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_id == NULL) { 151255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Memory error"); 152255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ERR; 153255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 154255e72915d4cbddceb435e13d81601755714e9fSE Android } 155255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm = 156255e72915d4cbddceb435e13d81601755714e9fSE Android (perm_datum_t *) calloc(1, sizeof(perm_datum_t)); 157255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_perm == NULL) { 158255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Memory error"); 159255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ERR; 160255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 161255e72915d4cbddceb435e13d81601755714e9fSE Android } 162255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(dest_class->permissions.table, 163255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 164255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_perm); 165255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 166255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 167255e72915d4cbddceb435e13d81601755714e9fSE Android "could not insert permission into class\n"); 168255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 169255e72915d4cbddceb435e13d81601755714e9fSE Android } 170255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm->s.value = dest_class->permissions.nprim + 1; 171255e72915d4cbddceb435e13d81601755714e9fSE Android dest_perm = new_perm; 172255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 173255e72915d4cbddceb435e13d81601755714e9fSE Android /* this is case c from above */ 174255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 175255e72915d4cbddceb435e13d81601755714e9fSE Android "Module %s depends on permission %s in class %s, not satisfied", 176255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, perm_id, 177255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_class_name); 178255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_EREQ; 179255e72915d4cbddceb435e13d81601755714e9fSE Android } 180255e72915d4cbddceb435e13d81601755714e9fSE Android } 181255e72915d4cbddceb435e13d81601755714e9fSE Android 182255e72915d4cbddceb435e13d81601755714e9fSE Android /* build the mapping for permissions encompassing this class. 183255e72915d4cbddceb435e13d81601755714e9fSE Android * unlike symbols, the permission map translates between 184255e72915d4cbddceb435e13d81601755714e9fSE Android * module permission bit to target permission bit. that bit 185255e72915d4cbddceb435e13d81601755714e9fSE Android * may have originated from the class -or- it could be from 186255e72915d4cbddceb435e13d81601755714e9fSE Android * the class's common parent.*/ 187255e72915d4cbddceb435e13d81601755714e9fSE Android if (perm->s.value > mod->perm_map_len[sclassi]) { 188255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *newmap = calloc(perm->s.value, sizeof(*newmap)); 189255e72915d4cbddceb435e13d81601755714e9fSE Android if (newmap == NULL) { 190255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 191255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 192255e72915d4cbddceb435e13d81601755714e9fSE Android } 193255e72915d4cbddceb435e13d81601755714e9fSE Android memcpy(newmap, mod->perm_map[sclassi], 194255e72915d4cbddceb435e13d81601755714e9fSE Android mod->perm_map_len[sclassi] * sizeof(*newmap)); 195255e72915d4cbddceb435e13d81601755714e9fSE Android free(mod->perm_map[sclassi]); 196255e72915d4cbddceb435e13d81601755714e9fSE Android mod->perm_map[sclassi] = newmap; 197255e72915d4cbddceb435e13d81601755714e9fSE Android mod->perm_map_len[sclassi] = perm->s.value; 198255e72915d4cbddceb435e13d81601755714e9fSE Android } 199255e72915d4cbddceb435e13d81601755714e9fSE Android mod->perm_map[sclassi][perm->s.value - 1] = dest_perm->s.value; 200255e72915d4cbddceb435e13d81601755714e9fSE Android 201255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 202255e72915d4cbddceb435e13d81601755714e9fSE Android err: 203255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 204255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_perm); 205255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 206255e72915d4cbddceb435e13d81601755714e9fSE Android} 207255e72915d4cbddceb435e13d81601755714e9fSE Android 208255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 209255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 210255e72915d4cbddceb435e13d81601755714e9fSE Android{ 211255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key, *new_id = NULL; 212255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *cladatum, *new_class = NULL; 213255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 214255e72915d4cbddceb435e13d81601755714e9fSE Android scope_datum_t *scope = NULL; 215255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 216255e72915d4cbddceb435e13d81601755714e9fSE Android 217255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum = (class_datum_t *) datum; 218255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_class_req = 0; 219255e72915d4cbddceb435e13d81601755714e9fSE Android 220255e72915d4cbddceb435e13d81601755714e9fSE Android new_class = hashtab_search(state->base->p_classes.table, id); 221255e72915d4cbddceb435e13d81601755714e9fSE Android /* If there is not an object class already in the base symtab that means 222255e72915d4cbddceb435e13d81601755714e9fSE Android * that either a) a module is trying to declare a new object class (which 223255e72915d4cbddceb435e13d81601755714e9fSE Android * the compiler should prevent) or b) an object class was required that is 224255e72915d4cbddceb435e13d81601755714e9fSE Android * not in the base. 225255e72915d4cbddceb435e13d81601755714e9fSE Android */ 226255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_class == NULL) { 227255e72915d4cbddceb435e13d81601755714e9fSE Android scope = 228255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(state->cur->policy->p_classes_scope.table, 229255e72915d4cbddceb435e13d81601755714e9fSE Android id); 230255e72915d4cbddceb435e13d81601755714e9fSE Android if (scope == NULL) { 231255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ERR; 232255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 233255e72915d4cbddceb435e13d81601755714e9fSE Android } 234255e72915d4cbddceb435e13d81601755714e9fSE Android if (scope->scope == SCOPE_DECL) { 235255e72915d4cbddceb435e13d81601755714e9fSE Android /* disallow declarations in modules */ 236255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 237255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Modules may not yet declare new classes.", 238255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name); 239255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ENOTSUP; 240255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 241255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 242255e72915d4cbddceb435e13d81601755714e9fSE Android /* It would be nice to error early here because the requirement is 243255e72915d4cbddceb435e13d81601755714e9fSE Android * not met, but we cannot because the decl might be optional (in which 244255e72915d4cbddceb435e13d81601755714e9fSE Android * case we should record the requirement so that it is just turned 245255e72915d4cbddceb435e13d81601755714e9fSE Android * off). Note: this will break horribly if modules can declare object 246255e72915d4cbddceb435e13d81601755714e9fSE Android * classes because the class numbers will be all wrong (i.e., they 247255e72915d4cbddceb435e13d81601755714e9fSE Android * might be assigned in the order they were required rather than the 248255e72915d4cbddceb435e13d81601755714e9fSE Android * current scheme which ensures correct numbering by ordering the 249255e72915d4cbddceb435e13d81601755714e9fSE Android * declarations properly). This can't be fixed until some infrastructure 250255e72915d4cbddceb435e13d81601755714e9fSE Android * for querying the object class numbers is in place. */ 251255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_class_req = 1; 252255e72915d4cbddceb435e13d81601755714e9fSE Android new_class = 253255e72915d4cbddceb435e13d81601755714e9fSE Android (class_datum_t *) calloc(1, sizeof(class_datum_t)); 254255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_class == NULL) { 255255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Memory error\n"); 256255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ERR; 257255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 258255e72915d4cbddceb435e13d81601755714e9fSE Android } 259255e72915d4cbddceb435e13d81601755714e9fSE Android if (symtab_init 260255e72915d4cbddceb435e13d81601755714e9fSE Android (&new_class->permissions, PERM_SYMTAB_SIZE)) { 261255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ERR; 262255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 263255e72915d4cbddceb435e13d81601755714e9fSE Android } 264255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 265255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_id == NULL) { 266255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Memory error\n"); 267255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ERR; 268255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 269255e72915d4cbddceb435e13d81601755714e9fSE Android } 270255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->base->p_classes.table, 271255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 272255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_class); 273255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 274255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 275255e72915d4cbddceb435e13d81601755714e9fSE Android "could not insert new class into symtab"); 276255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 277255e72915d4cbddceb435e13d81601755714e9fSE Android } 278255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->s.value = ++(state->base->p_classes.nprim); 279255e72915d4cbddceb435e13d81601755714e9fSE Android } 280255e72915d4cbddceb435e13d81601755714e9fSE Android } 281255e72915d4cbddceb435e13d81601755714e9fSE Android 282255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur->map[SYM_CLASSES][cladatum->s.value - 1] = 283255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->s.value; 284255e72915d4cbddceb435e13d81601755714e9fSE Android 285255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy permissions */ 286255e72915d4cbddceb435e13d81601755714e9fSE Android state->src_class = cladatum; 287255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_class = new_class; 288255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_class_name = (char *)key; 289255e72915d4cbddceb435e13d81601755714e9fSE Android 290255e72915d4cbddceb435e13d81601755714e9fSE Android ret = 291255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(cladatum->permissions.table, permission_copy_callback, 292255e72915d4cbddceb435e13d81601755714e9fSE Android state); 293255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret != 0) { 294255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 295255e72915d4cbddceb435e13d81601755714e9fSE Android } 296255e72915d4cbddceb435e13d81601755714e9fSE Android 297255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 298255e72915d4cbddceb435e13d81601755714e9fSE Android err: 299255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_class); 300255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 301255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 302255e72915d4cbddceb435e13d81601755714e9fSE Android} 303255e72915d4cbddceb435e13d81601755714e9fSE Android 304255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 305255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 306255e72915d4cbddceb435e13d81601755714e9fSE Android{ 307255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 308255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key, *new_id = NULL; 309255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role, *base_role, *new_role = NULL; 310255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 311255e72915d4cbddceb435e13d81601755714e9fSE Android 312255e72915d4cbddceb435e13d81601755714e9fSE Android role = (role_datum_t *) datum; 313255e72915d4cbddceb435e13d81601755714e9fSE Android 314255e72915d4cbddceb435e13d81601755714e9fSE Android base_role = hashtab_search(state->base->p_roles.table, id); 315255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_role != NULL) { 316255e72915d4cbddceb435e13d81601755714e9fSE Android /* role already exists. check that it is what this 317255e72915d4cbddceb435e13d81601755714e9fSE Android * module expected. duplicate declarations (e.g., two 318255e72915d4cbddceb435e13d81601755714e9fSE Android * modules both declare role foo_r) is checked during 319255e72915d4cbddceb435e13d81601755714e9fSE Android * scope_copy_callback(). */ 320255e72915d4cbddceb435e13d81601755714e9fSE Android if (role->flavor == ROLE_ATTRIB 321255e72915d4cbddceb435e13d81601755714e9fSE Android && base_role->flavor != ROLE_ATTRIB) { 322255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 323255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Expected %s to be a role attribute, but it was already declared as a regular role.", 324255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, id); 325255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 326255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (role->flavor != ROLE_ATTRIB 327255e72915d4cbddceb435e13d81601755714e9fSE Android && base_role->flavor == ROLE_ATTRIB) { 328255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 329255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Expected %s to be a regular role, but it was already declared as a role attribute.", 330255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, id); 331255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 332255e72915d4cbddceb435e13d81601755714e9fSE Android } 333255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 334255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 335255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying role %s", id); 336255e72915d4cbddceb435e13d81601755714e9fSE Android 337255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 338255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 339255e72915d4cbddceb435e13d81601755714e9fSE Android } 340255e72915d4cbddceb435e13d81601755714e9fSE Android 341255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_role = 342255e72915d4cbddceb435e13d81601755714e9fSE Android (role_datum_t *) malloc(sizeof(*new_role))) == NULL) { 343255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 344255e72915d4cbddceb435e13d81601755714e9fSE Android } 345255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_init(new_role); 346255e72915d4cbddceb435e13d81601755714e9fSE Android 347255e72915d4cbddceb435e13d81601755714e9fSE Android /* new_role's dominates, types and roles field will be copied 348255e72915d4cbddceb435e13d81601755714e9fSE Android * during role_fix_callback() */ 349255e72915d4cbddceb435e13d81601755714e9fSE Android new_role->flavor = role->flavor; 350255e72915d4cbddceb435e13d81601755714e9fSE Android new_role->s.value = state->base->p_roles.nprim + 1; 351255e72915d4cbddceb435e13d81601755714e9fSE Android 352255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->base->p_roles.table, 353255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 354255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_role); 355255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 356255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 357255e72915d4cbddceb435e13d81601755714e9fSE Android } 358255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->p_roles.nprim++; 359255e72915d4cbddceb435e13d81601755714e9fSE Android base_role = new_role; 360255e72915d4cbddceb435e13d81601755714e9fSE Android } 361255e72915d4cbddceb435e13d81601755714e9fSE Android 362255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->dest_decl) { 363255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = NULL; 364255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_role = malloc(sizeof(*new_role))) == NULL) { 365255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 366255e72915d4cbddceb435e13d81601755714e9fSE Android } 367255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_init(new_role); 368255e72915d4cbddceb435e13d81601755714e9fSE Android new_role->flavor = base_role->flavor; 369255e72915d4cbddceb435e13d81601755714e9fSE Android new_role->s.value = base_role->s.value; 370255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 371255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 372255e72915d4cbddceb435e13d81601755714e9fSE Android } 373255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_insert 374255e72915d4cbddceb435e13d81601755714e9fSE Android (state->dest_decl->p_roles.table, new_id, new_role)) { 375255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 376255e72915d4cbddceb435e13d81601755714e9fSE Android } 377255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_decl->p_roles.nprim++; 378255e72915d4cbddceb435e13d81601755714e9fSE Android } 379255e72915d4cbddceb435e13d81601755714e9fSE Android 380255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur->map[SYM_ROLES][role->s.value - 1] = base_role->s.value; 381255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 382255e72915d4cbddceb435e13d81601755714e9fSE Android 383255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 384255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 385255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_destroy(new_role); 386255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 387255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_role); 388255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 389255e72915d4cbddceb435e13d81601755714e9fSE Android} 390255e72915d4cbddceb435e13d81601755714e9fSE Android 391255e72915d4cbddceb435e13d81601755714e9fSE Android/* Copy types and attributes from a module into the base module. The 392255e72915d4cbddceb435e13d81601755714e9fSE Android * attributes are copied, but the types that make up this attribute 393255e72915d4cbddceb435e13d81601755714e9fSE Android * are delayed type_fix_callback(). */ 394255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 395255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 396255e72915d4cbddceb435e13d81601755714e9fSE Android{ 397255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 398255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key, *new_id = NULL; 399255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type, *base_type, *new_type = NULL; 400255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 401255e72915d4cbddceb435e13d81601755714e9fSE Android 402255e72915d4cbddceb435e13d81601755714e9fSE Android type = (type_datum_t *) datum; 403255e72915d4cbddceb435e13d81601755714e9fSE Android if ((type->flavor == TYPE_TYPE && !type->primary) 404255e72915d4cbddceb435e13d81601755714e9fSE Android || type->flavor == TYPE_ALIAS) { 405255e72915d4cbddceb435e13d81601755714e9fSE Android /* aliases are handled later, in alias_copy_callback() */ 406255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 407255e72915d4cbddceb435e13d81601755714e9fSE Android } 408255e72915d4cbddceb435e13d81601755714e9fSE Android 409255e72915d4cbddceb435e13d81601755714e9fSE Android base_type = hashtab_search(state->base->p_types.table, id); 410255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_type != NULL) { 411255e72915d4cbddceb435e13d81601755714e9fSE Android /* type already exists. check that it is what this 412255e72915d4cbddceb435e13d81601755714e9fSE Android * module expected. duplicate declarations (e.g., two 413255e72915d4cbddceb435e13d81601755714e9fSE Android * modules both declare type foo_t) is checked during 414255e72915d4cbddceb435e13d81601755714e9fSE Android * scope_copy_callback(). */ 415255e72915d4cbddceb435e13d81601755714e9fSE Android if (type->flavor == TYPE_ATTRIB 416255e72915d4cbddceb435e13d81601755714e9fSE Android && base_type->flavor != TYPE_ATTRIB) { 417255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 418255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Expected %s to be an attribute, but it was already declared as a type.", 419255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, id); 420255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 421255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (type->flavor != TYPE_ATTRIB 422255e72915d4cbddceb435e13d81601755714e9fSE Android && base_type->flavor == TYPE_ATTRIB) { 423255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 424255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Expected %s to be a type, but it was already declared as an attribute.", 425255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, id); 426255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 427255e72915d4cbddceb435e13d81601755714e9fSE Android } 428255e72915d4cbddceb435e13d81601755714e9fSE Android /* permissive should pass to the base type */ 429255e72915d4cbddceb435e13d81601755714e9fSE Android base_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); 430255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 431255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 432255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying type %s", id); 433255e72915d4cbddceb435e13d81601755714e9fSE Android 434255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 435255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 436255e72915d4cbddceb435e13d81601755714e9fSE Android } 437255e72915d4cbddceb435e13d81601755714e9fSE Android 438255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_type = 439255e72915d4cbddceb435e13d81601755714e9fSE Android (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) { 440255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 441255e72915d4cbddceb435e13d81601755714e9fSE Android } 442255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->primary = type->primary; 443255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flags = type->flags; 444255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flavor = type->flavor; 445255e72915d4cbddceb435e13d81601755714e9fSE Android /* for attributes, the writing of new_type->types is 446255e72915d4cbddceb435e13d81601755714e9fSE Android done in type_fix_callback() */ 447255e72915d4cbddceb435e13d81601755714e9fSE Android 448255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->s.value = state->base->p_types.nprim + 1; 449255e72915d4cbddceb435e13d81601755714e9fSE Android 450255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->base->p_types.table, 451255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 452255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_type); 453255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 454255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 455255e72915d4cbddceb435e13d81601755714e9fSE Android } 456255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->p_types.nprim++; 457255e72915d4cbddceb435e13d81601755714e9fSE Android base_type = new_type; 458255e72915d4cbddceb435e13d81601755714e9fSE Android } 459255e72915d4cbddceb435e13d81601755714e9fSE Android 460255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->dest_decl) { 461255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = NULL; 462255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_type = calloc(1, sizeof(*new_type))) == NULL) { 463255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 464255e72915d4cbddceb435e13d81601755714e9fSE Android } 465255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->primary = type->primary; 466255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flavor = type->flavor; 467255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flags = type->flags; 468255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->s.value = base_type->s.value; 469255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 470255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 471255e72915d4cbddceb435e13d81601755714e9fSE Android } 472255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_insert 473255e72915d4cbddceb435e13d81601755714e9fSE Android (state->dest_decl->p_types.table, new_id, new_type)) { 474255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 475255e72915d4cbddceb435e13d81601755714e9fSE Android } 476255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_decl->p_types.nprim++; 477255e72915d4cbddceb435e13d81601755714e9fSE Android } 478255e72915d4cbddceb435e13d81601755714e9fSE Android 479255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur->map[SYM_TYPES][type->s.value - 1] = base_type->s.value; 480255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 481255e72915d4cbddceb435e13d81601755714e9fSE Android 482255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 483255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 484255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 485255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_type); 486255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 487255e72915d4cbddceb435e13d81601755714e9fSE Android} 488255e72915d4cbddceb435e13d81601755714e9fSE Android 489255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 490255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 491255e72915d4cbddceb435e13d81601755714e9fSE Android{ 492255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 493255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key, *new_id = NULL; 494255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *user, *base_user, *new_user = NULL; 495255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 496255e72915d4cbddceb435e13d81601755714e9fSE Android 497255e72915d4cbddceb435e13d81601755714e9fSE Android user = (user_datum_t *) datum; 498255e72915d4cbddceb435e13d81601755714e9fSE Android 499255e72915d4cbddceb435e13d81601755714e9fSE Android base_user = hashtab_search(state->base->p_users.table, id); 500255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_user == NULL) { 501255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 502255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying user %s", id); 503255e72915d4cbddceb435e13d81601755714e9fSE Android 504255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 505255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 506255e72915d4cbddceb435e13d81601755714e9fSE Android } 507255e72915d4cbddceb435e13d81601755714e9fSE Android 508255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_user = 509255e72915d4cbddceb435e13d81601755714e9fSE Android (user_datum_t *) malloc(sizeof(*new_user))) == NULL) { 510255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 511255e72915d4cbddceb435e13d81601755714e9fSE Android } 512255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_init(new_user); 513255e72915d4cbddceb435e13d81601755714e9fSE Android /* new_users's roles and MLS fields will be copied during 514255e72915d4cbddceb435e13d81601755714e9fSE Android user_fix_callback(). */ 515255e72915d4cbddceb435e13d81601755714e9fSE Android 516255e72915d4cbddceb435e13d81601755714e9fSE Android new_user->s.value = state->base->p_users.nprim + 1; 517255e72915d4cbddceb435e13d81601755714e9fSE Android 518255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->base->p_users.table, 519255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 520255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_user); 521255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 522255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 523255e72915d4cbddceb435e13d81601755714e9fSE Android } 524255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->p_users.nprim++; 525255e72915d4cbddceb435e13d81601755714e9fSE Android base_user = new_user; 526255e72915d4cbddceb435e13d81601755714e9fSE Android } 527255e72915d4cbddceb435e13d81601755714e9fSE Android 528255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->dest_decl) { 529255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = NULL; 530255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_user = malloc(sizeof(*new_user))) == NULL) { 531255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 532255e72915d4cbddceb435e13d81601755714e9fSE Android } 533255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_init(new_user); 534255e72915d4cbddceb435e13d81601755714e9fSE Android new_user->s.value = base_user->s.value; 535255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 536255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 537255e72915d4cbddceb435e13d81601755714e9fSE Android } 538255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_insert 539255e72915d4cbddceb435e13d81601755714e9fSE Android (state->dest_decl->p_users.table, new_id, new_user)) { 540255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 541255e72915d4cbddceb435e13d81601755714e9fSE Android } 542255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_decl->p_users.nprim++; 543255e72915d4cbddceb435e13d81601755714e9fSE Android } 544255e72915d4cbddceb435e13d81601755714e9fSE Android 545255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur->map[SYM_USERS][user->s.value - 1] = base_user->s.value; 546255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 547255e72915d4cbddceb435e13d81601755714e9fSE Android 548255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 549255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 550255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_destroy(new_user); 551255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 552255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_user); 553255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 554255e72915d4cbddceb435e13d81601755714e9fSE Android} 555255e72915d4cbddceb435e13d81601755714e9fSE Android 556255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 557255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 558255e72915d4cbddceb435e13d81601755714e9fSE Android{ 559255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 560255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key, *new_id = NULL; 561255e72915d4cbddceb435e13d81601755714e9fSE Android cond_bool_datum_t *booldatum, *base_bool, *new_bool = NULL; 562255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 563255e72915d4cbddceb435e13d81601755714e9fSE Android scope_datum_t *scope; 564255e72915d4cbddceb435e13d81601755714e9fSE Android 565255e72915d4cbddceb435e13d81601755714e9fSE Android booldatum = (cond_bool_datum_t *) datum; 566255e72915d4cbddceb435e13d81601755714e9fSE Android 567255e72915d4cbddceb435e13d81601755714e9fSE Android base_bool = hashtab_search(state->base->p_bools.table, id); 568255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_bool == NULL) { 569255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 570255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying boolean %s", id); 571255e72915d4cbddceb435e13d81601755714e9fSE Android 572255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 573255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 574255e72915d4cbddceb435e13d81601755714e9fSE Android } 575255e72915d4cbddceb435e13d81601755714e9fSE Android 576255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_bool = 577255e72915d4cbddceb435e13d81601755714e9fSE Android (cond_bool_datum_t *) malloc(sizeof(*new_bool))) == NULL) { 578255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 579255e72915d4cbddceb435e13d81601755714e9fSE Android } 580255e72915d4cbddceb435e13d81601755714e9fSE Android new_bool->s.value = state->base->p_bools.nprim + 1; 581255e72915d4cbddceb435e13d81601755714e9fSE Android 582255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->base->p_bools.table, 583255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 584255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_bool); 585255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 586255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 587255e72915d4cbddceb435e13d81601755714e9fSE Android } 588255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->p_bools.nprim++; 589255e72915d4cbddceb435e13d81601755714e9fSE Android base_bool = new_bool; 590fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley base_bool->flags = booldatum->flags; 591fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } else if ((booldatum->flags & COND_BOOL_FLAGS_TUNABLE) != 592fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley (base_bool->flags & COND_BOOL_FLAGS_TUNABLE)) { 593fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* A mismatch between boolean/tunable declaration 594fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * and usage(for example a boolean used in the 595fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * tunable_policy() or vice versa). 596fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * 597fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * This is not allowed and bail out with errors */ 598fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley ERR(state->handle, 599fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley "%s: Mismatch between boolean/tunable definition " 600fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley "and usage for %s", state->cur_mod_name, id); 601fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley return -1; 602255e72915d4cbddceb435e13d81601755714e9fSE Android } 603255e72915d4cbddceb435e13d81601755714e9fSE Android 604255e72915d4cbddceb435e13d81601755714e9fSE Android /* Get the scope info for this boolean to see if this is the declaration, 605255e72915d4cbddceb435e13d81601755714e9fSE Android * if so set the state */ 606255e72915d4cbddceb435e13d81601755714e9fSE Android scope = hashtab_search(state->cur->policy->p_bools_scope.table, id); 607255e72915d4cbddceb435e13d81601755714e9fSE Android if (!scope) 608255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ERR; 609fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (scope->scope == SCOPE_DECL) { 610255e72915d4cbddceb435e13d81601755714e9fSE Android base_bool->state = booldatum->state; 611fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* Only the declaration rather than requirement 612fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * decides if it is a boolean or tunable. */ 613fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley base_bool->flags = booldatum->flags; 614fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 615255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur->map[SYM_BOOLS][booldatum->s.value - 1] = base_bool->s.value; 616255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 617255e72915d4cbddceb435e13d81601755714e9fSE Android 618255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 619255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 620255e72915d4cbddceb435e13d81601755714e9fSE Android cond_destroy_bool(new_id, new_bool, NULL); 621255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 622255e72915d4cbddceb435e13d81601755714e9fSE Android} 623255e72915d4cbddceb435e13d81601755714e9fSE Android 624255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 625255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 626255e72915d4cbddceb435e13d81601755714e9fSE Android{ 627255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key; 628255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_t *level, *base_level; 629255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 630255e72915d4cbddceb435e13d81601755714e9fSE Android scope_datum_t *scope; 631255e72915d4cbddceb435e13d81601755714e9fSE Android 632255e72915d4cbddceb435e13d81601755714e9fSE Android level = (level_datum_t *) datum; 633255e72915d4cbddceb435e13d81601755714e9fSE Android 634255e72915d4cbddceb435e13d81601755714e9fSE Android base_level = hashtab_search(state->base->p_levels.table, id); 635255e72915d4cbddceb435e13d81601755714e9fSE Android if (!base_level) { 636255e72915d4cbddceb435e13d81601755714e9fSE Android scope = 637255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(state->cur->policy->p_sens_scope.table, id); 638255e72915d4cbddceb435e13d81601755714e9fSE Android if (!scope) 639255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ERR; 640255e72915d4cbddceb435e13d81601755714e9fSE Android if (scope->scope == SCOPE_DECL) { 641255e72915d4cbddceb435e13d81601755714e9fSE Android /* disallow declarations in modules */ 642255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 643255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Modules may not declare new sensitivities.", 644255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name); 645255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ENOTSUP; 646255e72915d4cbddceb435e13d81601755714e9fSE Android } 647255e72915d4cbddceb435e13d81601755714e9fSE Android if (scope->scope == SCOPE_REQ) { 648255e72915d4cbddceb435e13d81601755714e9fSE Android /* unmet requirement */ 649255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 650255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Sensitivity %s not declared by base.", 651255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, id); 652255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ENOTSUP; 653255e72915d4cbddceb435e13d81601755714e9fSE Android } 654255e72915d4cbddceb435e13d81601755714e9fSE Android } 655255e72915d4cbddceb435e13d81601755714e9fSE Android 656255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur->map[SYM_LEVELS][level->level->sens - 1] = 657255e72915d4cbddceb435e13d81601755714e9fSE Android base_level->level->sens; 658255e72915d4cbddceb435e13d81601755714e9fSE Android 659255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 660255e72915d4cbddceb435e13d81601755714e9fSE Android} 661255e72915d4cbddceb435e13d81601755714e9fSE Android 662255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 663255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 664255e72915d4cbddceb435e13d81601755714e9fSE Android{ 665255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key; 666255e72915d4cbddceb435e13d81601755714e9fSE Android cat_datum_t *cat, *base_cat; 667255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 668255e72915d4cbddceb435e13d81601755714e9fSE Android scope_datum_t *scope; 669255e72915d4cbddceb435e13d81601755714e9fSE Android 670255e72915d4cbddceb435e13d81601755714e9fSE Android cat = (cat_datum_t *) datum; 671255e72915d4cbddceb435e13d81601755714e9fSE Android 672255e72915d4cbddceb435e13d81601755714e9fSE Android base_cat = hashtab_search(state->base->p_cats.table, id); 673255e72915d4cbddceb435e13d81601755714e9fSE Android if (!base_cat) { 674255e72915d4cbddceb435e13d81601755714e9fSE Android scope = 675255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(state->cur->policy->p_cat_scope.table, id); 676255e72915d4cbddceb435e13d81601755714e9fSE Android if (!scope) 677255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ERR; 678255e72915d4cbddceb435e13d81601755714e9fSE Android if (scope->scope == SCOPE_DECL) { 679255e72915d4cbddceb435e13d81601755714e9fSE Android /* disallow declarations in modules */ 680255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 681255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Modules may not declare new categories.", 682255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name); 683255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ENOTSUP; 684255e72915d4cbddceb435e13d81601755714e9fSE Android } 685255e72915d4cbddceb435e13d81601755714e9fSE Android if (scope->scope == SCOPE_REQ) { 686255e72915d4cbddceb435e13d81601755714e9fSE Android /* unmet requirement */ 687255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 688255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Category %s not declared by base.", 689255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, id); 690255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ENOTSUP; 691255e72915d4cbddceb435e13d81601755714e9fSE Android } 692255e72915d4cbddceb435e13d81601755714e9fSE Android } 693255e72915d4cbddceb435e13d81601755714e9fSE Android 694255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur->map[SYM_CATS][cat->s.value - 1] = base_cat->s.value; 695255e72915d4cbddceb435e13d81601755714e9fSE Android 696255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 697255e72915d4cbddceb435e13d81601755714e9fSE Android} 698255e72915d4cbddceb435e13d81601755714e9fSE Android 699255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int (*copy_callback_f[SYM_NUM]) (hashtab_key_t key, 700255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, void *datap) = { 701255e72915d4cbddceb435e13d81601755714e9fSE AndroidNULL, class_copy_callback, role_copy_callback, type_copy_callback, 702255e72915d4cbddceb435e13d81601755714e9fSE Android user_copy_callback, bool_copy_callback, sens_copy_callback, 703255e72915d4cbddceb435e13d81601755714e9fSE Android cat_copy_callback}; 704255e72915d4cbddceb435e13d81601755714e9fSE Android 705255e72915d4cbddceb435e13d81601755714e9fSE Android/* 706255e72915d4cbddceb435e13d81601755714e9fSE Android * The boundaries have to be copied after the types/roles/users are copied, 707255e72915d4cbddceb435e13d81601755714e9fSE Android * because it refers hashtab to lookup destinated objects. 708255e72915d4cbddceb435e13d81601755714e9fSE Android */ 709255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_bounds_copy_callback(hashtab_key_t key, 710255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, void *data) 711255e72915d4cbddceb435e13d81601755714e9fSE Android{ 712255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 713255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type = (type_datum_t *) datum; 714255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *dest; 715255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t bounds_val; 716255e72915d4cbddceb435e13d81601755714e9fSE Android 717255e72915d4cbddceb435e13d81601755714e9fSE Android if (!type->bounds) 718255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 719255e72915d4cbddceb435e13d81601755714e9fSE Android 720255e72915d4cbddceb435e13d81601755714e9fSE Android bounds_val = state->cur->map[SYM_TYPES][type->bounds - 1]; 721255e72915d4cbddceb435e13d81601755714e9fSE Android 722255e72915d4cbddceb435e13d81601755714e9fSE Android dest = hashtab_search(state->base->p_types.table, key); 723255e72915d4cbddceb435e13d81601755714e9fSE Android if (!dest) { 724255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 725255e72915d4cbddceb435e13d81601755714e9fSE Android "Type lookup failed for %s", (char *)key); 726255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 727255e72915d4cbddceb435e13d81601755714e9fSE Android } 728255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest->bounds != 0 && dest->bounds != bounds_val) { 729255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 730255e72915d4cbddceb435e13d81601755714e9fSE Android "Inconsistent boundary for %s", (char *)key); 731255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 732255e72915d4cbddceb435e13d81601755714e9fSE Android } 733255e72915d4cbddceb435e13d81601755714e9fSE Android dest->bounds = bounds_val; 734255e72915d4cbddceb435e13d81601755714e9fSE Android 735255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 736255e72915d4cbddceb435e13d81601755714e9fSE Android} 737255e72915d4cbddceb435e13d81601755714e9fSE Android 738255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_bounds_copy_callback(hashtab_key_t key, 739255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, void *data) 740255e72915d4cbddceb435e13d81601755714e9fSE Android{ 741255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 742255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role = (role_datum_t *) datum; 743255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *dest; 744255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t bounds_val; 745255e72915d4cbddceb435e13d81601755714e9fSE Android 746255e72915d4cbddceb435e13d81601755714e9fSE Android if (!role->bounds) 747255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 748255e72915d4cbddceb435e13d81601755714e9fSE Android 749255e72915d4cbddceb435e13d81601755714e9fSE Android bounds_val = state->cur->map[SYM_ROLES][role->bounds - 1]; 750255e72915d4cbddceb435e13d81601755714e9fSE Android 751255e72915d4cbddceb435e13d81601755714e9fSE Android dest = hashtab_search(state->base->p_roles.table, key); 752255e72915d4cbddceb435e13d81601755714e9fSE Android if (!dest) { 753255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 754255e72915d4cbddceb435e13d81601755714e9fSE Android "Role lookup failed for %s", (char *)key); 755255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 756255e72915d4cbddceb435e13d81601755714e9fSE Android } 757255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest->bounds != 0 && dest->bounds != bounds_val) { 758255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 759255e72915d4cbddceb435e13d81601755714e9fSE Android "Inconsistent boundary for %s", (char *)key); 760255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 761255e72915d4cbddceb435e13d81601755714e9fSE Android } 762255e72915d4cbddceb435e13d81601755714e9fSE Android dest->bounds = bounds_val; 763255e72915d4cbddceb435e13d81601755714e9fSE Android 764255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 765255e72915d4cbddceb435e13d81601755714e9fSE Android} 766255e72915d4cbddceb435e13d81601755714e9fSE Android 767255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int user_bounds_copy_callback(hashtab_key_t key, 768255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, void *data) 769255e72915d4cbddceb435e13d81601755714e9fSE Android{ 770255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 771255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *user = (user_datum_t *) datum; 772255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *dest; 773255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t bounds_val; 774255e72915d4cbddceb435e13d81601755714e9fSE Android 775255e72915d4cbddceb435e13d81601755714e9fSE Android if (!user->bounds) 776255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 777255e72915d4cbddceb435e13d81601755714e9fSE Android 778255e72915d4cbddceb435e13d81601755714e9fSE Android bounds_val = state->cur->map[SYM_USERS][user->bounds - 1]; 779255e72915d4cbddceb435e13d81601755714e9fSE Android 780255e72915d4cbddceb435e13d81601755714e9fSE Android dest = hashtab_search(state->base->p_users.table, key); 781255e72915d4cbddceb435e13d81601755714e9fSE Android if (!dest) { 782255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 783255e72915d4cbddceb435e13d81601755714e9fSE Android "User lookup failed for %s", (char *)key); 784255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 785255e72915d4cbddceb435e13d81601755714e9fSE Android } 786255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest->bounds != 0 && dest->bounds != bounds_val) { 787255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 788255e72915d4cbddceb435e13d81601755714e9fSE Android "Inconsistent boundary for %s", (char *)key); 789255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 790255e72915d4cbddceb435e13d81601755714e9fSE Android } 791255e72915d4cbddceb435e13d81601755714e9fSE Android dest->bounds = bounds_val; 792255e72915d4cbddceb435e13d81601755714e9fSE Android 793255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 794255e72915d4cbddceb435e13d81601755714e9fSE Android} 795255e72915d4cbddceb435e13d81601755714e9fSE Android 796255e72915d4cbddceb435e13d81601755714e9fSE Android/* The aliases have to be copied after the types and attributes to be 797255e72915d4cbddceb435e13d81601755714e9fSE Android * certain that the base symbol table will have the type that the 798255e72915d4cbddceb435e13d81601755714e9fSE Android * alias refers. Otherwise, we won't be able to find the type value 799255e72915d4cbddceb435e13d81601755714e9fSE Android * for the alias. We can't depend on the declaration ordering because 800255e72915d4cbddceb435e13d81601755714e9fSE Android * of the hash table. 801255e72915d4cbddceb435e13d81601755714e9fSE Android */ 802255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 803255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 804255e72915d4cbddceb435e13d81601755714e9fSE Android{ 805255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key, *new_id = NULL, *target_id; 806255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type, *base_type, *new_type = NULL, *target_type; 807255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 808255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t *mod = state->cur; 809255e72915d4cbddceb435e13d81601755714e9fSE Android int primval; 810255e72915d4cbddceb435e13d81601755714e9fSE Android 811255e72915d4cbddceb435e13d81601755714e9fSE Android type = (type_datum_t *) datum; 812255e72915d4cbddceb435e13d81601755714e9fSE Android /* there are 2 kinds of aliases. Ones with their own value (TYPE_ALIAS) 813255e72915d4cbddceb435e13d81601755714e9fSE Android * and ones with the value of their primary (TYPE_TYPE && type->primary = 0) 814255e72915d4cbddceb435e13d81601755714e9fSE Android */ 815255e72915d4cbddceb435e13d81601755714e9fSE Android if (! 816255e72915d4cbddceb435e13d81601755714e9fSE Android (type->flavor == TYPE_ALIAS 817255e72915d4cbddceb435e13d81601755714e9fSE Android || (type->flavor == TYPE_TYPE && !type->primary))) { 818255e72915d4cbddceb435e13d81601755714e9fSE Android /* ignore types and attributes -- they were handled in 819255e72915d4cbddceb435e13d81601755714e9fSE Android * type_copy_callback() */ 820255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 821255e72915d4cbddceb435e13d81601755714e9fSE Android } 822255e72915d4cbddceb435e13d81601755714e9fSE Android 823255e72915d4cbddceb435e13d81601755714e9fSE Android if (type->flavor == TYPE_ALIAS) 824255e72915d4cbddceb435e13d81601755714e9fSE Android primval = type->primary; 825255e72915d4cbddceb435e13d81601755714e9fSE Android else 826255e72915d4cbddceb435e13d81601755714e9fSE Android primval = type->s.value; 827255e72915d4cbddceb435e13d81601755714e9fSE Android 828255e72915d4cbddceb435e13d81601755714e9fSE Android target_id = mod->policy->p_type_val_to_name[primval - 1]; 829255e72915d4cbddceb435e13d81601755714e9fSE Android target_type = hashtab_search(state->base->p_types.table, target_id); 830255e72915d4cbddceb435e13d81601755714e9fSE Android if (target_type == NULL) { 831255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "%s: Could not find type %s for alias %s.", 832255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, target_id, id); 833255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 834255e72915d4cbddceb435e13d81601755714e9fSE Android } 835255e72915d4cbddceb435e13d81601755714e9fSE Android 836255e72915d4cbddceb435e13d81601755714e9fSE Android if (!strcmp(id, target_id)) { 837255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "%s: Self aliasing of %s.", 838255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, id); 839255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 840255e72915d4cbddceb435e13d81601755714e9fSE Android } 841255e72915d4cbddceb435e13d81601755714e9fSE Android 842255e72915d4cbddceb435e13d81601755714e9fSE Android target_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); 843255e72915d4cbddceb435e13d81601755714e9fSE Android 844255e72915d4cbddceb435e13d81601755714e9fSE Android base_type = hashtab_search(state->base->p_types.table, id); 845255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_type == NULL) { 846255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 847255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying alias %s", id); 848255e72915d4cbddceb435e13d81601755714e9fSE Android 849255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_type = 850255e72915d4cbddceb435e13d81601755714e9fSE Android (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) { 851255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 852255e72915d4cbddceb435e13d81601755714e9fSE Android } 853255e72915d4cbddceb435e13d81601755714e9fSE Android /* the linked copy always has TYPE_ALIAS style aliases */ 854255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->primary = target_type->s.value; 855255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flags = target_type->flags; 856255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flavor = TYPE_ALIAS; 857255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->s.value = state->base->p_types.nprim + 1; 858255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 859255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 860255e72915d4cbddceb435e13d81601755714e9fSE Android } 861255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_insert 862255e72915d4cbddceb435e13d81601755714e9fSE Android (state->base->p_types.table, new_id, new_type)) { 863255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 864255e72915d4cbddceb435e13d81601755714e9fSE Android } 865255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->p_types.nprim++; 866255e72915d4cbddceb435e13d81601755714e9fSE Android base_type = new_type; 867255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 868255e72915d4cbddceb435e13d81601755714e9fSE Android 869255e72915d4cbddceb435e13d81601755714e9fSE Android /* if this already exists and isn't an alias it was required by another module (or base) 870255e72915d4cbddceb435e13d81601755714e9fSE Android * and inserted into the hashtable as a type, fix it up now */ 871255e72915d4cbddceb435e13d81601755714e9fSE Android 872255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_type->flavor == TYPE_ALIAS) { 873255e72915d4cbddceb435e13d81601755714e9fSE Android /* error checking */ 874255e72915d4cbddceb435e13d81601755714e9fSE Android assert(base_type->primary == target_type->s.value); 875255e72915d4cbddceb435e13d81601755714e9fSE Android assert(base_type->primary == 876255e72915d4cbddceb435e13d81601755714e9fSE Android mod->map[SYM_TYPES][primval - 1]); 877255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_TYPES][type->s.value - 1] == 878255e72915d4cbddceb435e13d81601755714e9fSE Android base_type->primary); 879255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 880255e72915d4cbddceb435e13d81601755714e9fSE Android } 881255e72915d4cbddceb435e13d81601755714e9fSE Android 882255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_type->flavor == TYPE_ATTRIB) { 883255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 884255e72915d4cbddceb435e13d81601755714e9fSE Android "%s is an alias of an attribute, not allowed", id); 885255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 886255e72915d4cbddceb435e13d81601755714e9fSE Android } 887255e72915d4cbddceb435e13d81601755714e9fSE Android 888255e72915d4cbddceb435e13d81601755714e9fSE Android base_type->flavor = TYPE_ALIAS; 889255e72915d4cbddceb435e13d81601755714e9fSE Android base_type->primary = target_type->s.value; 890255e72915d4cbddceb435e13d81601755714e9fSE Android base_type->flags |= (target_type->flags & TYPE_FLAGS_PERMISSIVE); 891255e72915d4cbddceb435e13d81601755714e9fSE Android 892255e72915d4cbddceb435e13d81601755714e9fSE Android } 893255e72915d4cbddceb435e13d81601755714e9fSE Android /* the aliases map points from its value to its primary so when this module 894255e72915d4cbddceb435e13d81601755714e9fSE Android * references this type the value it gets back from the map is the primary */ 895255e72915d4cbddceb435e13d81601755714e9fSE Android mod->map[SYM_TYPES][type->s.value - 1] = base_type->primary; 896255e72915d4cbddceb435e13d81601755714e9fSE Android 897255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 898255e72915d4cbddceb435e13d81601755714e9fSE Android 899255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 900255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 901255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 902255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_type); 903255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 904255e72915d4cbddceb435e13d81601755714e9fSE Android} 905255e72915d4cbddceb435e13d81601755714e9fSE Android 906255e72915d4cbddceb435e13d81601755714e9fSE Android/*********** callbacks that fix bitmaps ***********/ 907255e72915d4cbddceb435e13d81601755714e9fSE Android 908255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_set_convert(type_set_t * types, type_set_t * dst, 909255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * mod, link_state_t * state 910255e72915d4cbddceb435e13d81601755714e9fSE Android __attribute__ ((unused))) 911255e72915d4cbddceb435e13d81601755714e9fSE Android{ 912255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 913255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *tnode; 914255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&types->types, tnode, i) { 915255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(tnode, i)) { 916255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_TYPES][i]); 917255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 918255e72915d4cbddceb435e13d81601755714e9fSE Android (&dst->types, mod->map[SYM_TYPES][i] - 1, 1)) { 919255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 920255e72915d4cbddceb435e13d81601755714e9fSE Android } 921255e72915d4cbddceb435e13d81601755714e9fSE Android } 922255e72915d4cbddceb435e13d81601755714e9fSE Android } 923255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&types->negset, tnode, i) { 924255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(tnode, i)) { 925255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_TYPES][i]); 926255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 927255e72915d4cbddceb435e13d81601755714e9fSE Android (&dst->negset, mod->map[SYM_TYPES][i] - 1, 1)) { 928255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 929255e72915d4cbddceb435e13d81601755714e9fSE Android } 930255e72915d4cbddceb435e13d81601755714e9fSE Android } 931255e72915d4cbddceb435e13d81601755714e9fSE Android } 932255e72915d4cbddceb435e13d81601755714e9fSE Android dst->flags = types->flags; 933255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 934255e72915d4cbddceb435e13d81601755714e9fSE Android 935255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 936255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 937255e72915d4cbddceb435e13d81601755714e9fSE Android} 938255e72915d4cbddceb435e13d81601755714e9fSE Android 939255e72915d4cbddceb435e13d81601755714e9fSE Android/* OR 2 typemaps together and at the same time map the src types to 940255e72915d4cbddceb435e13d81601755714e9fSE Android * the correct values in the dst typeset. 941255e72915d4cbddceb435e13d81601755714e9fSE Android */ 942255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_set_or_convert(type_set_t * types, type_set_t * dst, 943255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * mod, link_state_t * state) 944255e72915d4cbddceb435e13d81601755714e9fSE Android{ 945255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_t ts_tmp; 946255e72915d4cbddceb435e13d81601755714e9fSE Android 947255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_init(&ts_tmp); 948255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_convert(types, &ts_tmp, mod, state) == -1) { 949255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 950255e72915d4cbddceb435e13d81601755714e9fSE Android } 951255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_or_eq(dst, &ts_tmp)) { 952255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 953255e72915d4cbddceb435e13d81601755714e9fSE Android } 954255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_destroy(&ts_tmp); 955255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 956255e72915d4cbddceb435e13d81601755714e9fSE Android 957255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 958255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 959255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_destroy(&ts_tmp); 960255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 961255e72915d4cbddceb435e13d81601755714e9fSE Android} 962255e72915d4cbddceb435e13d81601755714e9fSE Android 963255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_set_or_convert(role_set_t * roles, role_set_t * dst, 964255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * mod, link_state_t * state) 965255e72915d4cbddceb435e13d81601755714e9fSE Android{ 966255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 967255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t tmp; 968255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode; 969255e72915d4cbddceb435e13d81601755714e9fSE Android 970255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&tmp); 971255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&roles->roles, rnode, i) { 972255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, i)) { 973255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_ROLES][i]); 974255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 975255e72915d4cbddceb435e13d81601755714e9fSE Android (&tmp, mod->map[SYM_ROLES][i] - 1, 1)) { 976255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 977255e72915d4cbddceb435e13d81601755714e9fSE Android } 978255e72915d4cbddceb435e13d81601755714e9fSE Android } 979255e72915d4cbddceb435e13d81601755714e9fSE Android } 980255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&dst->roles, &tmp)) { 981255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 982255e72915d4cbddceb435e13d81601755714e9fSE Android } 983255e72915d4cbddceb435e13d81601755714e9fSE Android dst->flags |= roles->flags; 984255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp); 985255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 986255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 987255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 988255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp); 989255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 990255e72915d4cbddceb435e13d81601755714e9fSE Android} 991255e72915d4cbddceb435e13d81601755714e9fSE Android 992255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int mls_level_convert(mls_semantic_level_t * src, mls_semantic_level_t * dst, 993255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * mod, link_state_t * state) 994255e72915d4cbddceb435e13d81601755714e9fSE Android{ 995255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_cat_t *src_cat, *new_cat; 996255e72915d4cbddceb435e13d81601755714e9fSE Android 997255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mod->policy->mls) 998255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 999255e72915d4cbddceb435e13d81601755714e9fSE Android 1000255e72915d4cbddceb435e13d81601755714e9fSE Android /* Required not declared. */ 1001255e72915d4cbddceb435e13d81601755714e9fSE Android if (!src->sens) 1002255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1003255e72915d4cbddceb435e13d81601755714e9fSE Android 1004255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_LEVELS][src->sens - 1]); 1005255e72915d4cbddceb435e13d81601755714e9fSE Android dst->sens = mod->map[SYM_LEVELS][src->sens - 1]; 1006255e72915d4cbddceb435e13d81601755714e9fSE Android 1007255e72915d4cbddceb435e13d81601755714e9fSE Android for (src_cat = src->cat; src_cat; src_cat = src_cat->next) { 1008255e72915d4cbddceb435e13d81601755714e9fSE Android new_cat = 1009255e72915d4cbddceb435e13d81601755714e9fSE Android (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 1010255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_cat) { 1011255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory"); 1012255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1013255e72915d4cbddceb435e13d81601755714e9fSE Android } 1014255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_cat_init(new_cat); 1015255e72915d4cbddceb435e13d81601755714e9fSE Android 1016255e72915d4cbddceb435e13d81601755714e9fSE Android new_cat->next = dst->cat; 1017255e72915d4cbddceb435e13d81601755714e9fSE Android dst->cat = new_cat; 1018255e72915d4cbddceb435e13d81601755714e9fSE Android 1019255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_CATS][src_cat->low - 1]); 1020255e72915d4cbddceb435e13d81601755714e9fSE Android dst->cat->low = mod->map[SYM_CATS][src_cat->low - 1]; 1021255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_CATS][src_cat->high - 1]); 1022255e72915d4cbddceb435e13d81601755714e9fSE Android dst->cat->high = mod->map[SYM_CATS][src_cat->high - 1]; 1023255e72915d4cbddceb435e13d81601755714e9fSE Android } 1024255e72915d4cbddceb435e13d81601755714e9fSE Android 1025255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1026255e72915d4cbddceb435e13d81601755714e9fSE Android} 1027255e72915d4cbddceb435e13d81601755714e9fSE Android 1028255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int mls_range_convert(mls_semantic_range_t * src, mls_semantic_range_t * dst, 1029255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * mod, link_state_t * state) 1030255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1031255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 1032255e72915d4cbddceb435e13d81601755714e9fSE Android ret = mls_level_convert(&src->level[0], &dst->level[0], mod, state); 1033255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) 1034255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 1035255e72915d4cbddceb435e13d81601755714e9fSE Android ret = mls_level_convert(&src->level[1], &dst->level[1], mod, state); 1036255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) 1037255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 1038255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1039255e72915d4cbddceb435e13d81601755714e9fSE Android} 1040255e72915d4cbddceb435e13d81601755714e9fSE Android 1041255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 1042255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1043255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1044255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 1045255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key; 1046255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role, *dest_role = NULL; 1047255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 1048255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t e_tmp; 1049255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t *mod = state->cur; 1050255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode; 1051255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_t role_tab; 1052255e72915d4cbddceb435e13d81601755714e9fSE Android 1053255e72915d4cbddceb435e13d81601755714e9fSE Android role = (role_datum_t *) datum; 1054255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->dest_decl == NULL) 1055255e72915d4cbddceb435e13d81601755714e9fSE Android role_tab = state->base->p_roles.table; 1056255e72915d4cbddceb435e13d81601755714e9fSE Android else 1057255e72915d4cbddceb435e13d81601755714e9fSE Android role_tab = state->dest_decl->p_roles.table; 1058255e72915d4cbddceb435e13d81601755714e9fSE Android 1059255e72915d4cbddceb435e13d81601755714e9fSE Android dest_role = hashtab_search(role_tab, id); 1060255e72915d4cbddceb435e13d81601755714e9fSE Android assert(dest_role != NULL); 1061255e72915d4cbddceb435e13d81601755714e9fSE Android 1062255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) { 1063255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "fixing role %s", id); 1064255e72915d4cbddceb435e13d81601755714e9fSE Android } 1065255e72915d4cbddceb435e13d81601755714e9fSE Android 1066255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&e_tmp); 1067255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&role->dominates, rnode, i) { 1068255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, i)) { 1069255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_ROLES][i]); 1070255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 1071255e72915d4cbddceb435e13d81601755714e9fSE Android (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { 1072255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1073255e72915d4cbddceb435e13d81601755714e9fSE Android } 1074255e72915d4cbddceb435e13d81601755714e9fSE Android } 1075255e72915d4cbddceb435e13d81601755714e9fSE Android } 1076255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&dest_role->dominates, &e_tmp)) { 1077255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1078255e72915d4cbddceb435e13d81601755714e9fSE Android } 1079255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_or_convert(&role->types, &dest_role->types, mod, state)) { 1080255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1081255e72915d4cbddceb435e13d81601755714e9fSE Android } 1082255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&e_tmp); 1083255e72915d4cbddceb435e13d81601755714e9fSE Android 1084255e72915d4cbddceb435e13d81601755714e9fSE Android if (role->flavor == ROLE_ATTRIB) { 1085255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&e_tmp); 1086255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&role->roles, rnode, i) { 1087255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, i)) { 1088255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_ROLES][i]); 1089255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 1090255e72915d4cbddceb435e13d81601755714e9fSE Android (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { 1091255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1092255e72915d4cbddceb435e13d81601755714e9fSE Android } 1093255e72915d4cbddceb435e13d81601755714e9fSE Android } 1094255e72915d4cbddceb435e13d81601755714e9fSE Android } 1095255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&dest_role->roles, &e_tmp)) { 1096255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1097255e72915d4cbddceb435e13d81601755714e9fSE Android } 1098255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&e_tmp); 1099255e72915d4cbddceb435e13d81601755714e9fSE Android } 1100255e72915d4cbddceb435e13d81601755714e9fSE Android 1101255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1102255e72915d4cbddceb435e13d81601755714e9fSE Android 1103255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1104255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1105255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&e_tmp); 1106255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1107255e72915d4cbddceb435e13d81601755714e9fSE Android} 1108255e72915d4cbddceb435e13d81601755714e9fSE Android 1109255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 1110255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1111255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1112255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 1113255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key; 1114255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type, *new_type = NULL; 1115255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 1116255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t e_tmp; 1117255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t *mod = state->cur; 1118255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *tnode; 1119255e72915d4cbddceb435e13d81601755714e9fSE Android symtab_t *typetab; 1120255e72915d4cbddceb435e13d81601755714e9fSE Android 1121255e72915d4cbddceb435e13d81601755714e9fSE Android type = (type_datum_t *) datum; 1122255e72915d4cbddceb435e13d81601755714e9fSE Android 1123255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->dest_decl == NULL) 1124255e72915d4cbddceb435e13d81601755714e9fSE Android typetab = &state->base->p_types; 1125255e72915d4cbddceb435e13d81601755714e9fSE Android else 1126255e72915d4cbddceb435e13d81601755714e9fSE Android typetab = &state->dest_decl->p_types; 1127255e72915d4cbddceb435e13d81601755714e9fSE Android 1128255e72915d4cbddceb435e13d81601755714e9fSE Android /* only fix attributes */ 1129255e72915d4cbddceb435e13d81601755714e9fSE Android if (type->flavor != TYPE_ATTRIB) { 1130255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1131255e72915d4cbddceb435e13d81601755714e9fSE Android } 1132255e72915d4cbddceb435e13d81601755714e9fSE Android 1133255e72915d4cbddceb435e13d81601755714e9fSE Android new_type = hashtab_search(typetab->table, id); 1134255e72915d4cbddceb435e13d81601755714e9fSE Android assert(new_type != NULL && new_type->flavor == TYPE_ATTRIB); 1135255e72915d4cbddceb435e13d81601755714e9fSE Android 1136255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) { 1137255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "fixing attribute %s", id); 1138255e72915d4cbddceb435e13d81601755714e9fSE Android } 1139255e72915d4cbddceb435e13d81601755714e9fSE Android 1140255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&e_tmp); 1141255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&type->types, tnode, i) { 1142255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(tnode, i)) { 1143255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_TYPES][i]); 1144255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 1145255e72915d4cbddceb435e13d81601755714e9fSE Android (&e_tmp, mod->map[SYM_TYPES][i] - 1, 1)) { 1146255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1147255e72915d4cbddceb435e13d81601755714e9fSE Android } 1148255e72915d4cbddceb435e13d81601755714e9fSE Android } 1149255e72915d4cbddceb435e13d81601755714e9fSE Android } 1150255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&new_type->types, &e_tmp)) { 1151255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1152255e72915d4cbddceb435e13d81601755714e9fSE Android } 1153255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&e_tmp); 1154255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1155255e72915d4cbddceb435e13d81601755714e9fSE Android 1156255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1157255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1158255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&e_tmp); 1159255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1160255e72915d4cbddceb435e13d81601755714e9fSE Android} 1161255e72915d4cbddceb435e13d81601755714e9fSE Android 1162255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int user_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 1163255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1164255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1165255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key; 1166255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *user, *new_user = NULL; 1167255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 1168255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t *mod = state->cur; 1169255e72915d4cbddceb435e13d81601755714e9fSE Android symtab_t *usertab; 1170255e72915d4cbddceb435e13d81601755714e9fSE Android 1171255e72915d4cbddceb435e13d81601755714e9fSE Android user = (user_datum_t *) datum; 1172255e72915d4cbddceb435e13d81601755714e9fSE Android 1173255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->dest_decl == NULL) 1174255e72915d4cbddceb435e13d81601755714e9fSE Android usertab = &state->base->p_users; 1175255e72915d4cbddceb435e13d81601755714e9fSE Android else 1176255e72915d4cbddceb435e13d81601755714e9fSE Android usertab = &state->dest_decl->p_users; 1177255e72915d4cbddceb435e13d81601755714e9fSE Android 1178255e72915d4cbddceb435e13d81601755714e9fSE Android new_user = hashtab_search(usertab->table, id); 1179255e72915d4cbddceb435e13d81601755714e9fSE Android assert(new_user != NULL); 1180255e72915d4cbddceb435e13d81601755714e9fSE Android 1181255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) { 1182255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "fixing user %s", id); 1183255e72915d4cbddceb435e13d81601755714e9fSE Android } 1184255e72915d4cbddceb435e13d81601755714e9fSE Android 1185255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_or_convert(&user->roles, &new_user->roles, mod, state)) { 1186255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1187255e72915d4cbddceb435e13d81601755714e9fSE Android } 1188255e72915d4cbddceb435e13d81601755714e9fSE Android 1189255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_range_convert(&user->range, &new_user->range, mod, state)) 1190255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1191255e72915d4cbddceb435e13d81601755714e9fSE Android 1192255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_convert(&user->dfltlevel, &new_user->dfltlevel, mod, state)) 1193255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1194255e72915d4cbddceb435e13d81601755714e9fSE Android 1195255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1196255e72915d4cbddceb435e13d81601755714e9fSE Android 1197255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1198255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1199255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1200255e72915d4cbddceb435e13d81601755714e9fSE Android} 1201255e72915d4cbddceb435e13d81601755714e9fSE Android 1202255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int (*fix_callback_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 1203255e72915d4cbddceb435e13d81601755714e9fSE Android void *datap) = { 1204255e72915d4cbddceb435e13d81601755714e9fSE AndroidNULL, NULL, role_fix_callback, type_fix_callback, user_fix_callback, 1205255e72915d4cbddceb435e13d81601755714e9fSE Android NULL, NULL, NULL}; 1206255e72915d4cbddceb435e13d81601755714e9fSE Android 1207255e72915d4cbddceb435e13d81601755714e9fSE Android/*********** functions that copy AV rules ***********/ 1208255e72915d4cbddceb435e13d81601755714e9fSE Android 1209255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_avrule_list(avrule_t * list, avrule_t ** dst, 1210255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * module, link_state_t * state) 1211255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1212255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 1213255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t *cur, *new_rule = NULL, *tail; 1214255e72915d4cbddceb435e13d81601755714e9fSE Android class_perm_node_t *cur_perm, *new_perm, *tail_perm = NULL; 1215255e72915d4cbddceb435e13d81601755714e9fSE Android 1216255e72915d4cbddceb435e13d81601755714e9fSE Android tail = *dst; 1217255e72915d4cbddceb435e13d81601755714e9fSE Android while (tail && tail->next) { 1218255e72915d4cbddceb435e13d81601755714e9fSE Android tail = tail->next; 1219255e72915d4cbddceb435e13d81601755714e9fSE Android } 1220255e72915d4cbddceb435e13d81601755714e9fSE Android 1221255e72915d4cbddceb435e13d81601755714e9fSE Android cur = list; 1222255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1223255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_rule = (avrule_t *) malloc(sizeof(avrule_t))) == NULL) { 1224255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1225255e72915d4cbddceb435e13d81601755714e9fSE Android } 1226255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_init(new_rule); 1227255e72915d4cbddceb435e13d81601755714e9fSE Android 1228255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->specified = cur->specified; 1229255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->flags = cur->flags; 1230255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_convert 1231255e72915d4cbddceb435e13d81601755714e9fSE Android (&cur->stypes, &new_rule->stypes, module, state) == -1 1232255e72915d4cbddceb435e13d81601755714e9fSE Android || type_set_convert(&cur->ttypes, &new_rule->ttypes, module, 1233255e72915d4cbddceb435e13d81601755714e9fSE Android state) == -1) { 1234255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1235255e72915d4cbddceb435e13d81601755714e9fSE Android } 1236255e72915d4cbddceb435e13d81601755714e9fSE Android 1237255e72915d4cbddceb435e13d81601755714e9fSE Android cur_perm = cur->perms; 1238255e72915d4cbddceb435e13d81601755714e9fSE Android tail_perm = NULL; 1239255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur_perm) { 1240255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_perm = (class_perm_node_t *) 1241255e72915d4cbddceb435e13d81601755714e9fSE Android malloc(sizeof(class_perm_node_t))) == NULL) { 1242255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1243255e72915d4cbddceb435e13d81601755714e9fSE Android } 1244255e72915d4cbddceb435e13d81601755714e9fSE Android class_perm_node_init(new_perm); 1245255e72915d4cbddceb435e13d81601755714e9fSE Android 1246255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm->class = 1247255e72915d4cbddceb435e13d81601755714e9fSE Android module->map[SYM_CLASSES][cur_perm->class - 1]; 1248255e72915d4cbddceb435e13d81601755714e9fSE Android assert(new_perm->class); 1249255e72915d4cbddceb435e13d81601755714e9fSE Android 1250255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_rule->specified & AVRULE_AV) { 1251255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; 1252255e72915d4cbddceb435e13d81601755714e9fSE Android i < 1253255e72915d4cbddceb435e13d81601755714e9fSE Android module->perm_map_len[cur_perm->class - 1]; 1254255e72915d4cbddceb435e13d81601755714e9fSE Android i++) { 1255255e72915d4cbddceb435e13d81601755714e9fSE Android if (!(cur_perm->data & (1U << i))) 1256255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1257255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm->data |= 1258255e72915d4cbddceb435e13d81601755714e9fSE Android (1U << 1259255e72915d4cbddceb435e13d81601755714e9fSE Android (module-> 1260255e72915d4cbddceb435e13d81601755714e9fSE Android perm_map[cur_perm->class - 1][i] - 1261255e72915d4cbddceb435e13d81601755714e9fSE Android 1)); 1262255e72915d4cbddceb435e13d81601755714e9fSE Android } 1263255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1264255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm->data = 1265255e72915d4cbddceb435e13d81601755714e9fSE Android module->map[SYM_TYPES][cur_perm->data - 1]; 1266255e72915d4cbddceb435e13d81601755714e9fSE Android } 1267255e72915d4cbddceb435e13d81601755714e9fSE Android 1268255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_rule->perms == NULL) { 1269255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->perms = new_perm; 1270255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1271255e72915d4cbddceb435e13d81601755714e9fSE Android tail_perm->next = new_perm; 1272255e72915d4cbddceb435e13d81601755714e9fSE Android } 1273255e72915d4cbddceb435e13d81601755714e9fSE Android tail_perm = new_perm; 1274255e72915d4cbddceb435e13d81601755714e9fSE Android cur_perm = cur_perm->next; 1275255e72915d4cbddceb435e13d81601755714e9fSE Android } 1276255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->line = cur->line; 1277255e72915d4cbddceb435e13d81601755714e9fSE Android 1278255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1279255e72915d4cbddceb435e13d81601755714e9fSE Android 1280255e72915d4cbddceb435e13d81601755714e9fSE Android if (*dst == NULL) { 1281255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = new_rule; 1282255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1283255e72915d4cbddceb435e13d81601755714e9fSE Android tail->next = new_rule; 1284255e72915d4cbddceb435e13d81601755714e9fSE Android } 1285255e72915d4cbddceb435e13d81601755714e9fSE Android tail = new_rule; 1286255e72915d4cbddceb435e13d81601755714e9fSE Android } 1287255e72915d4cbddceb435e13d81601755714e9fSE Android 1288255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1289255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1290255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1291255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_destroy(new_rule); 1292255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_rule); 1293255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1294255e72915d4cbddceb435e13d81601755714e9fSE Android} 1295255e72915d4cbddceb435e13d81601755714e9fSE Android 1296255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_role_trans_list(role_trans_rule_t * list, 1297255e72915d4cbddceb435e13d81601755714e9fSE Android role_trans_rule_t ** dst, 1298255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * module, link_state_t * state) 1299255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1300255e72915d4cbddceb435e13d81601755714e9fSE Android role_trans_rule_t *cur, *new_rule = NULL, *tail; 1301255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 1302255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *cnode; 1303255e72915d4cbddceb435e13d81601755714e9fSE Android 1304255e72915d4cbddceb435e13d81601755714e9fSE Android cur = list; 1305255e72915d4cbddceb435e13d81601755714e9fSE Android tail = *dst; 1306255e72915d4cbddceb435e13d81601755714e9fSE Android while (tail && tail->next) { 1307255e72915d4cbddceb435e13d81601755714e9fSE Android tail = tail->next; 1308255e72915d4cbddceb435e13d81601755714e9fSE Android } 1309255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1310255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_rule = 1311255e72915d4cbddceb435e13d81601755714e9fSE Android (role_trans_rule_t *) malloc(sizeof(role_trans_rule_t))) == 1312255e72915d4cbddceb435e13d81601755714e9fSE Android NULL) { 1313255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1314255e72915d4cbddceb435e13d81601755714e9fSE Android } 1315255e72915d4cbddceb435e13d81601755714e9fSE Android role_trans_rule_init(new_rule); 1316255e72915d4cbddceb435e13d81601755714e9fSE Android 1317255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_or_convert 1318255e72915d4cbddceb435e13d81601755714e9fSE Android (&cur->roles, &new_rule->roles, module, state) 1319255e72915d4cbddceb435e13d81601755714e9fSE Android || type_set_or_convert(&cur->types, &new_rule->types, 1320255e72915d4cbddceb435e13d81601755714e9fSE Android module, state)) { 1321255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1322255e72915d4cbddceb435e13d81601755714e9fSE Android } 1323255e72915d4cbddceb435e13d81601755714e9fSE Android 1324255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&cur->classes, cnode, i) { 1325255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(cnode, i)) { 1326255e72915d4cbddceb435e13d81601755714e9fSE Android assert(module->map[SYM_CLASSES][i]); 1327255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&new_rule->classes, 1328255e72915d4cbddceb435e13d81601755714e9fSE Android module-> 1329255e72915d4cbddceb435e13d81601755714e9fSE Android map[SYM_CLASSES][i] - 1, 1330255e72915d4cbddceb435e13d81601755714e9fSE Android 1)) { 1331255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1332255e72915d4cbddceb435e13d81601755714e9fSE Android } 1333255e72915d4cbddceb435e13d81601755714e9fSE Android } 1334255e72915d4cbddceb435e13d81601755714e9fSE Android } 1335255e72915d4cbddceb435e13d81601755714e9fSE Android 1336255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->new_role = module->map[SYM_ROLES][cur->new_role - 1]; 1337255e72915d4cbddceb435e13d81601755714e9fSE Android 1338255e72915d4cbddceb435e13d81601755714e9fSE Android if (*dst == NULL) { 1339255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = new_rule; 1340255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1341255e72915d4cbddceb435e13d81601755714e9fSE Android tail->next = new_rule; 1342255e72915d4cbddceb435e13d81601755714e9fSE Android } 1343255e72915d4cbddceb435e13d81601755714e9fSE Android tail = new_rule; 1344255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1345255e72915d4cbddceb435e13d81601755714e9fSE Android } 1346255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1347255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1348255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1349255e72915d4cbddceb435e13d81601755714e9fSE Android role_trans_rule_list_destroy(new_rule); 1350255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1351255e72915d4cbddceb435e13d81601755714e9fSE Android} 1352255e72915d4cbddceb435e13d81601755714e9fSE Android 1353255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_role_allow_list(role_allow_rule_t * list, 1354255e72915d4cbddceb435e13d81601755714e9fSE Android role_allow_rule_t ** dst, 1355255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * module, link_state_t * state) 1356255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1357255e72915d4cbddceb435e13d81601755714e9fSE Android role_allow_rule_t *cur, *new_rule = NULL, *tail; 1358255e72915d4cbddceb435e13d81601755714e9fSE Android 1359255e72915d4cbddceb435e13d81601755714e9fSE Android cur = list; 1360255e72915d4cbddceb435e13d81601755714e9fSE Android tail = *dst; 1361255e72915d4cbddceb435e13d81601755714e9fSE Android while (tail && tail->next) { 1362255e72915d4cbddceb435e13d81601755714e9fSE Android tail = tail->next; 1363255e72915d4cbddceb435e13d81601755714e9fSE Android } 1364255e72915d4cbddceb435e13d81601755714e9fSE Android 1365255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1366255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_rule = 1367255e72915d4cbddceb435e13d81601755714e9fSE Android (role_allow_rule_t *) malloc(sizeof(role_allow_rule_t))) == 1368255e72915d4cbddceb435e13d81601755714e9fSE Android NULL) { 1369255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1370255e72915d4cbddceb435e13d81601755714e9fSE Android } 1371255e72915d4cbddceb435e13d81601755714e9fSE Android role_allow_rule_init(new_rule); 1372255e72915d4cbddceb435e13d81601755714e9fSE Android 1373255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_or_convert 1374255e72915d4cbddceb435e13d81601755714e9fSE Android (&cur->roles, &new_rule->roles, module, state) 1375255e72915d4cbddceb435e13d81601755714e9fSE Android || role_set_or_convert(&cur->new_roles, 1376255e72915d4cbddceb435e13d81601755714e9fSE Android &new_rule->new_roles, module, 1377255e72915d4cbddceb435e13d81601755714e9fSE Android state)) { 1378255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1379255e72915d4cbddceb435e13d81601755714e9fSE Android } 1380255e72915d4cbddceb435e13d81601755714e9fSE Android if (*dst == NULL) { 1381255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = new_rule; 1382255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1383255e72915d4cbddceb435e13d81601755714e9fSE Android tail->next = new_rule; 1384255e72915d4cbddceb435e13d81601755714e9fSE Android } 1385255e72915d4cbddceb435e13d81601755714e9fSE Android tail = new_rule; 1386255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1387255e72915d4cbddceb435e13d81601755714e9fSE Android } 1388255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1389255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1390255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1391255e72915d4cbddceb435e13d81601755714e9fSE Android role_allow_rule_list_destroy(new_rule); 1392255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1393255e72915d4cbddceb435e13d81601755714e9fSE Android} 1394255e72915d4cbddceb435e13d81601755714e9fSE Android 1395255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_filename_trans_list(filename_trans_rule_t * list, 1396255e72915d4cbddceb435e13d81601755714e9fSE Android filename_trans_rule_t ** dst, 1397255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * module, 1398255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t * state) 1399255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1400255e72915d4cbddceb435e13d81601755714e9fSE Android filename_trans_rule_t *cur, *new_rule, *tail; 1401255e72915d4cbddceb435e13d81601755714e9fSE Android 1402255e72915d4cbddceb435e13d81601755714e9fSE Android cur = list; 1403255e72915d4cbddceb435e13d81601755714e9fSE Android tail = *dst; 1404255e72915d4cbddceb435e13d81601755714e9fSE Android while (tail && tail->next) 1405255e72915d4cbddceb435e13d81601755714e9fSE Android tail = tail->next; 1406255e72915d4cbddceb435e13d81601755714e9fSE Android 1407255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1408255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule = malloc(sizeof(*new_rule)); 1409255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_rule) 1410255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 1411255e72915d4cbddceb435e13d81601755714e9fSE Android 1412255e72915d4cbddceb435e13d81601755714e9fSE Android filename_trans_rule_init(new_rule); 1413255e72915d4cbddceb435e13d81601755714e9fSE Android 1414255e72915d4cbddceb435e13d81601755714e9fSE Android if (*dst == NULL) 1415255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = new_rule; 1416255e72915d4cbddceb435e13d81601755714e9fSE Android else 1417255e72915d4cbddceb435e13d81601755714e9fSE Android tail->next = new_rule; 1418255e72915d4cbddceb435e13d81601755714e9fSE Android tail = new_rule; 1419255e72915d4cbddceb435e13d81601755714e9fSE Android 1420255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->name = strdup(cur->name); 1421255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_rule->name) 1422255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 1423255e72915d4cbddceb435e13d81601755714e9fSE Android 1424255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module, state) || 1425255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module, state)) 1426255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 1427255e72915d4cbddceb435e13d81601755714e9fSE Android 1428255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->tclass = module->map[SYM_CLASSES][cur->tclass - 1]; 1429255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->otype = module->map[SYM_TYPES][cur->otype - 1]; 1430255e72915d4cbddceb435e13d81601755714e9fSE Android 1431255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1432255e72915d4cbddceb435e13d81601755714e9fSE Android } 1433255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1434255e72915d4cbddceb435e13d81601755714e9fSE Androiderr: 1435255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1436255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1437255e72915d4cbddceb435e13d81601755714e9fSE Android} 1438255e72915d4cbddceb435e13d81601755714e9fSE Android 1439255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_range_trans_list(range_trans_rule_t * rules, 1440255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_rule_t ** dst, 1441255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * mod, link_state_t * state) 1442255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1443255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_rule_t *rule, *new_rule = NULL; 1444255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 1445255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *cnode; 1446255e72915d4cbddceb435e13d81601755714e9fSE Android 1447255e72915d4cbddceb435e13d81601755714e9fSE Android for (rule = rules; rule; rule = rule->next) { 1448255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule = 1449255e72915d4cbddceb435e13d81601755714e9fSE Android (range_trans_rule_t *) malloc(sizeof(range_trans_rule_t)); 1450255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_rule) 1451255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1452255e72915d4cbddceb435e13d81601755714e9fSE Android 1453255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_rule_init(new_rule); 1454255e72915d4cbddceb435e13d81601755714e9fSE Android 1455255e72915d4cbddceb435e13d81601755714e9fSE Android new_rule->next = *dst; 1456255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = new_rule; 1457255e72915d4cbddceb435e13d81601755714e9fSE Android 1458255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_convert(&rule->stypes, &new_rule->stypes, 1459255e72915d4cbddceb435e13d81601755714e9fSE Android mod, state)) 1460255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1461255e72915d4cbddceb435e13d81601755714e9fSE Android 1462255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_convert(&rule->ttypes, &new_rule->ttypes, 1463255e72915d4cbddceb435e13d81601755714e9fSE Android mod, state)) 1464255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1465255e72915d4cbddceb435e13d81601755714e9fSE Android 1466255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&rule->tclasses, cnode, i) { 1467255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(cnode, i)) { 1468255e72915d4cbddceb435e13d81601755714e9fSE Android assert(mod->map[SYM_CLASSES][i]); 1469255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 1470255e72915d4cbddceb435e13d81601755714e9fSE Android (&new_rule->tclasses, 1471255e72915d4cbddceb435e13d81601755714e9fSE Android mod->map[SYM_CLASSES][i] - 1, 1)) { 1472255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1473255e72915d4cbddceb435e13d81601755714e9fSE Android } 1474255e72915d4cbddceb435e13d81601755714e9fSE Android } 1475255e72915d4cbddceb435e13d81601755714e9fSE Android } 1476255e72915d4cbddceb435e13d81601755714e9fSE Android 1477255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_range_convert(&rule->trange, &new_rule->trange, mod, state)) 1478255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1479255e72915d4cbddceb435e13d81601755714e9fSE Android } 1480255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1481255e72915d4cbddceb435e13d81601755714e9fSE Android 1482255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1483255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1484255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_rule_list_destroy(new_rule); 1485255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1486255e72915d4cbddceb435e13d81601755714e9fSE Android} 1487255e72915d4cbddceb435e13d81601755714e9fSE Android 1488255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_cond_list(cond_node_t * list, cond_node_t ** dst, 1489255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * module, link_state_t * state) 1490255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1491255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned i; 1492255e72915d4cbddceb435e13d81601755714e9fSE Android cond_node_t *cur, *new_node = NULL, *tail; 1493255e72915d4cbddceb435e13d81601755714e9fSE Android cond_expr_t *cur_expr; 1494255e72915d4cbddceb435e13d81601755714e9fSE Android tail = *dst; 1495255e72915d4cbddceb435e13d81601755714e9fSE Android while (tail && tail->next) 1496255e72915d4cbddceb435e13d81601755714e9fSE Android tail = tail->next; 1497255e72915d4cbddceb435e13d81601755714e9fSE Android 1498255e72915d4cbddceb435e13d81601755714e9fSE Android cur = list; 1499255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1500255e72915d4cbddceb435e13d81601755714e9fSE Android new_node = (cond_node_t *) malloc(sizeof(cond_node_t)); 1501255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_node) { 1502255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1503255e72915d4cbddceb435e13d81601755714e9fSE Android } 1504255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_node, 0, sizeof(cond_node_t)); 1505255e72915d4cbddceb435e13d81601755714e9fSE Android 1506255e72915d4cbddceb435e13d81601755714e9fSE Android new_node->cur_state = cur->cur_state; 1507255e72915d4cbddceb435e13d81601755714e9fSE Android new_node->expr = cond_copy_expr(cur->expr); 1508255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_node->expr) 1509255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1510255e72915d4cbddceb435e13d81601755714e9fSE Android /* go back through and remap the expression */ 1511255e72915d4cbddceb435e13d81601755714e9fSE Android for (cur_expr = new_node->expr; cur_expr != NULL; 1512255e72915d4cbddceb435e13d81601755714e9fSE Android cur_expr = cur_expr->next) { 1513255e72915d4cbddceb435e13d81601755714e9fSE Android /* expression nodes don't have a bool value of 0 - don't map them */ 1514255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur_expr->expr_type != COND_BOOL) 1515255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1516255e72915d4cbddceb435e13d81601755714e9fSE Android assert(module->map[SYM_BOOLS][cur_expr->bool - 1] != 0); 1517255e72915d4cbddceb435e13d81601755714e9fSE Android cur_expr->bool = 1518255e72915d4cbddceb435e13d81601755714e9fSE Android module->map[SYM_BOOLS][cur_expr->bool - 1]; 1519255e72915d4cbddceb435e13d81601755714e9fSE Android } 1520255e72915d4cbddceb435e13d81601755714e9fSE Android new_node->nbools = cur->nbools; 1521255e72915d4cbddceb435e13d81601755714e9fSE Android /* FIXME should COND_MAX_BOOLS be used here? */ 1522255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < min(cur->nbools, COND_MAX_BOOLS); i++) { 1523255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t remapped_id = 1524255e72915d4cbddceb435e13d81601755714e9fSE Android module->map[SYM_BOOLS][cur->bool_ids[i] - 1]; 1525255e72915d4cbddceb435e13d81601755714e9fSE Android assert(remapped_id != 0); 1526255e72915d4cbddceb435e13d81601755714e9fSE Android new_node->bool_ids[i] = remapped_id; 1527255e72915d4cbddceb435e13d81601755714e9fSE Android } 1528255e72915d4cbddceb435e13d81601755714e9fSE Android new_node->expr_pre_comp = cur->expr_pre_comp; 1529255e72915d4cbddceb435e13d81601755714e9fSE Android 1530255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_avrule_list 1531255e72915d4cbddceb435e13d81601755714e9fSE Android (cur->avtrue_list, &new_node->avtrue_list, module, state) 1532255e72915d4cbddceb435e13d81601755714e9fSE Android || copy_avrule_list(cur->avfalse_list, 1533255e72915d4cbddceb435e13d81601755714e9fSE Android &new_node->avfalse_list, module, 1534255e72915d4cbddceb435e13d81601755714e9fSE Android state)) { 1535255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1536255e72915d4cbddceb435e13d81601755714e9fSE Android } 1537255e72915d4cbddceb435e13d81601755714e9fSE Android 1538255e72915d4cbddceb435e13d81601755714e9fSE Android if (*dst == NULL) { 1539255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = new_node; 1540255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1541255e72915d4cbddceb435e13d81601755714e9fSE Android tail->next = new_node; 1542255e72915d4cbddceb435e13d81601755714e9fSE Android } 1543255e72915d4cbddceb435e13d81601755714e9fSE Android tail = new_node; 1544255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1545255e72915d4cbddceb435e13d81601755714e9fSE Android } 1546255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1547255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1548255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1549255e72915d4cbddceb435e13d81601755714e9fSE Android cond_node_destroy(new_node); 1550255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_node); 1551255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1552255e72915d4cbddceb435e13d81601755714e9fSE Android 1553255e72915d4cbddceb435e13d81601755714e9fSE Android} 1554255e72915d4cbddceb435e13d81601755714e9fSE Android 1555255e72915d4cbddceb435e13d81601755714e9fSE Android/*********** functions that copy avrule_decls from module to base ***********/ 1556255e72915d4cbddceb435e13d81601755714e9fSE Android 1557255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_identifiers(link_state_t * state, symtab_t * src_symtab, 1558255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t * dest_decl) 1559255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1560255e72915d4cbddceb435e13d81601755714e9fSE Android int i, ret; 1561255e72915d4cbddceb435e13d81601755714e9fSE Android 1562255e72915d4cbddceb435e13d81601755714e9fSE Android state->dest_decl = dest_decl; 1563255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < SYM_NUM; i++) { 1564255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_callback_f[i] != NULL) { 1565255e72915d4cbddceb435e13d81601755714e9fSE Android ret = 1566255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(src_symtab[i].table, copy_callback_f[i], 1567255e72915d4cbddceb435e13d81601755714e9fSE Android state); 1568255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 1569255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 1570255e72915d4cbddceb435e13d81601755714e9fSE Android } 1571255e72915d4cbddceb435e13d81601755714e9fSE Android } 1572255e72915d4cbddceb435e13d81601755714e9fSE Android } 1573255e72915d4cbddceb435e13d81601755714e9fSE Android 1574255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(src_symtab[SYM_TYPES].table, 1575255e72915d4cbddceb435e13d81601755714e9fSE Android type_bounds_copy_callback, state)) 1576255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1577255e72915d4cbddceb435e13d81601755714e9fSE Android 1578255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(src_symtab[SYM_TYPES].table, 1579255e72915d4cbddceb435e13d81601755714e9fSE Android alias_copy_callback, state)) 1580255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1581255e72915d4cbddceb435e13d81601755714e9fSE Android 1582255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(src_symtab[SYM_ROLES].table, 1583255e72915d4cbddceb435e13d81601755714e9fSE Android role_bounds_copy_callback, state)) 1584255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1585255e72915d4cbddceb435e13d81601755714e9fSE Android 1586255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(src_symtab[SYM_USERS].table, 1587255e72915d4cbddceb435e13d81601755714e9fSE Android user_bounds_copy_callback, state)) 1588255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1589255e72915d4cbddceb435e13d81601755714e9fSE Android 1590255e72915d4cbddceb435e13d81601755714e9fSE Android /* then fix bitmaps associated with those newly copied identifiers */ 1591255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < SYM_NUM; i++) { 1592255e72915d4cbddceb435e13d81601755714e9fSE Android if (fix_callback_f[i] != NULL && 1593255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(src_symtab[i].table, fix_callback_f[i], 1594255e72915d4cbddceb435e13d81601755714e9fSE Android state)) { 1595255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1596255e72915d4cbddceb435e13d81601755714e9fSE Android } 1597255e72915d4cbddceb435e13d81601755714e9fSE Android } 1598255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1599255e72915d4cbddceb435e13d81601755714e9fSE Android} 1600255e72915d4cbddceb435e13d81601755714e9fSE Android 1601255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_scope_index(scope_index_t * src, scope_index_t * dest, 1602255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t * module, link_state_t * state) 1603255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1604255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 1605255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t largest_mapped_class_value = 0; 1606255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *node; 1607255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy the scoping information for this avrule decl block */ 1608255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < SYM_NUM; i++) { 1609255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *srcmap = src->scope + i; 1610255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *destmap = dest->scope + i; 1611255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_callback_f[i] == NULL) { 1612255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1613255e72915d4cbddceb435e13d81601755714e9fSE Android } 1614255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(srcmap, node, j) { 1615255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(node, j)) { 1616255e72915d4cbddceb435e13d81601755714e9fSE Android assert(module->map[i][j] != 0); 1617255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit 1618255e72915d4cbddceb435e13d81601755714e9fSE Android (destmap, module->map[i][j] - 1, 1) != 0) { 1619255e72915d4cbddceb435e13d81601755714e9fSE Android 1620255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1621255e72915d4cbddceb435e13d81601755714e9fSE Android } 1622255e72915d4cbddceb435e13d81601755714e9fSE Android if (i == SYM_CLASSES && 1623255e72915d4cbddceb435e13d81601755714e9fSE Android largest_mapped_class_value < 1624255e72915d4cbddceb435e13d81601755714e9fSE Android module->map[SYM_CLASSES][j]) { 1625255e72915d4cbddceb435e13d81601755714e9fSE Android largest_mapped_class_value = 1626255e72915d4cbddceb435e13d81601755714e9fSE Android module->map[SYM_CLASSES][j]; 1627255e72915d4cbddceb435e13d81601755714e9fSE Android } 1628255e72915d4cbddceb435e13d81601755714e9fSE Android } 1629255e72915d4cbddceb435e13d81601755714e9fSE Android } 1630255e72915d4cbddceb435e13d81601755714e9fSE Android } 1631255e72915d4cbddceb435e13d81601755714e9fSE Android 1632255e72915d4cbddceb435e13d81601755714e9fSE Android /* next copy the enabled permissions data */ 1633255e72915d4cbddceb435e13d81601755714e9fSE Android if ((dest->class_perms_map = malloc(largest_mapped_class_value * 1634255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(*dest->class_perms_map))) == 1635255e72915d4cbddceb435e13d81601755714e9fSE Android NULL) { 1636255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1637255e72915d4cbddceb435e13d81601755714e9fSE Android } 1638255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < largest_mapped_class_value; i++) { 1639255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(dest->class_perms_map + i); 1640255e72915d4cbddceb435e13d81601755714e9fSE Android } 1641255e72915d4cbddceb435e13d81601755714e9fSE Android dest->class_perms_len = largest_mapped_class_value; 1642255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < src->class_perms_len; i++) { 1643255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *srcmap = src->class_perms_map + i; 1644255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *destmap = 1645255e72915d4cbddceb435e13d81601755714e9fSE Android dest->class_perms_map + module->map[SYM_CLASSES][i] - 1; 1646255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(srcmap, node, j) { 1647255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(node, j) && 1648255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_set_bit(destmap, module->perm_map[i][j] - 1, 1649255e72915d4cbddceb435e13d81601755714e9fSE Android 1)) { 1650255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1651255e72915d4cbddceb435e13d81601755714e9fSE Android } 1652255e72915d4cbddceb435e13d81601755714e9fSE Android } 1653255e72915d4cbddceb435e13d81601755714e9fSE Android } 1654255e72915d4cbddceb435e13d81601755714e9fSE Android 1655255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1656255e72915d4cbddceb435e13d81601755714e9fSE Android 1657255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1658255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1659255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1660255e72915d4cbddceb435e13d81601755714e9fSE Android} 1661255e72915d4cbddceb435e13d81601755714e9fSE Android 1662255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_avrule_decl(link_state_t * state, policy_module_t * module, 1663255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t * src_decl, avrule_decl_t * dest_decl) 1664255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1665255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 1666255e72915d4cbddceb435e13d81601755714e9fSE Android 1667255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy all of the RBAC and TE rules */ 1668255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_avrule_list 1669255e72915d4cbddceb435e13d81601755714e9fSE Android (src_decl->avrules, &dest_decl->avrules, module, state) == -1 1670255e72915d4cbddceb435e13d81601755714e9fSE Android || copy_role_trans_list(src_decl->role_tr_rules, 1671255e72915d4cbddceb435e13d81601755714e9fSE Android &dest_decl->role_tr_rules, module, 1672255e72915d4cbddceb435e13d81601755714e9fSE Android state) == -1 1673255e72915d4cbddceb435e13d81601755714e9fSE Android || copy_role_allow_list(src_decl->role_allow_rules, 1674255e72915d4cbddceb435e13d81601755714e9fSE Android &dest_decl->role_allow_rules, module, 1675255e72915d4cbddceb435e13d81601755714e9fSE Android state) == -1 1676255e72915d4cbddceb435e13d81601755714e9fSE Android || copy_cond_list(src_decl->cond_list, &dest_decl->cond_list, 1677255e72915d4cbddceb435e13d81601755714e9fSE Android module, state) == -1) { 1678255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1679255e72915d4cbddceb435e13d81601755714e9fSE Android } 1680255e72915d4cbddceb435e13d81601755714e9fSE Android 1681255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_filename_trans_list(src_decl->filename_trans_rules, 1682255e72915d4cbddceb435e13d81601755714e9fSE Android &dest_decl->filename_trans_rules, 1683255e72915d4cbddceb435e13d81601755714e9fSE Android module, state)) 1684255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1685255e72915d4cbddceb435e13d81601755714e9fSE Android 1686255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_range_trans_list(src_decl->range_tr_rules, 1687255e72915d4cbddceb435e13d81601755714e9fSE Android &dest_decl->range_tr_rules, module, state)) 1688255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1689255e72915d4cbddceb435e13d81601755714e9fSE Android 1690255e72915d4cbddceb435e13d81601755714e9fSE Android /* finally copy any identifiers local to this declaration */ 1691255e72915d4cbddceb435e13d81601755714e9fSE Android ret = copy_identifiers(state, src_decl->symtab, dest_decl); 1692255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret < 0) { 1693255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 1694255e72915d4cbddceb435e13d81601755714e9fSE Android } 1695255e72915d4cbddceb435e13d81601755714e9fSE Android 1696255e72915d4cbddceb435e13d81601755714e9fSE Android /* then copy required and declared scope indices here */ 1697255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_scope_index(&src_decl->required, &dest_decl->required, 1698255e72915d4cbddceb435e13d81601755714e9fSE Android module, state) == -1 || 1699255e72915d4cbddceb435e13d81601755714e9fSE Android copy_scope_index(&src_decl->declared, &dest_decl->declared, 1700255e72915d4cbddceb435e13d81601755714e9fSE Android module, state) == -1) { 1701255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1702255e72915d4cbddceb435e13d81601755714e9fSE Android } 1703255e72915d4cbddceb435e13d81601755714e9fSE Android 1704255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1705255e72915d4cbddceb435e13d81601755714e9fSE Android} 1706255e72915d4cbddceb435e13d81601755714e9fSE Android 1707255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_avrule_block(link_state_t * state, policy_module_t * module, 1708255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t * block) 1709255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1710255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *new_block = avrule_block_create(); 1711255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl, *last_decl = NULL; 1712255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 1713255e72915d4cbddceb435e13d81601755714e9fSE Android 1714255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_block == NULL) { 1715255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1716255e72915d4cbddceb435e13d81601755714e9fSE Android ret = -1; 1717255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1718255e72915d4cbddceb435e13d81601755714e9fSE Android } 1719255e72915d4cbddceb435e13d81601755714e9fSE Android 1720255e72915d4cbddceb435e13d81601755714e9fSE Android new_block->flags = block->flags; 1721255e72915d4cbddceb435e13d81601755714e9fSE Android 1722255e72915d4cbddceb435e13d81601755714e9fSE Android for (decl = block->branch_list; decl != NULL; decl = decl->next) { 1723255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *new_decl = 1724255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_create(state->next_decl_id); 1725255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_decl == NULL) { 1726255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1727255e72915d4cbddceb435e13d81601755714e9fSE Android ret = -1; 1728255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1729255e72915d4cbddceb435e13d81601755714e9fSE Android } 1730255e72915d4cbddceb435e13d81601755714e9fSE Android 1731255e72915d4cbddceb435e13d81601755714e9fSE Android if (module->policy->name != NULL) { 1732255e72915d4cbddceb435e13d81601755714e9fSE Android new_decl->module_name = strdup(module->policy->name); 1733255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_decl->module_name == NULL) { 1734255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory\n"); 1735255e72915d4cbddceb435e13d81601755714e9fSE Android ret = -1; 1736255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1737255e72915d4cbddceb435e13d81601755714e9fSE Android } 1738255e72915d4cbddceb435e13d81601755714e9fSE Android } 1739255e72915d4cbddceb435e13d81601755714e9fSE Android 1740255e72915d4cbddceb435e13d81601755714e9fSE Android if (last_decl == NULL) { 1741255e72915d4cbddceb435e13d81601755714e9fSE Android new_block->branch_list = new_decl; 1742255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1743255e72915d4cbddceb435e13d81601755714e9fSE Android last_decl->next = new_decl; 1744255e72915d4cbddceb435e13d81601755714e9fSE Android } 1745255e72915d4cbddceb435e13d81601755714e9fSE Android last_decl = new_decl; 1746255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->decl_val_to_struct[state->next_decl_id - 1] = 1747255e72915d4cbddceb435e13d81601755714e9fSE Android new_decl; 1748255e72915d4cbddceb435e13d81601755714e9fSE Android state->decl_to_mod[state->next_decl_id] = module->policy; 1749255e72915d4cbddceb435e13d81601755714e9fSE Android 1750255e72915d4cbddceb435e13d81601755714e9fSE Android module->avdecl_map[decl->decl_id] = new_decl->decl_id; 1751255e72915d4cbddceb435e13d81601755714e9fSE Android 1752255e72915d4cbddceb435e13d81601755714e9fSE Android ret = copy_avrule_decl(state, module, decl, new_decl); 1753255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 1754255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1755255e72915d4cbddceb435e13d81601755714e9fSE Android } 1756255e72915d4cbddceb435e13d81601755714e9fSE Android 1757255e72915d4cbddceb435e13d81601755714e9fSE Android state->next_decl_id++; 1758255e72915d4cbddceb435e13d81601755714e9fSE Android } 1759255e72915d4cbddceb435e13d81601755714e9fSE Android state->last_avrule_block->next = new_block; 1760255e72915d4cbddceb435e13d81601755714e9fSE Android state->last_avrule_block = new_block; 1761255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1762255e72915d4cbddceb435e13d81601755714e9fSE Android 1763255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1764255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_list_destroy(new_block); 1765255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 1766255e72915d4cbddceb435e13d81601755714e9fSE Android} 1767255e72915d4cbddceb435e13d81601755714e9fSE Android 1768255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int scope_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1769255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1770255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1771255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 1772255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 1773255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key, *new_id = NULL; 1774255e72915d4cbddceb435e13d81601755714e9fSE Android scope_datum_t *scope, *base_scope; 1775255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *) data; 1776255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t symbol_num = state->symbol_num; 1777255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *avdecl_map = state->cur->avdecl_map; 1778255e72915d4cbddceb435e13d81601755714e9fSE Android 1779255e72915d4cbddceb435e13d81601755714e9fSE Android scope = (scope_datum_t *) datum; 1780255e72915d4cbddceb435e13d81601755714e9fSE Android 1781255e72915d4cbddceb435e13d81601755714e9fSE Android /* check if the base already has a scope entry */ 1782255e72915d4cbddceb435e13d81601755714e9fSE Android base_scope = hashtab_search(state->base->scope[symbol_num].table, id); 1783255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_scope == NULL) { 1784255e72915d4cbddceb435e13d81601755714e9fSE Android scope_datum_t *new_scope; 1785255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_id = strdup(id)) == NULL) { 1786255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1787255e72915d4cbddceb435e13d81601755714e9fSE Android } 1788255e72915d4cbddceb435e13d81601755714e9fSE Android 1789255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_scope = 1790255e72915d4cbddceb435e13d81601755714e9fSE Android (scope_datum_t *) calloc(1, sizeof(*new_scope))) == NULL) { 1791255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 1792255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1793255e72915d4cbddceb435e13d81601755714e9fSE Android } 1794255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->base->scope[symbol_num].table, 1795255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 1796255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_scope); 1797255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 1798255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 1799255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_scope); 1800255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1801255e72915d4cbddceb435e13d81601755714e9fSE Android } 1802255e72915d4cbddceb435e13d81601755714e9fSE Android new_scope->scope = SCOPE_REQ; /* this is reset further down */ 1803255e72915d4cbddceb435e13d81601755714e9fSE Android base_scope = new_scope; 1804255e72915d4cbddceb435e13d81601755714e9fSE Android } 1805255e72915d4cbddceb435e13d81601755714e9fSE Android if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_DECL) { 1806255e72915d4cbddceb435e13d81601755714e9fSE Android /* this module declared symbol, so overwrite the old 1807255e72915d4cbddceb435e13d81601755714e9fSE Android * list with the new decl ids */ 1808255e72915d4cbddceb435e13d81601755714e9fSE Android base_scope->scope = SCOPE_DECL; 1809255e72915d4cbddceb435e13d81601755714e9fSE Android free(base_scope->decl_ids); 1810255e72915d4cbddceb435e13d81601755714e9fSE Android base_scope->decl_ids = NULL; 1811255e72915d4cbddceb435e13d81601755714e9fSE Android base_scope->decl_ids_len = 0; 1812255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < scope->decl_ids_len; i++) { 1813255e72915d4cbddceb435e13d81601755714e9fSE Android if (add_i_to_a(avdecl_map[scope->decl_ids[i]], 1814255e72915d4cbddceb435e13d81601755714e9fSE Android &base_scope->decl_ids_len, 1815255e72915d4cbddceb435e13d81601755714e9fSE Android &base_scope->decl_ids) == -1) { 1816255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1817255e72915d4cbddceb435e13d81601755714e9fSE Android } 1818255e72915d4cbddceb435e13d81601755714e9fSE Android } 1819255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (base_scope->scope == SCOPE_DECL && scope->scope == SCOPE_REQ) { 1820255e72915d4cbddceb435e13d81601755714e9fSE Android /* this module depended on a symbol that now exists, 1821255e72915d4cbddceb435e13d81601755714e9fSE Android * so don't do anything */ 1822255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_REQ) { 1823255e72915d4cbddceb435e13d81601755714e9fSE Android /* symbol is still required, so add to the list */ 1824255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < scope->decl_ids_len; i++) { 1825255e72915d4cbddceb435e13d81601755714e9fSE Android if (add_i_to_a(avdecl_map[scope->decl_ids[i]], 1826255e72915d4cbddceb435e13d81601755714e9fSE Android &base_scope->decl_ids_len, 1827255e72915d4cbddceb435e13d81601755714e9fSE Android &base_scope->decl_ids) == -1) { 1828255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1829255e72915d4cbddceb435e13d81601755714e9fSE Android } 1830255e72915d4cbddceb435e13d81601755714e9fSE Android } 1831255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1832255e72915d4cbddceb435e13d81601755714e9fSE Android /* this module declared a symbol, and it was already 1833255e72915d4cbddceb435e13d81601755714e9fSE Android * declared. only roles and users may be multiply 1834255e72915d4cbddceb435e13d81601755714e9fSE Android * declared; for all others this is an error. */ 1835255e72915d4cbddceb435e13d81601755714e9fSE Android if (symbol_num != SYM_ROLES && symbol_num != SYM_USERS) { 1836255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 1837255e72915d4cbddceb435e13d81601755714e9fSE Android "%s: Duplicate declaration in module: %s %s", 1838255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name, 1839255e72915d4cbddceb435e13d81601755714e9fSE Android symtab_names[state->symbol_num], id); 1840255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1841255e72915d4cbddceb435e13d81601755714e9fSE Android } 1842255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < scope->decl_ids_len; i++) { 1843255e72915d4cbddceb435e13d81601755714e9fSE Android if (add_i_to_a(avdecl_map[scope->decl_ids[i]], 1844255e72915d4cbddceb435e13d81601755714e9fSE Android &base_scope->decl_ids_len, 1845255e72915d4cbddceb435e13d81601755714e9fSE Android &base_scope->decl_ids) == -1) { 1846255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 1847255e72915d4cbddceb435e13d81601755714e9fSE Android } 1848255e72915d4cbddceb435e13d81601755714e9fSE Android } 1849255e72915d4cbddceb435e13d81601755714e9fSE Android } 1850255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1851255e72915d4cbddceb435e13d81601755714e9fSE Android 1852255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 1853255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1854255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1855255e72915d4cbddceb435e13d81601755714e9fSE Android} 1856255e72915d4cbddceb435e13d81601755714e9fSE Android 1857255e72915d4cbddceb435e13d81601755714e9fSE Android/* Copy a module over to a base, remapping all values within. After 1858255e72915d4cbddceb435e13d81601755714e9fSE Android * all identifiers and rules are done, copy the scoping information. 1859255e72915d4cbddceb435e13d81601755714e9fSE Android * This is when it checks for duplicate declarations. */ 1860255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_module(link_state_t * state, policy_module_t * module) 1861255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1862255e72915d4cbddceb435e13d81601755714e9fSE Android int i, ret; 1863255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *cur; 1864255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur = module; 1865255e72915d4cbddceb435e13d81601755714e9fSE Android state->cur_mod_name = module->policy->name; 1866255e72915d4cbddceb435e13d81601755714e9fSE Android 1867255e72915d4cbddceb435e13d81601755714e9fSE Android /* first copy all of the identifiers */ 1868255e72915d4cbddceb435e13d81601755714e9fSE Android ret = copy_identifiers(state, module->policy->symtab, NULL); 1869255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 1870255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 1871255e72915d4cbddceb435e13d81601755714e9fSE Android } 1872255e72915d4cbddceb435e13d81601755714e9fSE Android 1873255e72915d4cbddceb435e13d81601755714e9fSE Android /* next copy all of the avrule blocks */ 1874255e72915d4cbddceb435e13d81601755714e9fSE Android for (cur = module->policy->global; cur != NULL; cur = cur->next) { 1875255e72915d4cbddceb435e13d81601755714e9fSE Android ret = copy_avrule_block(state, module, cur); 1876255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 1877255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 1878255e72915d4cbddceb435e13d81601755714e9fSE Android } 1879255e72915d4cbddceb435e13d81601755714e9fSE Android } 1880255e72915d4cbddceb435e13d81601755714e9fSE Android 1881255e72915d4cbddceb435e13d81601755714e9fSE Android /* then copy the scoping tables */ 1882255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < SYM_NUM; i++) { 1883255e72915d4cbddceb435e13d81601755714e9fSE Android state->symbol_num = i; 1884255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 1885255e72915d4cbddceb435e13d81601755714e9fSE Android (module->policy->scope[i].table, scope_copy_callback, 1886255e72915d4cbddceb435e13d81601755714e9fSE Android state)) { 1887255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1888255e72915d4cbddceb435e13d81601755714e9fSE Android } 1889255e72915d4cbddceb435e13d81601755714e9fSE Android } 1890255e72915d4cbddceb435e13d81601755714e9fSE Android 1891255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1892255e72915d4cbddceb435e13d81601755714e9fSE Android} 1893255e72915d4cbddceb435e13d81601755714e9fSE Android 1894255e72915d4cbddceb435e13d81601755714e9fSE Android/***** functions that check requirements and enable blocks in a module ******/ 1895255e72915d4cbddceb435e13d81601755714e9fSE Android 1896255e72915d4cbddceb435e13d81601755714e9fSE Android/* borrowed from checkpolicy.c */ 1897255e72915d4cbddceb435e13d81601755714e9fSE Android 1898255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct find_perm_arg { 1899255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int valuep; 1900255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_key_t key; 1901255e72915d4cbddceb435e13d81601755714e9fSE Android}; 1902255e72915d4cbddceb435e13d81601755714e9fSE Android 1903255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *varg) 1904255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1905255e72915d4cbddceb435e13d81601755714e9fSE Android 1906255e72915d4cbddceb435e13d81601755714e9fSE Android struct find_perm_arg *arg = varg; 1907255e72915d4cbddceb435e13d81601755714e9fSE Android 1908255e72915d4cbddceb435e13d81601755714e9fSE Android perm_datum_t *perdatum = (perm_datum_t *) datum; 1909255e72915d4cbddceb435e13d81601755714e9fSE Android if (arg->valuep == perdatum->s.value) { 1910255e72915d4cbddceb435e13d81601755714e9fSE Android arg->key = key; 1911255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 1912255e72915d4cbddceb435e13d81601755714e9fSE Android } 1913255e72915d4cbddceb435e13d81601755714e9fSE Android 1914255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1915255e72915d4cbddceb435e13d81601755714e9fSE Android} 1916255e72915d4cbddceb435e13d81601755714e9fSE Android 1917255e72915d4cbddceb435e13d81601755714e9fSE Android/* Check if the requirements are met for a single declaration. If all 1918255e72915d4cbddceb435e13d81601755714e9fSE Android * are met return 1. For the first requirement found to be missing, 1919255e72915d4cbddceb435e13d81601755714e9fSE Android * if 'missing_sym_num' and 'missing_value' are both not NULL then 1920255e72915d4cbddceb435e13d81601755714e9fSE Android * write to them the symbol number and value for the missing 1921255e72915d4cbddceb435e13d81601755714e9fSE Android * declaration. Then return 0 to indicate a missing declaration. 1922255e72915d4cbddceb435e13d81601755714e9fSE Android * Note that if a declaration had no requirement at all (e.g., an ELSE 1923255e72915d4cbddceb435e13d81601755714e9fSE Android * block) this returns 1. */ 1924255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int is_decl_requires_met(link_state_t * state, 1925255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t * decl, 1926255e72915d4cbddceb435e13d81601755714e9fSE Android struct missing_requirement *req) 1927255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1928255e72915d4cbddceb435e13d81601755714e9fSE Android /* (This algorithm is very unoptimized. It performs many 1929255e72915d4cbddceb435e13d81601755714e9fSE Android * redundant checks. A very obvious improvement is to cache 1930255e72915d4cbddceb435e13d81601755714e9fSE Android * which symbols have been verified, so that they do not need 1931255e72915d4cbddceb435e13d81601755714e9fSE Android * to be re-checked.) */ 1932255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 1933255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *bitmap; 1934255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *perm_id; 1935255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *pol = state->base; 1936255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *node; 1937255e72915d4cbddceb435e13d81601755714e9fSE Android 1938255e72915d4cbddceb435e13d81601755714e9fSE Android /* check that all symbols have been satisfied */ 1939255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < SYM_NUM; i++) { 1940255e72915d4cbddceb435e13d81601755714e9fSE Android if (i == SYM_CLASSES) { 1941255e72915d4cbddceb435e13d81601755714e9fSE Android /* classes will be checked during permissions 1942255e72915d4cbddceb435e13d81601755714e9fSE Android * checking phase below */ 1943255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1944255e72915d4cbddceb435e13d81601755714e9fSE Android } 1945255e72915d4cbddceb435e13d81601755714e9fSE Android bitmap = &decl->required.scope[i]; 1946255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(bitmap, node, j) { 1947255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(node, j)) { 1948255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1949255e72915d4cbddceb435e13d81601755714e9fSE Android } 1950255e72915d4cbddceb435e13d81601755714e9fSE Android 1951255e72915d4cbddceb435e13d81601755714e9fSE Android /* check base's scope table */ 1952255e72915d4cbddceb435e13d81601755714e9fSE Android id = pol->sym_val_to_name[i][j]; 1953255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, i)) { 1954255e72915d4cbddceb435e13d81601755714e9fSE Android /* this symbol was not found */ 1955255e72915d4cbddceb435e13d81601755714e9fSE Android if (req != NULL) { 1956255e72915d4cbddceb435e13d81601755714e9fSE Android req->symbol_type = i; 1957255e72915d4cbddceb435e13d81601755714e9fSE Android req->symbol_value = j + 1; 1958255e72915d4cbddceb435e13d81601755714e9fSE Android } 1959255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1960255e72915d4cbddceb435e13d81601755714e9fSE Android } 1961255e72915d4cbddceb435e13d81601755714e9fSE Android } 1962255e72915d4cbddceb435e13d81601755714e9fSE Android } 1963255e72915d4cbddceb435e13d81601755714e9fSE Android /* check that all classes and permissions have been satisfied */ 1964255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < decl->required.class_perms_len; i++) { 1965255e72915d4cbddceb435e13d81601755714e9fSE Android 1966255e72915d4cbddceb435e13d81601755714e9fSE Android bitmap = decl->required.class_perms_map + i; 1967255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(bitmap, node, j) { 1968255e72915d4cbddceb435e13d81601755714e9fSE Android struct find_perm_arg fparg; 1969255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *cladatum; 1970255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t perm_value = j + 1; 1971255e72915d4cbddceb435e13d81601755714e9fSE Android scope_datum_t *scope; 1972255e72915d4cbddceb435e13d81601755714e9fSE Android 1973255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(node, j)) { 1974255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1975255e72915d4cbddceb435e13d81601755714e9fSE Android } 1976255e72915d4cbddceb435e13d81601755714e9fSE Android id = pol->p_class_val_to_name[i]; 1977255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum = pol->class_val_to_struct[i]; 1978255e72915d4cbddceb435e13d81601755714e9fSE Android 1979255e72915d4cbddceb435e13d81601755714e9fSE Android scope = 1980255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(state->base->p_classes_scope.table, 1981255e72915d4cbddceb435e13d81601755714e9fSE Android id); 1982255e72915d4cbddceb435e13d81601755714e9fSE Android if (scope == NULL) { 1983255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 1984255e72915d4cbddceb435e13d81601755714e9fSE Android "Could not find scope information for class %s", 1985255e72915d4cbddceb435e13d81601755714e9fSE Android id); 1986255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1987255e72915d4cbddceb435e13d81601755714e9fSE Android } 1988255e72915d4cbddceb435e13d81601755714e9fSE Android 1989255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.valuep = perm_value; 1990255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.key = NULL; 1991255e72915d4cbddceb435e13d81601755714e9fSE Android 1992255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(cladatum->permissions.table, find_perm, 1993255e72915d4cbddceb435e13d81601755714e9fSE Android &fparg); 1994255e72915d4cbddceb435e13d81601755714e9fSE Android if (fparg.key == NULL && cladatum->comdatum != NULL) 1995255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(cladatum->comdatum->permissions. 1996255e72915d4cbddceb435e13d81601755714e9fSE Android table, find_perm, &fparg); 1997255e72915d4cbddceb435e13d81601755714e9fSE Android perm_id = fparg.key; 1998255e72915d4cbddceb435e13d81601755714e9fSE Android 1999255e72915d4cbddceb435e13d81601755714e9fSE Android assert(perm_id != NULL); 2000255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_perm_enabled(id, perm_id, state->base)) { 2001255e72915d4cbddceb435e13d81601755714e9fSE Android if (req != NULL) { 2002255e72915d4cbddceb435e13d81601755714e9fSE Android req->symbol_type = SYM_CLASSES; 2003255e72915d4cbddceb435e13d81601755714e9fSE Android req->symbol_value = i + 1; 2004255e72915d4cbddceb435e13d81601755714e9fSE Android req->perm_value = perm_value; 2005255e72915d4cbddceb435e13d81601755714e9fSE Android } 2006255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2007255e72915d4cbddceb435e13d81601755714e9fSE Android } 2008255e72915d4cbddceb435e13d81601755714e9fSE Android } 2009255e72915d4cbddceb435e13d81601755714e9fSE Android } 2010255e72915d4cbddceb435e13d81601755714e9fSE Android 2011255e72915d4cbddceb435e13d81601755714e9fSE Android /* all requirements have been met */ 2012255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 2013255e72915d4cbddceb435e13d81601755714e9fSE Android} 2014255e72915d4cbddceb435e13d81601755714e9fSE Android 2015255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int debug_requirements(link_state_t * state, policydb_t * p) 2016255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2017255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 2018255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *cur; 2019255e72915d4cbddceb435e13d81601755714e9fSE Android missing_requirement_t req; 2020255e72915d4cbddceb435e13d81601755714e9fSE Android 2021255e72915d4cbddceb435e13d81601755714e9fSE Android for (cur = p->global; cur != NULL; cur = cur->next) { 2022255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur->enabled != NULL) 2023255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2024255e72915d4cbddceb435e13d81601755714e9fSE Android 2025255e72915d4cbddceb435e13d81601755714e9fSE Android ret = is_decl_requires_met(state, cur->branch_list, &req); 2026255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret < 0) { 2027255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 2028255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (ret == 0) { 2029255e72915d4cbddceb435e13d81601755714e9fSE Android char *mod_name = cur->branch_list->module_name ? 2030255e72915d4cbddceb435e13d81601755714e9fSE Android cur->branch_list->module_name : "BASE"; 2031255e72915d4cbddceb435e13d81601755714e9fSE Android if (req.symbol_type == SYM_CLASSES) { 2032255e72915d4cbddceb435e13d81601755714e9fSE Android 2033255e72915d4cbddceb435e13d81601755714e9fSE Android struct find_perm_arg fparg; 2034255e72915d4cbddceb435e13d81601755714e9fSE Android 2035255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *cladatum; 2036255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum = 2037255e72915d4cbddceb435e13d81601755714e9fSE Android p->class_val_to_struct[req.symbol_value - 2038255e72915d4cbddceb435e13d81601755714e9fSE Android 1]; 2039255e72915d4cbddceb435e13d81601755714e9fSE Android 2040255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.valuep = req.perm_value; 2041255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.key = NULL; 2042255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(cladatum->permissions.table, 2043255e72915d4cbddceb435e13d81601755714e9fSE Android find_perm, &fparg); 2044255e72915d4cbddceb435e13d81601755714e9fSE Android 2045255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur->flags & AVRULE_OPTIONAL) { 2046255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2047255e72915d4cbddceb435e13d81601755714e9fSE Android "%s[%d]'s optional requirements were not met: class %s, permission %s", 2048255e72915d4cbddceb435e13d81601755714e9fSE Android mod_name, cur->branch_list->decl_id, 2049255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_class_val_to_name[req. 2050255e72915d4cbddceb435e13d81601755714e9fSE Android symbol_value 2051255e72915d4cbddceb435e13d81601755714e9fSE Android - 1], 2052255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.key); 2053255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2054255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2055255e72915d4cbddceb435e13d81601755714e9fSE Android "%s[%d]'s global requirements were not met: class %s, permission %s", 2056255e72915d4cbddceb435e13d81601755714e9fSE Android mod_name, cur->branch_list->decl_id, 2057255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_class_val_to_name[req. 2058255e72915d4cbddceb435e13d81601755714e9fSE Android symbol_value 2059255e72915d4cbddceb435e13d81601755714e9fSE Android - 1], 2060255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.key); 2061255e72915d4cbddceb435e13d81601755714e9fSE Android } 2062255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2063255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur->flags & AVRULE_OPTIONAL) { 2064255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2065255e72915d4cbddceb435e13d81601755714e9fSE Android "%s[%d]'s optional requirements were not met: %s %s", 2066255e72915d4cbddceb435e13d81601755714e9fSE Android mod_name, cur->branch_list->decl_id, 2067255e72915d4cbddceb435e13d81601755714e9fSE Android symtab_names[req.symbol_type], 2068255e72915d4cbddceb435e13d81601755714e9fSE Android p->sym_val_to_name[req. 2069255e72915d4cbddceb435e13d81601755714e9fSE Android symbol_type][req. 2070255e72915d4cbddceb435e13d81601755714e9fSE Android symbol_value 2071255e72915d4cbddceb435e13d81601755714e9fSE Android - 2072255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 2073255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2074255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2075255e72915d4cbddceb435e13d81601755714e9fSE Android "%s[%d]'s global requirements were not met: %s %s", 2076255e72915d4cbddceb435e13d81601755714e9fSE Android mod_name, cur->branch_list->decl_id, 2077255e72915d4cbddceb435e13d81601755714e9fSE Android symtab_names[req.symbol_type], 2078255e72915d4cbddceb435e13d81601755714e9fSE Android p->sym_val_to_name[req. 2079255e72915d4cbddceb435e13d81601755714e9fSE Android symbol_type][req. 2080255e72915d4cbddceb435e13d81601755714e9fSE Android symbol_value 2081255e72915d4cbddceb435e13d81601755714e9fSE Android - 2082255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 2083255e72915d4cbddceb435e13d81601755714e9fSE Android } 2084255e72915d4cbddceb435e13d81601755714e9fSE Android } 2085255e72915d4cbddceb435e13d81601755714e9fSE Android } 2086255e72915d4cbddceb435e13d81601755714e9fSE Android } 2087255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2088255e72915d4cbddceb435e13d81601755714e9fSE Android} 2089255e72915d4cbddceb435e13d81601755714e9fSE Android 2090255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic void print_missing_requirements(link_state_t * state, 2091255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t * cur, 2092255e72915d4cbddceb435e13d81601755714e9fSE Android missing_requirement_t * req) 2093255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2094255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *p = state->base; 2095255e72915d4cbddceb435e13d81601755714e9fSE Android char *mod_name = cur->branch_list->module_name ? 2096255e72915d4cbddceb435e13d81601755714e9fSE Android cur->branch_list->module_name : "BASE"; 2097255e72915d4cbddceb435e13d81601755714e9fSE Android 2098255e72915d4cbddceb435e13d81601755714e9fSE Android if (req->symbol_type == SYM_CLASSES) { 2099255e72915d4cbddceb435e13d81601755714e9fSE Android 2100255e72915d4cbddceb435e13d81601755714e9fSE Android struct find_perm_arg fparg; 2101255e72915d4cbddceb435e13d81601755714e9fSE Android 2102255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *cladatum; 2103255e72915d4cbddceb435e13d81601755714e9fSE Android cladatum = p->class_val_to_struct[req->symbol_value - 1]; 2104255e72915d4cbddceb435e13d81601755714e9fSE Android 2105255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.valuep = req->perm_value; 2106255e72915d4cbddceb435e13d81601755714e9fSE Android fparg.key = NULL; 2107255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(cladatum->permissions.table, find_perm, &fparg); 2108255e72915d4cbddceb435e13d81601755714e9fSE Android 2109255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2110255e72915d4cbddceb435e13d81601755714e9fSE Android "%s's global requirements were not met: class %s, permission %s", 2111255e72915d4cbddceb435e13d81601755714e9fSE Android mod_name, 2112255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_class_val_to_name[req->symbol_value - 1], fparg.key); 2113255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2114255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2115255e72915d4cbddceb435e13d81601755714e9fSE Android "%s's global requirements were not met: %s %s", 2116255e72915d4cbddceb435e13d81601755714e9fSE Android mod_name, 2117255e72915d4cbddceb435e13d81601755714e9fSE Android symtab_names[req->symbol_type], 2118255e72915d4cbddceb435e13d81601755714e9fSE Android p->sym_val_to_name[req->symbol_type][req->symbol_value - 2119255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 2120255e72915d4cbddceb435e13d81601755714e9fSE Android } 2121255e72915d4cbddceb435e13d81601755714e9fSE Android} 2122255e72915d4cbddceb435e13d81601755714e9fSE Android 2123255e72915d4cbddceb435e13d81601755714e9fSE Android/* Enable all of the avrule_decl blocks for the policy. This simple 2124255e72915d4cbddceb435e13d81601755714e9fSE Android * algorithm is the following: 2125255e72915d4cbddceb435e13d81601755714e9fSE Android * 2126255e72915d4cbddceb435e13d81601755714e9fSE Android * 1) Enable all of the non-else avrule_decls for all blocks. 2127255e72915d4cbddceb435e13d81601755714e9fSE Android * 2) Iterate through the non-else decls looking for decls whose requirements 2128255e72915d4cbddceb435e13d81601755714e9fSE Android * are not met. 2129255e72915d4cbddceb435e13d81601755714e9fSE Android * 2a) If the decl is non-optional, return immediately with an error. 2130255e72915d4cbddceb435e13d81601755714e9fSE Android * 2b) If the decl is optional, disable the block and mark changed = 1 2131255e72915d4cbddceb435e13d81601755714e9fSE Android * 3) If changed == 1 goto 2. 2132255e72915d4cbddceb435e13d81601755714e9fSE Android * 4) Iterate through all blocks looking for those that have no enabled 2133255e72915d4cbddceb435e13d81601755714e9fSE Android * decl. If the block has an else decl, enable. 2134255e72915d4cbddceb435e13d81601755714e9fSE Android * 2135255e72915d4cbddceb435e13d81601755714e9fSE Android * This will correctly handle all dependencies, including mutual and 2136255e72915d4cbddceb435e13d81601755714e9fSE Android * cicular. The only downside is that it is slow. 2137255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2138255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int enable_avrules(link_state_t * state, policydb_t * pol) 2139255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2140255e72915d4cbddceb435e13d81601755714e9fSE Android int changed = 1; 2141255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *block; 2142255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl; 2143255e72915d4cbddceb435e13d81601755714e9fSE Android missing_requirement_t req; 2144255e72915d4cbddceb435e13d81601755714e9fSE Android int ret = 0, rc; 2145255e72915d4cbddceb435e13d81601755714e9fSE Android 2146255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) { 2147255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "Determining which avrules to enable."); 2148255e72915d4cbddceb435e13d81601755714e9fSE Android } 2149255e72915d4cbddceb435e13d81601755714e9fSE Android 2150255e72915d4cbddceb435e13d81601755714e9fSE Android /* 1) enable all of the non-else blocks */ 2151255e72915d4cbddceb435e13d81601755714e9fSE Android for (block = pol->global; block != NULL; block = block->next) { 2152255e72915d4cbddceb435e13d81601755714e9fSE Android block->enabled = block->branch_list; 2153255e72915d4cbddceb435e13d81601755714e9fSE Android block->enabled->enabled = 1; 2154255e72915d4cbddceb435e13d81601755714e9fSE Android for (decl = block->branch_list->next; decl != NULL; 2155255e72915d4cbddceb435e13d81601755714e9fSE Android decl = decl->next) 2156255e72915d4cbddceb435e13d81601755714e9fSE Android decl->enabled = 0; 2157255e72915d4cbddceb435e13d81601755714e9fSE Android } 2158255e72915d4cbddceb435e13d81601755714e9fSE Android 2159255e72915d4cbddceb435e13d81601755714e9fSE Android /* 2) Iterate */ 2160255e72915d4cbddceb435e13d81601755714e9fSE Android while (changed) { 2161255e72915d4cbddceb435e13d81601755714e9fSE Android changed = 0; 2162255e72915d4cbddceb435e13d81601755714e9fSE Android for (block = pol->global; block != NULL; block = block->next) { 2163255e72915d4cbddceb435e13d81601755714e9fSE Android if (block->enabled == NULL) { 2164255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2165255e72915d4cbddceb435e13d81601755714e9fSE Android } 2166255e72915d4cbddceb435e13d81601755714e9fSE Android decl = block->branch_list; 2167255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) { 2168255e72915d4cbddceb435e13d81601755714e9fSE Android char *mod_name = decl->module_name ? 2169255e72915d4cbddceb435e13d81601755714e9fSE Android decl->module_name : "BASE"; 2170255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "check module %s decl %d\n", 2171255e72915d4cbddceb435e13d81601755714e9fSE Android mod_name, decl->decl_id); 2172255e72915d4cbddceb435e13d81601755714e9fSE Android } 2173255e72915d4cbddceb435e13d81601755714e9fSE Android rc = is_decl_requires_met(state, decl, &req); 2174255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc < 0) { 2175255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_ERR; 2176255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 2177255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (rc == 0) { 2178255e72915d4cbddceb435e13d81601755714e9fSE Android decl->enabled = 0; 2179255e72915d4cbddceb435e13d81601755714e9fSE Android block->enabled = NULL; 2180255e72915d4cbddceb435e13d81601755714e9fSE Android changed = 1; 2181255e72915d4cbddceb435e13d81601755714e9fSE Android if (!(block->flags & AVRULE_OPTIONAL)) { 2182255e72915d4cbddceb435e13d81601755714e9fSE Android print_missing_requirements(state, block, 2183255e72915d4cbddceb435e13d81601755714e9fSE Android &req); 2184255e72915d4cbddceb435e13d81601755714e9fSE Android ret = SEPOL_EREQ; 2185255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 2186255e72915d4cbddceb435e13d81601755714e9fSE Android } 2187255e72915d4cbddceb435e13d81601755714e9fSE Android } 2188255e72915d4cbddceb435e13d81601755714e9fSE Android } 2189255e72915d4cbddceb435e13d81601755714e9fSE Android } 2190255e72915d4cbddceb435e13d81601755714e9fSE Android 2191255e72915d4cbddceb435e13d81601755714e9fSE Android /* 4) else handling 2192255e72915d4cbddceb435e13d81601755714e9fSE Android * 2193255e72915d4cbddceb435e13d81601755714e9fSE Android * Iterate through all of the blocks skipping the first (which is the 2194255e72915d4cbddceb435e13d81601755714e9fSE Android * global block, is required to be present, and cannot have an else). 2195255e72915d4cbddceb435e13d81601755714e9fSE Android * If the block is disabled and has an else decl, enable that. 2196255e72915d4cbddceb435e13d81601755714e9fSE Android * 2197255e72915d4cbddceb435e13d81601755714e9fSE Android * This code assumes that the second block in the branch list is the else 2198255e72915d4cbddceb435e13d81601755714e9fSE Android * block. This is currently supported by the compiler. 2199255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2200255e72915d4cbddceb435e13d81601755714e9fSE Android for (block = pol->global->next; block != NULL; block = block->next) { 2201255e72915d4cbddceb435e13d81601755714e9fSE Android if (block->enabled == NULL) { 2202255e72915d4cbddceb435e13d81601755714e9fSE Android if (block->branch_list->next != NULL) { 2203255e72915d4cbddceb435e13d81601755714e9fSE Android block->enabled = block->branch_list->next; 2204255e72915d4cbddceb435e13d81601755714e9fSE Android block->branch_list->next->enabled = 1; 2205255e72915d4cbddceb435e13d81601755714e9fSE Android } 2206255e72915d4cbddceb435e13d81601755714e9fSE Android } 2207255e72915d4cbddceb435e13d81601755714e9fSE Android } 2208255e72915d4cbddceb435e13d81601755714e9fSE Android 2209255e72915d4cbddceb435e13d81601755714e9fSE Android out: 2210255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 2211255e72915d4cbddceb435e13d81601755714e9fSE Android debug_requirements(state, pol); 2212255e72915d4cbddceb435e13d81601755714e9fSE Android 2213255e72915d4cbddceb435e13d81601755714e9fSE Android return ret; 2214255e72915d4cbddceb435e13d81601755714e9fSE Android} 2215255e72915d4cbddceb435e13d81601755714e9fSE Android 2216255e72915d4cbddceb435e13d81601755714e9fSE Android/*********** the main linking functions ***********/ 2217255e72915d4cbddceb435e13d81601755714e9fSE Android 2218255e72915d4cbddceb435e13d81601755714e9fSE Android/* Given a module's policy, normalize all conditional expressions 2219255e72915d4cbddceb435e13d81601755714e9fSE Android * within. Return 0 on success, -1 on error. */ 2220255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int cond_normalize(policydb_t * p) 2221255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2222255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *block; 2223255e72915d4cbddceb435e13d81601755714e9fSE Android for (block = p->global; block != NULL; block = block->next) { 2224255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl; 2225255e72915d4cbddceb435e13d81601755714e9fSE Android for (decl = block->branch_list; decl != NULL; decl = decl->next) { 2226255e72915d4cbddceb435e13d81601755714e9fSE Android cond_list_t *cond = decl->cond_list; 2227255e72915d4cbddceb435e13d81601755714e9fSE Android while (cond) { 2228255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_normalize_expr(p, cond) < 0) 2229255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2230255e72915d4cbddceb435e13d81601755714e9fSE Android cond = cond->next; 2231255e72915d4cbddceb435e13d81601755714e9fSE Android } 2232255e72915d4cbddceb435e13d81601755714e9fSE Android } 2233255e72915d4cbddceb435e13d81601755714e9fSE Android } 2234255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2235255e72915d4cbddceb435e13d81601755714e9fSE Android} 2236255e72915d4cbddceb435e13d81601755714e9fSE Android 2237255e72915d4cbddceb435e13d81601755714e9fSE Android/* Allocate space for the various remapping arrays. */ 2238255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int prepare_module(link_state_t * state, policy_module_t * module) 2239255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2240255e72915d4cbddceb435e13d81601755714e9fSE Android int i; 2241255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t items, num_decls = 0; 2242255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *cur; 2243255e72915d4cbddceb435e13d81601755714e9fSE Android 2244255e72915d4cbddceb435e13d81601755714e9fSE Android /* allocate the maps */ 2245255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < SYM_NUM; i++) { 2246255e72915d4cbddceb435e13d81601755714e9fSE Android items = module->policy->symtab[i].nprim; 2247255e72915d4cbddceb435e13d81601755714e9fSE Android if ((module->map[i] = 2248255e72915d4cbddceb435e13d81601755714e9fSE Android (uint32_t *) calloc(items, 2249255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(*module->map[i]))) == NULL) { 2250255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2251255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2252255e72915d4cbddceb435e13d81601755714e9fSE Android } 2253255e72915d4cbddceb435e13d81601755714e9fSE Android } 2254255e72915d4cbddceb435e13d81601755714e9fSE Android 2255255e72915d4cbddceb435e13d81601755714e9fSE Android /* allocate the permissions remap here */ 2256255e72915d4cbddceb435e13d81601755714e9fSE Android items = module->policy->p_classes.nprim; 2257255e72915d4cbddceb435e13d81601755714e9fSE Android if ((module->perm_map_len = 2258255e72915d4cbddceb435e13d81601755714e9fSE Android calloc(items, sizeof(*module->perm_map_len))) == NULL) { 2259255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2260255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2261255e72915d4cbddceb435e13d81601755714e9fSE Android } 2262255e72915d4cbddceb435e13d81601755714e9fSE Android if ((module->perm_map = 2263255e72915d4cbddceb435e13d81601755714e9fSE Android calloc(items, sizeof(*module->perm_map))) == NULL) { 2264255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2265255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2266255e72915d4cbddceb435e13d81601755714e9fSE Android } 2267255e72915d4cbddceb435e13d81601755714e9fSE Android 2268255e72915d4cbddceb435e13d81601755714e9fSE Android /* allocate a map for avrule_decls */ 2269255e72915d4cbddceb435e13d81601755714e9fSE Android for (cur = module->policy->global; cur != NULL; cur = cur->next) { 2270255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl; 2271255e72915d4cbddceb435e13d81601755714e9fSE Android for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 2272255e72915d4cbddceb435e13d81601755714e9fSE Android if (decl->decl_id > num_decls) { 2273255e72915d4cbddceb435e13d81601755714e9fSE Android num_decls = decl->decl_id; 2274255e72915d4cbddceb435e13d81601755714e9fSE Android } 2275255e72915d4cbddceb435e13d81601755714e9fSE Android } 2276255e72915d4cbddceb435e13d81601755714e9fSE Android } 2277255e72915d4cbddceb435e13d81601755714e9fSE Android num_decls++; 2278255e72915d4cbddceb435e13d81601755714e9fSE Android if ((module->avdecl_map = calloc(num_decls, sizeof(uint32_t))) == NULL) { 2279255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2280255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2281255e72915d4cbddceb435e13d81601755714e9fSE Android } 2282255e72915d4cbddceb435e13d81601755714e9fSE Android module->num_decls = num_decls; 2283255e72915d4cbddceb435e13d81601755714e9fSE Android 2284255e72915d4cbddceb435e13d81601755714e9fSE Android /* normalize conditionals within */ 2285255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_normalize(module->policy) < 0) { 2286255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2287255e72915d4cbddceb435e13d81601755714e9fSE Android "Error while normalizing conditionals within the module %s.", 2288255e72915d4cbddceb435e13d81601755714e9fSE Android module->policy->name); 2289255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2290255e72915d4cbddceb435e13d81601755714e9fSE Android } 2291255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2292255e72915d4cbddceb435e13d81601755714e9fSE Android} 2293255e72915d4cbddceb435e13d81601755714e9fSE Android 2294255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int prepare_base(link_state_t * state, uint32_t num_mod_decls) 2295255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2296255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *cur = state->base->global; 2297255e72915d4cbddceb435e13d81601755714e9fSE Android assert(cur != NULL); 2298255e72915d4cbddceb435e13d81601755714e9fSE Android state->next_decl_id = 0; 2299255e72915d4cbddceb435e13d81601755714e9fSE Android 2300255e72915d4cbddceb435e13d81601755714e9fSE Android /* iterate through all of the declarations in the base, to 2301255e72915d4cbddceb435e13d81601755714e9fSE Android determine what the next decl_id should be */ 2302255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur != NULL) { 2303255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl; 2304255e72915d4cbddceb435e13d81601755714e9fSE Android for (decl = cur->branch_list; decl != NULL; decl = decl->next) { 2305255e72915d4cbddceb435e13d81601755714e9fSE Android if (decl->decl_id > state->next_decl_id) { 2306255e72915d4cbddceb435e13d81601755714e9fSE Android state->next_decl_id = decl->decl_id; 2307255e72915d4cbddceb435e13d81601755714e9fSE Android } 2308255e72915d4cbddceb435e13d81601755714e9fSE Android } 2309255e72915d4cbddceb435e13d81601755714e9fSE Android state->last_avrule_block = cur; 2310255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 2311255e72915d4cbddceb435e13d81601755714e9fSE Android } 2312255e72915d4cbddceb435e13d81601755714e9fSE Android state->last_base_avrule_block = state->last_avrule_block; 2313255e72915d4cbddceb435e13d81601755714e9fSE Android state->next_decl_id++; 2314255e72915d4cbddceb435e13d81601755714e9fSE Android 2315255e72915d4cbddceb435e13d81601755714e9fSE Android /* allocate the table mapping from base's decl_id to its 2316255e72915d4cbddceb435e13d81601755714e9fSE Android * avrule_decls and set the initial mappings */ 2317255e72915d4cbddceb435e13d81601755714e9fSE Android free(state->base->decl_val_to_struct); 2318255e72915d4cbddceb435e13d81601755714e9fSE Android if ((state->base->decl_val_to_struct = 2319255e72915d4cbddceb435e13d81601755714e9fSE Android calloc(state->next_decl_id + num_mod_decls, 2320255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(*(state->base->decl_val_to_struct)))) == NULL) { 2321255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2322255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2323255e72915d4cbddceb435e13d81601755714e9fSE Android } 2324255e72915d4cbddceb435e13d81601755714e9fSE Android /* This allocates the decl block to module mapping used for error reporting */ 2325255e72915d4cbddceb435e13d81601755714e9fSE Android if ((state->decl_to_mod = calloc(state->next_decl_id + num_mod_decls, 2326255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(*(state->decl_to_mod)))) == 2327255e72915d4cbddceb435e13d81601755714e9fSE Android NULL) { 2328255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2329255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2330255e72915d4cbddceb435e13d81601755714e9fSE Android } 2331255e72915d4cbddceb435e13d81601755714e9fSE Android cur = state->base->global; 2332255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur != NULL) { 2333255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl = cur->branch_list; 2334255e72915d4cbddceb435e13d81601755714e9fSE Android while (decl != NULL) { 2335255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->decl_val_to_struct[decl->decl_id - 1] = 2336255e72915d4cbddceb435e13d81601755714e9fSE Android decl; 2337255e72915d4cbddceb435e13d81601755714e9fSE Android state->decl_to_mod[decl->decl_id] = state->base; 2338255e72915d4cbddceb435e13d81601755714e9fSE Android decl = decl->next; 2339255e72915d4cbddceb435e13d81601755714e9fSE Android } 2340255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 2341255e72915d4cbddceb435e13d81601755714e9fSE Android } 2342255e72915d4cbddceb435e13d81601755714e9fSE Android 2343255e72915d4cbddceb435e13d81601755714e9fSE Android /* normalize conditionals within */ 2344255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_normalize(state->base) < 0) { 2345255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2346255e72915d4cbddceb435e13d81601755714e9fSE Android "Error while normalizing conditionals within the base module."); 2347255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2348255e72915d4cbddceb435e13d81601755714e9fSE Android } 2349255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2350255e72915d4cbddceb435e13d81601755714e9fSE Android} 2351255e72915d4cbddceb435e13d81601755714e9fSE Android 2352255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_role_attributes(hashtab_key_t key, hashtab_datum_t datum, 2353255e72915d4cbddceb435e13d81601755714e9fSE Android void * data) 2354255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2355255e72915d4cbddceb435e13d81601755714e9fSE Android char *id; 2356255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role, *sub_attr; 2357255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state; 2358255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 2359255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode; 2360255e72915d4cbddceb435e13d81601755714e9fSE Android 2361255e72915d4cbddceb435e13d81601755714e9fSE Android id = key; 2362255e72915d4cbddceb435e13d81601755714e9fSE Android role = (role_datum_t *)datum; 2363255e72915d4cbddceb435e13d81601755714e9fSE Android state = (link_state_t *)data; 2364255e72915d4cbddceb435e13d81601755714e9fSE Android 2365255e72915d4cbddceb435e13d81601755714e9fSE Android if (strcmp(id, OBJECT_R) == 0){ 2366255e72915d4cbddceb435e13d81601755714e9fSE Android /* object_r is never a role attribute by far */ 2367255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2368255e72915d4cbddceb435e13d81601755714e9fSE Android } 2369255e72915d4cbddceb435e13d81601755714e9fSE Android 2370255e72915d4cbddceb435e13d81601755714e9fSE Android if (role->flavor != ROLE_ATTRIB) 2371255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2372255e72915d4cbddceb435e13d81601755714e9fSE Android 2373255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 2374255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "expanding role attribute %s", id); 2375255e72915d4cbddceb435e13d81601755714e9fSE Android 2376255e72915d4cbddceb435e13d81601755714e9fSE Androidrestart: 2377255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&role->roles, rnode, i) { 2378255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, i)) { 2379255e72915d4cbddceb435e13d81601755714e9fSE Android sub_attr = state->base->role_val_to_struct[i]; 2380255e72915d4cbddceb435e13d81601755714e9fSE Android if (sub_attr->flavor != ROLE_ATTRIB) 2381255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2382255e72915d4cbddceb435e13d81601755714e9fSE Android 2383255e72915d4cbddceb435e13d81601755714e9fSE Android /* remove the sub role attribute from the parent 2384255e72915d4cbddceb435e13d81601755714e9fSE Android * role attribute's roles ebitmap */ 2385255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&role->roles, i, 0)) 2386255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2387255e72915d4cbddceb435e13d81601755714e9fSE Android 2388255e72915d4cbddceb435e13d81601755714e9fSE Android /* loop dependency of role attributes */ 2389255e72915d4cbddceb435e13d81601755714e9fSE Android if (sub_attr->s.value == role->s.value) 2390255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2391255e72915d4cbddceb435e13d81601755714e9fSE Android 2392255e72915d4cbddceb435e13d81601755714e9fSE Android /* now go on to expand a sub role attribute 2393255e72915d4cbddceb435e13d81601755714e9fSE Android * by escalating its roles ebitmap */ 2394255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&role->roles, &sub_attr->roles)) { 2395255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2396255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2397255e72915d4cbddceb435e13d81601755714e9fSE Android } 2398255e72915d4cbddceb435e13d81601755714e9fSE Android 2399255e72915d4cbddceb435e13d81601755714e9fSE Android /* sub_attr->roles may contain other role attributes, 2400255e72915d4cbddceb435e13d81601755714e9fSE Android * re-scan the parent role attribute's roles ebitmap */ 2401255e72915d4cbddceb435e13d81601755714e9fSE Android goto restart; 2402255e72915d4cbddceb435e13d81601755714e9fSE Android } 2403255e72915d4cbddceb435e13d81601755714e9fSE Android } 2404255e72915d4cbddceb435e13d81601755714e9fSE Android 2405255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2406255e72915d4cbddceb435e13d81601755714e9fSE Android} 2407255e72915d4cbddceb435e13d81601755714e9fSE Android 2408255e72915d4cbddceb435e13d81601755714e9fSE Android/* For any role attribute in a declaration's local symtab[SYM_ROLES] table, 2409255e72915d4cbddceb435e13d81601755714e9fSE Android * copy its roles ebitmap into its duplicate's in the base->p_roles.table. 2410255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2411255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int populate_decl_roleattributes(hashtab_key_t key, 2412255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, 2413255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 2414255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2415255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = key; 2416255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *decl_role, *base_role; 2417255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t *state = (link_state_t *)data; 2418255e72915d4cbddceb435e13d81601755714e9fSE Android 2419255e72915d4cbddceb435e13d81601755714e9fSE Android decl_role = (role_datum_t *)datum; 2420255e72915d4cbddceb435e13d81601755714e9fSE Android 2421255e72915d4cbddceb435e13d81601755714e9fSE Android if (strcmp(id, OBJECT_R) == 0) { 2422255e72915d4cbddceb435e13d81601755714e9fSE Android /* object_r is never a role attribute by far */ 2423255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2424255e72915d4cbddceb435e13d81601755714e9fSE Android } 2425255e72915d4cbddceb435e13d81601755714e9fSE Android 2426255e72915d4cbddceb435e13d81601755714e9fSE Android if (decl_role->flavor != ROLE_ATTRIB) 2427255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2428255e72915d4cbddceb435e13d81601755714e9fSE Android 2429255e72915d4cbddceb435e13d81601755714e9fSE Android base_role = (role_datum_t *)hashtab_search(state->base->p_roles.table, 2430255e72915d4cbddceb435e13d81601755714e9fSE Android id); 2431255e72915d4cbddceb435e13d81601755714e9fSE Android assert(base_role != NULL && base_role->flavor == ROLE_ATTRIB); 2432255e72915d4cbddceb435e13d81601755714e9fSE Android 2433255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&base_role->roles, &decl_role->roles)) { 2434255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2435255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2436255e72915d4cbddceb435e13d81601755714e9fSE Android } 2437255e72915d4cbddceb435e13d81601755714e9fSE Android 2438255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2439255e72915d4cbddceb435e13d81601755714e9fSE Android} 2440255e72915d4cbddceb435e13d81601755714e9fSE Android 2441255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int populate_roleattributes(link_state_t *state, policydb_t *pol) 2442255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2443255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *block; 2444255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl; 2445255e72915d4cbddceb435e13d81601755714e9fSE Android 2446255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 2447255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "Populating role-attribute relationship " 2448255e72915d4cbddceb435e13d81601755714e9fSE Android "from enabled declarations' local symtab."); 2449255e72915d4cbddceb435e13d81601755714e9fSE Android 2450255e72915d4cbddceb435e13d81601755714e9fSE Android /* Iterate through all of the blocks skipping the first(which is the 2451255e72915d4cbddceb435e13d81601755714e9fSE Android * global block, is required to be present and can't have an else). 2452255e72915d4cbddceb435e13d81601755714e9fSE Android * If the block is disabled or not having an enabled decl, skip it. 2453255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2454255e72915d4cbddceb435e13d81601755714e9fSE Android for (block = pol->global->next; block != NULL; block = block->next) 2455255e72915d4cbddceb435e13d81601755714e9fSE Android { 2456255e72915d4cbddceb435e13d81601755714e9fSE Android decl = block->enabled; 2457255e72915d4cbddceb435e13d81601755714e9fSE Android if (decl == NULL || decl->enabled == 0) 2458255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2459255e72915d4cbddceb435e13d81601755714e9fSE Android 2460255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(decl->symtab[SYM_ROLES].table, 2461255e72915d4cbddceb435e13d81601755714e9fSE Android populate_decl_roleattributes, state)) 2462255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2463255e72915d4cbddceb435e13d81601755714e9fSE Android } 2464255e72915d4cbddceb435e13d81601755714e9fSE Android 2465255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2466255e72915d4cbddceb435e13d81601755714e9fSE Android} 2467255e72915d4cbddceb435e13d81601755714e9fSE Android 2468255e72915d4cbddceb435e13d81601755714e9fSE Android/* Link a set of modules into a base module. This process is somewhat 2469255e72915d4cbddceb435e13d81601755714e9fSE Android * similar to an actual compiler: it requires a set of order dependent 2470255e72915d4cbddceb435e13d81601755714e9fSE Android * steps. The base and every module must have been indexed prior to 2471255e72915d4cbddceb435e13d81601755714e9fSE Android * calling this function. 2472255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2473255e72915d4cbddceb435e13d81601755714e9fSE Androidint link_modules(sepol_handle_t * handle, 2474255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * b, policydb_t ** mods, int len, int verbose) 2475255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2476255e72915d4cbddceb435e13d81601755714e9fSE Android int i, ret, retval = -1; 2477255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_t **modules = NULL; 2478255e72915d4cbddceb435e13d81601755714e9fSE Android link_state_t state; 2479255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t num_mod_decls = 0; 2480255e72915d4cbddceb435e13d81601755714e9fSE Android 2481255e72915d4cbddceb435e13d81601755714e9fSE Android memset(&state, 0, sizeof(state)); 2482255e72915d4cbddceb435e13d81601755714e9fSE Android state.base = b; 2483255e72915d4cbddceb435e13d81601755714e9fSE Android state.verbose = verbose; 2484255e72915d4cbddceb435e13d81601755714e9fSE Android state.handle = handle; 2485255e72915d4cbddceb435e13d81601755714e9fSE Android 2486255e72915d4cbddceb435e13d81601755714e9fSE Android if (b->policy_type != POLICY_BASE) { 2487255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, "Target of link was not a base policy."); 2488255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2489255e72915d4cbddceb435e13d81601755714e9fSE Android } 2490255e72915d4cbddceb435e13d81601755714e9fSE Android 2491255e72915d4cbddceb435e13d81601755714e9fSE Android /* first allocate some space to hold the maps from module 2492255e72915d4cbddceb435e13d81601755714e9fSE Android * symbol's value to the destination symbol value; then do 2493255e72915d4cbddceb435e13d81601755714e9fSE Android * other preparation work */ 2494255e72915d4cbddceb435e13d81601755714e9fSE Android if ((modules = 2495255e72915d4cbddceb435e13d81601755714e9fSE Android (policy_module_t **) calloc(len, sizeof(*modules))) == NULL) { 2496255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, "Out of memory!"); 2497255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2498255e72915d4cbddceb435e13d81601755714e9fSE Android } 2499255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < len; i++) { 2500255e72915d4cbddceb435e13d81601755714e9fSE Android if (mods[i]->policy_type != POLICY_MOD) { 2501255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, 2502255e72915d4cbddceb435e13d81601755714e9fSE Android "Tried to link in a policy that was not a module."); 2503255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2504255e72915d4cbddceb435e13d81601755714e9fSE Android } 2505255e72915d4cbddceb435e13d81601755714e9fSE Android 2506255e72915d4cbddceb435e13d81601755714e9fSE Android if (mods[i]->mls != b->mls) { 2507255e72915d4cbddceb435e13d81601755714e9fSE Android if (b->mls) 2508255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, 2509255e72915d4cbddceb435e13d81601755714e9fSE Android "Tried to link in a non-MLS module with an MLS base."); 2510255e72915d4cbddceb435e13d81601755714e9fSE Android else 2511255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, 2512255e72915d4cbddceb435e13d81601755714e9fSE Android "Tried to link in an MLS module with a non-MLS base."); 2513255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2514255e72915d4cbddceb435e13d81601755714e9fSE Android } 2515255e72915d4cbddceb435e13d81601755714e9fSE Android 2516255e72915d4cbddceb435e13d81601755714e9fSE Android if ((modules[i] = 2517255e72915d4cbddceb435e13d81601755714e9fSE Android (policy_module_t *) calloc(1, 2518255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(policy_module_t))) == 2519255e72915d4cbddceb435e13d81601755714e9fSE Android NULL) { 2520255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, "Out of memory!"); 2521255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2522255e72915d4cbddceb435e13d81601755714e9fSE Android } 2523255e72915d4cbddceb435e13d81601755714e9fSE Android modules[i]->policy = mods[i]; 2524255e72915d4cbddceb435e13d81601755714e9fSE Android if (prepare_module(&state, modules[i]) == -1) { 2525255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2526255e72915d4cbddceb435e13d81601755714e9fSE Android } 2527255e72915d4cbddceb435e13d81601755714e9fSE Android num_mod_decls += modules[i]->num_decls; 2528255e72915d4cbddceb435e13d81601755714e9fSE Android } 2529255e72915d4cbddceb435e13d81601755714e9fSE Android if (prepare_base(&state, num_mod_decls) == -1) { 2530255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2531255e72915d4cbddceb435e13d81601755714e9fSE Android } 2532255e72915d4cbddceb435e13d81601755714e9fSE Android 2533255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy all types, declared and required */ 2534255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < len; i++) { 2535255e72915d4cbddceb435e13d81601755714e9fSE Android state.cur = modules[i]; 2536255e72915d4cbddceb435e13d81601755714e9fSE Android state.cur_mod_name = modules[i]->policy->name; 2537255e72915d4cbddceb435e13d81601755714e9fSE Android ret = 2538255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_map(modules[i]->policy->p_types.table, 2539255e72915d4cbddceb435e13d81601755714e9fSE Android type_copy_callback, &state); 2540255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 2541255e72915d4cbddceb435e13d81601755714e9fSE Android retval = ret; 2542255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2543255e72915d4cbddceb435e13d81601755714e9fSE Android } 2544255e72915d4cbddceb435e13d81601755714e9fSE Android } 2545255e72915d4cbddceb435e13d81601755714e9fSE Android 2546255e72915d4cbddceb435e13d81601755714e9fSE Android /* then copy everything else, including aliases, and fixup attributes */ 2547255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < len; i++) { 2548255e72915d4cbddceb435e13d81601755714e9fSE Android state.cur = modules[i]; 2549255e72915d4cbddceb435e13d81601755714e9fSE Android state.cur_mod_name = modules[i]->policy->name; 2550255e72915d4cbddceb435e13d81601755714e9fSE Android ret = 2551255e72915d4cbddceb435e13d81601755714e9fSE Android copy_identifiers(&state, modules[i]->policy->symtab, NULL); 2552255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 2553255e72915d4cbddceb435e13d81601755714e9fSE Android retval = ret; 2554255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2555255e72915d4cbddceb435e13d81601755714e9fSE Android } 2556255e72915d4cbddceb435e13d81601755714e9fSE Android } 2557255e72915d4cbddceb435e13d81601755714e9fSE Android 2558255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_index_others(state.handle, state.base, 0)) { 2559255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, "Error while indexing others"); 2560255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2561255e72915d4cbddceb435e13d81601755714e9fSE Android } 2562255e72915d4cbddceb435e13d81601755714e9fSE Android 2563255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy and remap the module's data over to base */ 2564255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < len; i++) { 2565255e72915d4cbddceb435e13d81601755714e9fSE Android state.cur = modules[i]; 2566255e72915d4cbddceb435e13d81601755714e9fSE Android ret = copy_module(&state, modules[i]); 2567255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 2568255e72915d4cbddceb435e13d81601755714e9fSE Android retval = ret; 2569255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2570255e72915d4cbddceb435e13d81601755714e9fSE Android } 2571255e72915d4cbddceb435e13d81601755714e9fSE Android } 2572255e72915d4cbddceb435e13d81601755714e9fSE Android 2573255e72915d4cbddceb435e13d81601755714e9fSE Android /* re-index base, for symbols were added to symbol tables */ 2574255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_index_classes(state.base)) { 2575255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, "Error while indexing classes"); 2576255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2577255e72915d4cbddceb435e13d81601755714e9fSE Android } 2578255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_index_others(state.handle, state.base, 0)) { 2579255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state.handle, "Error while indexing others"); 2580255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2581255e72915d4cbddceb435e13d81601755714e9fSE Android } 2582255e72915d4cbddceb435e13d81601755714e9fSE Android 2583255e72915d4cbddceb435e13d81601755714e9fSE Android if (enable_avrules(&state, state.base)) { 2584255e72915d4cbddceb435e13d81601755714e9fSE Android retval = SEPOL_EREQ; 2585255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2586255e72915d4cbddceb435e13d81601755714e9fSE Android } 2587255e72915d4cbddceb435e13d81601755714e9fSE Android 2588255e72915d4cbddceb435e13d81601755714e9fSE Android /* Now that all role attribute's roles ebitmap have been settled, 2589255e72915d4cbddceb435e13d81601755714e9fSE Android * escalate sub role attribute's roles ebitmap into that of parent. 2590255e72915d4cbddceb435e13d81601755714e9fSE Android * 2591255e72915d4cbddceb435e13d81601755714e9fSE Android * First, since some role-attribute relationships could be recorded 2592255e72915d4cbddceb435e13d81601755714e9fSE Android * in some decl's local symtab(see get_local_role()), we need to 2593255e72915d4cbddceb435e13d81601755714e9fSE Android * populate them up to the base.p_roles table. */ 2594255e72915d4cbddceb435e13d81601755714e9fSE Android if (populate_roleattributes(&state, state.base)) { 2595255e72915d4cbddceb435e13d81601755714e9fSE Android retval = SEPOL_EREQ; 2596255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2597255e72915d4cbddceb435e13d81601755714e9fSE Android } 2598255e72915d4cbddceb435e13d81601755714e9fSE Android 2599255e72915d4cbddceb435e13d81601755714e9fSE Android /* Now do the escalation. */ 2600255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_roles.table, expand_role_attributes, 2601255e72915d4cbddceb435e13d81601755714e9fSE Android &state)) 2602255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2603255e72915d4cbddceb435e13d81601755714e9fSE Android 2604255e72915d4cbddceb435e13d81601755714e9fSE Android retval = 0; 2605255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 2606255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; modules != NULL && i < len; i++) { 2607255e72915d4cbddceb435e13d81601755714e9fSE Android policy_module_destroy(modules[i]); 2608255e72915d4cbddceb435e13d81601755714e9fSE Android } 2609255e72915d4cbddceb435e13d81601755714e9fSE Android free(modules); 2610255e72915d4cbddceb435e13d81601755714e9fSE Android free(state.decl_to_mod); 2611255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 2612255e72915d4cbddceb435e13d81601755714e9fSE Android} 2613