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