1255e72915d4cbddceb435e13d81601755714e9fSE Android/* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 2255e72915d4cbddceb435e13d81601755714e9fSE Android * Jason Tang <jtang@tresys.com> 3255e72915d4cbddceb435e13d81601755714e9fSE Android * Joshua Brindle <jbrindle@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 "context.h" 24255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 25255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/conditional.h> 26255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/hashtab.h> 27255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/expand.h> 28255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/hierarchy.h> 29255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/avrule_block.h> 30255e72915d4cbddceb435e13d81601755714e9fSE Android 31255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 32255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdarg.h> 33255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdio.h> 34255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h> 35255e72915d4cbddceb435e13d81601755714e9fSE Android#include <assert.h> 36255e72915d4cbddceb435e13d81601755714e9fSE Android 37255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 38255e72915d4cbddceb435e13d81601755714e9fSE Android#include "private.h" 39255e72915d4cbddceb435e13d81601755714e9fSE Android 40255e72915d4cbddceb435e13d81601755714e9fSE Androidtypedef struct expand_state { 41255e72915d4cbddceb435e13d81601755714e9fSE Android int verbose; 42255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *typemap; 43255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *boolmap; 44255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *rolemap; 45255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t *usermap; 46255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *base; 47255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *out; 48255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_handle_t *handle; 49255e72915d4cbddceb435e13d81601755714e9fSE Android int expand_neverallow; 50255e72915d4cbddceb435e13d81601755714e9fSE Android} expand_state_t; 51255e72915d4cbddceb435e13d81601755714e9fSE Android 52dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystruct linear_probe { 53dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley filename_trans_t **table; /* filename_trans chunks with same stype */ 54dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley filename_trans_t **ends; /* pointers to ends of **table chunks */ 55dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley uint32_t length; /* length of the table */ 56dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley}; 57dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 58dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic int linear_probe_create(struct linear_probe *probe, uint32_t length) 59dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 60dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley probe->table = calloc(length, sizeof(*probe->table)); 61dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (probe->table == NULL) 62dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return -1; 63dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 64dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley probe->ends = calloc(length, sizeof(*probe->ends)); 65dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (probe->ends == NULL) 66dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return -1; 67dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 68dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley probe->length = length; 69dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 70dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return 0; 71dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 72dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 73dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic void linear_probe_destroy(struct linear_probe *probe) 74dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 75dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (probe->length == 0) 76dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return; 77dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 78dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(probe->table); 79dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley free(probe->ends); 80dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley memset(probe, 0, sizeof(*probe)); 81dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 82dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 83dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic void linear_probe_insert(struct linear_probe *probe, uint32_t key, 84dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley filename_trans_t *data) 85dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 86dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley assert(probe->length > key); 87dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 88dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (probe->table[key] != NULL) { 89dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley data->next = probe->table[key]; 90dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley probe->table[key] = data; 91dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } else { 92dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley probe->table[key] = probe->ends[key] = data; 93dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 94dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 95dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 96dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic filename_trans_t *linear_probe_find(struct linear_probe *probe, uint32_t key) 97dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 98dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley assert(probe->length > key); 99dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 100dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return probe->table[key]; 101dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 102dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 103dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley/* Returns all chunks stored in the *probe as single-linked list */ 104dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalleystatic filename_trans_t *linear_probe_dump(struct linear_probe *probe, 105dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley filename_trans_t **endp) 106dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley{ 107dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley uint32_t i; 108dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley filename_trans_t *result = NULL; 109dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley filename_trans_t *end = NULL; 110dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 111dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley for (i = 0; i < probe->length; i++) { 112dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (probe->table[i] != NULL) { 113dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (end == NULL) 114dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley end = probe->ends[i]; 115dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley probe->ends[i]->next = result; 116dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley result = probe->table[i]; 117dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley probe->table[i] = probe->ends[i] = NULL; 118dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 119dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 120dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 121dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* Incoherent result and end pointers indicates bug */ 122dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley assert((result != NULL && end != NULL) || (result == NULL && end == NULL)); 123dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 124dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley *endp = end; 125dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return result; 126dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley} 127dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 128255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic void expand_state_init(expand_state_t * state) 129255e72915d4cbddceb435e13d81601755714e9fSE Android{ 130255e72915d4cbddceb435e13d81601755714e9fSE Android memset(state, 0, sizeof(expand_state_t)); 131255e72915d4cbddceb435e13d81601755714e9fSE Android} 132255e72915d4cbddceb435e13d81601755714e9fSE Android 133255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map) 134255e72915d4cbddceb435e13d81601755714e9fSE Android{ 135255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 136255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *tnode; 137255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(dst); 138255e72915d4cbddceb435e13d81601755714e9fSE Android 139255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(src, tnode, i) { 140255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, i)) 141255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 142255e72915d4cbddceb435e13d81601755714e9fSE Android if (!map[i]) 143255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 144255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(dst, map[i] - 1, 1)) 145255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 146255e72915d4cbddceb435e13d81601755714e9fSE Android } 147255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 148255e72915d4cbddceb435e13d81601755714e9fSE Android} 149255e72915d4cbddceb435e13d81601755714e9fSE Android 150255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 151255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 152255e72915d4cbddceb435e13d81601755714e9fSE Android{ 153255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 154255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 155255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type, *new_type; 156255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 157255e72915d4cbddceb435e13d81601755714e9fSE Android 158255e72915d4cbddceb435e13d81601755714e9fSE Android id = (char *)key; 159255e72915d4cbddceb435e13d81601755714e9fSE Android type = (type_datum_t *) datum; 160255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 161255e72915d4cbddceb435e13d81601755714e9fSE Android 162255e72915d4cbddceb435e13d81601755714e9fSE Android if ((type->flavor == TYPE_TYPE && !type->primary) 163255e72915d4cbddceb435e13d81601755714e9fSE Android || type->flavor == TYPE_ALIAS) { 164255e72915d4cbddceb435e13d81601755714e9fSE Android /* aliases are handled later */ 165255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 166255e72915d4cbddceb435e13d81601755714e9fSE Android } 167255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_TYPES)) { 168255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 169255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 170255e72915d4cbddceb435e13d81601755714e9fSE Android } 171255e72915d4cbddceb435e13d81601755714e9fSE Android 172255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 173255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying type or attribute %s", id); 174255e72915d4cbddceb435e13d81601755714e9fSE Android 175255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 176255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_id == NULL) { 177255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 178255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 179255e72915d4cbddceb435e13d81601755714e9fSE Android } 180255e72915d4cbddceb435e13d81601755714e9fSE Android 181255e72915d4cbddceb435e13d81601755714e9fSE Android new_type = (type_datum_t *) malloc(sizeof(type_datum_t)); 182255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_type) { 183255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 184255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 185255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ENOMEM; 186255e72915d4cbddceb435e13d81601755714e9fSE Android } 187255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_type, 0, sizeof(type_datum_t)); 188255e72915d4cbddceb435e13d81601755714e9fSE Android 189255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flavor = type->flavor; 190255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->flags = type->flags; 191255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->s.value = ++state->out->p_types.nprim; 192255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_type->s.value > UINT16_MAX) { 193255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 194255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_type); 195255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "type space overflow"); 196255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 197255e72915d4cbddceb435e13d81601755714e9fSE Android } 198255e72915d4cbddceb435e13d81601755714e9fSE Android new_type->primary = 1; 199255e72915d4cbddceb435e13d81601755714e9fSE Android state->typemap[type->s.value - 1] = new_type->s.value; 200255e72915d4cbddceb435e13d81601755714e9fSE Android 201255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->out->p_types.table, 202255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 203255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_type); 204255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 205255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 206255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_type); 207255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 208255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 209255e72915d4cbddceb435e13d81601755714e9fSE Android } 210255e72915d4cbddceb435e13d81601755714e9fSE Android 211255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_type->flags & TYPE_FLAGS_PERMISSIVE) 212255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&state->out->permissive_map, new_type->s.value, 1)) { 213255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!\n"); 214255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 215255e72915d4cbddceb435e13d81601755714e9fSE Android } 216255e72915d4cbddceb435e13d81601755714e9fSE Android 217255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 218255e72915d4cbddceb435e13d81601755714e9fSE Android} 219255e72915d4cbddceb435e13d81601755714e9fSE Android 220255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int attr_convert_callback(hashtab_key_t key, hashtab_datum_t datum, 221255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 222255e72915d4cbddceb435e13d81601755714e9fSE Android{ 223255e72915d4cbddceb435e13d81601755714e9fSE Android char *id; 224255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type, *new_type; 225255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 226255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t tmp_union; 227255e72915d4cbddceb435e13d81601755714e9fSE Android 228255e72915d4cbddceb435e13d81601755714e9fSE Android id = (char *)key; 229255e72915d4cbddceb435e13d81601755714e9fSE Android type = (type_datum_t *) datum; 230255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 231255e72915d4cbddceb435e13d81601755714e9fSE Android 232255e72915d4cbddceb435e13d81601755714e9fSE Android if (type->flavor != TYPE_ATTRIB) 233255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 234255e72915d4cbddceb435e13d81601755714e9fSE Android 235255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_TYPES)) { 236255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 237255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 238255e72915d4cbddceb435e13d81601755714e9fSE Android } 239255e72915d4cbddceb435e13d81601755714e9fSE Android 240255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 241255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "converting attribute %s", id); 242255e72915d4cbddceb435e13d81601755714e9fSE Android 243255e72915d4cbddceb435e13d81601755714e9fSE Android new_type = hashtab_search(state->out->p_types.table, id); 244255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_type) { 245255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "attribute %s vanished!", id); 246255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 247255e72915d4cbddceb435e13d81601755714e9fSE Android } 248255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&type->types, &tmp_union, state->typemap)) { 249255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "out of memory"); 250255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 251255e72915d4cbddceb435e13d81601755714e9fSE Android } 252255e72915d4cbddceb435e13d81601755714e9fSE Android 253255e72915d4cbddceb435e13d81601755714e9fSE Android /* then union tmp_union onto &new_type->types */ 254255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&new_type->types, &tmp_union)) { 255255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 256255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 257255e72915d4cbddceb435e13d81601755714e9fSE Android } 258255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp_union); 259255e72915d4cbddceb435e13d81601755714e9fSE Android 260255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 261255e72915d4cbddceb435e13d81601755714e9fSE Android} 262255e72915d4cbddceb435e13d81601755714e9fSE Android 263255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int perm_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 264255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 265255e72915d4cbddceb435e13d81601755714e9fSE Android{ 266255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 267255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 268255e72915d4cbddceb435e13d81601755714e9fSE Android symtab_t *s; 269255e72915d4cbddceb435e13d81601755714e9fSE Android perm_datum_t *perm, *new_perm; 270255e72915d4cbddceb435e13d81601755714e9fSE Android 271255e72915d4cbddceb435e13d81601755714e9fSE Android id = key; 272255e72915d4cbddceb435e13d81601755714e9fSE Android perm = (perm_datum_t *) datum; 273255e72915d4cbddceb435e13d81601755714e9fSE Android s = (symtab_t *) data; 274255e72915d4cbddceb435e13d81601755714e9fSE Android 275255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 276255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_perm) { 277255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 278255e72915d4cbddceb435e13d81601755714e9fSE Android } 279255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_perm, 0, sizeof(perm_datum_t)); 280255e72915d4cbddceb435e13d81601755714e9fSE Android 281255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 282255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) { 283255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_perm); 284255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 285255e72915d4cbddceb435e13d81601755714e9fSE Android } 286255e72915d4cbddceb435e13d81601755714e9fSE Android 287255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm->s.value = perm->s.value; 288255e72915d4cbddceb435e13d81601755714e9fSE Android s->nprim++; 289255e72915d4cbddceb435e13d81601755714e9fSE Android 290255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(s->table, new_id, (hashtab_datum_t *) new_perm); 291255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 292255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 293255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_perm); 294255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 295255e72915d4cbddceb435e13d81601755714e9fSE Android } 296255e72915d4cbddceb435e13d81601755714e9fSE Android 297255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 298255e72915d4cbddceb435e13d81601755714e9fSE Android} 299255e72915d4cbddceb435e13d81601755714e9fSE Android 300255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 301255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 302255e72915d4cbddceb435e13d81601755714e9fSE Android{ 303255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 304255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 305255e72915d4cbddceb435e13d81601755714e9fSE Android common_datum_t *common, *new_common; 306255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 307255e72915d4cbddceb435e13d81601755714e9fSE Android 308255e72915d4cbddceb435e13d81601755714e9fSE Android id = (char *)key; 309255e72915d4cbddceb435e13d81601755714e9fSE Android common = (common_datum_t *) datum; 310255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 311255e72915d4cbddceb435e13d81601755714e9fSE Android 312255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 313255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying common %s", id); 314255e72915d4cbddceb435e13d81601755714e9fSE Android 315255e72915d4cbddceb435e13d81601755714e9fSE Android new_common = (common_datum_t *) malloc(sizeof(common_datum_t)); 316255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_common) { 317255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 318255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 319255e72915d4cbddceb435e13d81601755714e9fSE Android } 320255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_common, 0, sizeof(common_datum_t)); 321255e72915d4cbddceb435e13d81601755714e9fSE Android if (symtab_init(&new_common->permissions, PERM_SYMTAB_SIZE)) { 322255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 323255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_common); 324255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 325255e72915d4cbddceb435e13d81601755714e9fSE Android } 326255e72915d4cbddceb435e13d81601755714e9fSE Android 327255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 328255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) { 329255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 330dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* free memory created by symtab_init first, then free new_common */ 331b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu symtab_destroy(&new_common->permissions); 332255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_common); 333255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 334255e72915d4cbddceb435e13d81601755714e9fSE Android } 335255e72915d4cbddceb435e13d81601755714e9fSE Android 336255e72915d4cbddceb435e13d81601755714e9fSE Android new_common->s.value = common->s.value; 337255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_commons.nprim++; 338255e72915d4cbddceb435e13d81601755714e9fSE Android 339255e72915d4cbddceb435e13d81601755714e9fSE Android ret = 340255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_insert(state->out->p_commons.table, new_id, 341255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t *) new_common); 342255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 343255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 344255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_common); 345255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 346255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 347255e72915d4cbddceb435e13d81601755714e9fSE Android } 348255e72915d4cbddceb435e13d81601755714e9fSE Android 349255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 350255e72915d4cbddceb435e13d81601755714e9fSE Android (common->permissions.table, perm_copy_callback, 351255e72915d4cbddceb435e13d81601755714e9fSE Android &new_common->permissions)) { 352255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 353255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 354255e72915d4cbddceb435e13d81601755714e9fSE Android } 355255e72915d4cbddceb435e13d81601755714e9fSE Android 356255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 357255e72915d4cbddceb435e13d81601755714e9fSE Android} 358255e72915d4cbddceb435e13d81601755714e9fSE Android 359255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int constraint_node_clone(constraint_node_t ** dst, 360255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_node_t * src, 361255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t * state) 362255e72915d4cbddceb435e13d81601755714e9fSE Android{ 363255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_node_t *new_con = NULL, *last_new_con = NULL; 364255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_expr_t *new_expr = NULL; 365255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = NULL; 366255e72915d4cbddceb435e13d81601755714e9fSE Android while (src != NULL) { 367255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_expr_t *expr, *expr_l = NULL; 368255e72915d4cbddceb435e13d81601755714e9fSE Android new_con = 369255e72915d4cbddceb435e13d81601755714e9fSE Android (constraint_node_t *) malloc(sizeof(constraint_node_t)); 370255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_con) { 371255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 372255e72915d4cbddceb435e13d81601755714e9fSE Android } 373255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_con, 0, sizeof(constraint_node_t)); 374255e72915d4cbddceb435e13d81601755714e9fSE Android new_con->permissions = src->permissions; 375255e72915d4cbddceb435e13d81601755714e9fSE Android for (expr = src->expr; expr; expr = expr->next) { 376255e72915d4cbddceb435e13d81601755714e9fSE Android if ((new_expr = calloc(1, sizeof(*new_expr))) == NULL) { 377255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 378255e72915d4cbddceb435e13d81601755714e9fSE Android } 379255e72915d4cbddceb435e13d81601755714e9fSE Android if (constraint_expr_init(new_expr) == -1) { 380255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 381255e72915d4cbddceb435e13d81601755714e9fSE Android } 382255e72915d4cbddceb435e13d81601755714e9fSE Android new_expr->expr_type = expr->expr_type; 383255e72915d4cbddceb435e13d81601755714e9fSE Android new_expr->attr = expr->attr; 384255e72915d4cbddceb435e13d81601755714e9fSE Android new_expr->op = expr->op; 385255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_expr->expr_type == CEXPR_NAMES) { 386255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_expr->attr & CEXPR_TYPE) { 387dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 388dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Copy over constraint policy source types and/or 389dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * attributes for sepol_compute_av_reason_buffer(3) 390dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * so that utilities can analyse constraint errors. 391dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 392dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (map_ebitmap(&expr->type_names->types, 393dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley &new_expr->type_names->types, 394dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley state->typemap)) { 395dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(NULL, "Failed to map type_names->types"); 396dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto out_of_mem; 397dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 398255e72915d4cbddceb435e13d81601755714e9fSE Android /* Type sets require expansion and conversion. */ 399255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set(state->out, 400255e72915d4cbddceb435e13d81601755714e9fSE Android state-> 401255e72915d4cbddceb435e13d81601755714e9fSE Android typemap, 402255e72915d4cbddceb435e13d81601755714e9fSE Android expr-> 403255e72915d4cbddceb435e13d81601755714e9fSE Android type_names, 404255e72915d4cbddceb435e13d81601755714e9fSE Android &new_expr-> 405255e72915d4cbddceb435e13d81601755714e9fSE Android names, 1)) { 406255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 407255e72915d4cbddceb435e13d81601755714e9fSE Android } 408255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (new_expr->attr & CEXPR_ROLE) { 409255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&expr->names, &new_expr->names, state->rolemap)) { 410255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 411255e72915d4cbddceb435e13d81601755714e9fSE Android } 412255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (new_expr->attr & CEXPR_USER) { 413255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&expr->names, &new_expr->names, state->usermap)) { 414255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 415255e72915d4cbddceb435e13d81601755714e9fSE Android } 416255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 417255e72915d4cbddceb435e13d81601755714e9fSE Android /* Other kinds of sets do not. */ 418255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&new_expr->names, 419255e72915d4cbddceb435e13d81601755714e9fSE Android &expr->names)) { 420255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 421255e72915d4cbddceb435e13d81601755714e9fSE Android } 422255e72915d4cbddceb435e13d81601755714e9fSE Android } 423255e72915d4cbddceb435e13d81601755714e9fSE Android } 424255e72915d4cbddceb435e13d81601755714e9fSE Android if (expr_l) { 425255e72915d4cbddceb435e13d81601755714e9fSE Android expr_l->next = new_expr; 426255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 427255e72915d4cbddceb435e13d81601755714e9fSE Android new_con->expr = new_expr; 428255e72915d4cbddceb435e13d81601755714e9fSE Android } 429255e72915d4cbddceb435e13d81601755714e9fSE Android expr_l = new_expr; 430255e72915d4cbddceb435e13d81601755714e9fSE Android new_expr = NULL; 431255e72915d4cbddceb435e13d81601755714e9fSE Android } 432255e72915d4cbddceb435e13d81601755714e9fSE Android if (last_new_con == NULL) { 433255e72915d4cbddceb435e13d81601755714e9fSE Android *dst = new_con; 434255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 435255e72915d4cbddceb435e13d81601755714e9fSE Android last_new_con->next = new_con; 436255e72915d4cbddceb435e13d81601755714e9fSE Android } 437255e72915d4cbddceb435e13d81601755714e9fSE Android last_new_con = new_con; 438255e72915d4cbddceb435e13d81601755714e9fSE Android src = src->next; 439255e72915d4cbddceb435e13d81601755714e9fSE Android } 440255e72915d4cbddceb435e13d81601755714e9fSE Android 441255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 442255e72915d4cbddceb435e13d81601755714e9fSE Android out_of_mem: 443255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 444255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_con) 445255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_con); 446255e72915d4cbddceb435e13d81601755714e9fSE Android constraint_expr_destroy(new_expr); 447255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 448255e72915d4cbddceb435e13d81601755714e9fSE Android} 449255e72915d4cbddceb435e13d81601755714e9fSE Android 4504ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalleystatic int class_copy_default_new_object(expand_state_t *state, 4514ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley class_datum_t *olddatum, 4524ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley class_datum_t *newdatum) 4534ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley{ 4544ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (olddatum->default_user) { 4554ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { 4564ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ERR(state->handle, "Found conflicting default user definitions"); 4574ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return SEPOL_ENOTSUP; 4584ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 4594ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley newdatum->default_user = olddatum->default_user; 4604ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley 4614ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 4624ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (olddatum->default_role) { 4634ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { 4644ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ERR(state->handle, "Found conflicting default role definitions"); 4654ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return SEPOL_ENOTSUP; 4664ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 4674ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley newdatum->default_role = olddatum->default_role; 4684ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 469dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (olddatum->default_type) { 470dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (newdatum->default_type && olddatum->default_type != newdatum->default_type) { 471dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(state->handle, "Found conflicting default type definitions"); 472dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return SEPOL_ENOTSUP; 473dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 474dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley newdatum->default_type = olddatum->default_type; 475dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 4764ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (olddatum->default_range) { 4774ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { 4784ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ERR(state->handle, "Found conflicting default range definitions"); 4794ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return SEPOL_ENOTSUP; 4804ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 4814ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley newdatum->default_range = olddatum->default_range; 4824ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 4834ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return 0; 4844ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley} 4854ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley 486255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 487255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 488255e72915d4cbddceb435e13d81601755714e9fSE Android{ 489255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 490255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 491255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *class, *new_class; 492255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 493255e72915d4cbddceb435e13d81601755714e9fSE Android 494255e72915d4cbddceb435e13d81601755714e9fSE Android id = (char *)key; 495255e72915d4cbddceb435e13d81601755714e9fSE Android class = (class_datum_t *) datum; 496255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 497255e72915d4cbddceb435e13d81601755714e9fSE Android 498255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_CLASSES)) { 499255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 500255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 501255e72915d4cbddceb435e13d81601755714e9fSE Android } 502255e72915d4cbddceb435e13d81601755714e9fSE Android 503255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 504255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying class %s", id); 505255e72915d4cbddceb435e13d81601755714e9fSE Android 506255e72915d4cbddceb435e13d81601755714e9fSE Android new_class = (class_datum_t *) malloc(sizeof(class_datum_t)); 507255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_class) { 508255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 509255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 510255e72915d4cbddceb435e13d81601755714e9fSE Android } 511255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_class, 0, sizeof(class_datum_t)); 512255e72915d4cbddceb435e13d81601755714e9fSE Android if (symtab_init(&new_class->permissions, PERM_SYMTAB_SIZE)) { 513255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 514255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_class); 515255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 516255e72915d4cbddceb435e13d81601755714e9fSE Android } 517255e72915d4cbddceb435e13d81601755714e9fSE Android 518255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->s.value = class->s.value; 519255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_classes.nprim++; 520255e72915d4cbddceb435e13d81601755714e9fSE Android 5214ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ret = class_copy_default_new_object(state, class, new_class); 5224ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (ret) { 5234ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley free(new_class); 5244ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return ret; 5254ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 5264ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley 527255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 528255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) { 529255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 530255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_class); 531255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 532255e72915d4cbddceb435e13d81601755714e9fSE Android } 533255e72915d4cbddceb435e13d81601755714e9fSE Android 534255e72915d4cbddceb435e13d81601755714e9fSE Android ret = 535255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_insert(state->out->p_classes.table, new_id, 536255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t *) new_class); 537255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 538255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 539255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_class); 540255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 541255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 542255e72915d4cbddceb435e13d81601755714e9fSE Android } 543255e72915d4cbddceb435e13d81601755714e9fSE Android 544255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 545255e72915d4cbddceb435e13d81601755714e9fSE Android (class->permissions.table, perm_copy_callback, 546255e72915d4cbddceb435e13d81601755714e9fSE Android &new_class->permissions)) { 547255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 548255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 549255e72915d4cbddceb435e13d81601755714e9fSE Android } 550255e72915d4cbddceb435e13d81601755714e9fSE Android 551255e72915d4cbddceb435e13d81601755714e9fSE Android if (class->comkey) { 552255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->comkey = strdup(class->comkey); 553255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_class->comkey) { 554255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 555255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 556255e72915d4cbddceb435e13d81601755714e9fSE Android } 557255e72915d4cbddceb435e13d81601755714e9fSE Android 558255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->comdatum = 559255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_search(state->out->p_commons.table, 560255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->comkey); 561255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_class->comdatum) { 562255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "could not find common datum %s", 563255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->comkey); 564255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 565255e72915d4cbddceb435e13d81601755714e9fSE Android } 566255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->permissions.nprim += 567255e72915d4cbddceb435e13d81601755714e9fSE Android new_class->comdatum->permissions.nprim; 568255e72915d4cbddceb435e13d81601755714e9fSE Android } 569255e72915d4cbddceb435e13d81601755714e9fSE Android 570255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 571255e72915d4cbddceb435e13d81601755714e9fSE Android} 572255e72915d4cbddceb435e13d81601755714e9fSE Android 573255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int constraint_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 574255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 575255e72915d4cbddceb435e13d81601755714e9fSE Android{ 576255e72915d4cbddceb435e13d81601755714e9fSE Android char *id; 577255e72915d4cbddceb435e13d81601755714e9fSE Android class_datum_t *class, *new_class; 578255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 579255e72915d4cbddceb435e13d81601755714e9fSE Android 580255e72915d4cbddceb435e13d81601755714e9fSE Android id = (char *)key; 581255e72915d4cbddceb435e13d81601755714e9fSE Android class = (class_datum_t *) datum; 582255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 583255e72915d4cbddceb435e13d81601755714e9fSE Android 584255e72915d4cbddceb435e13d81601755714e9fSE Android new_class = hashtab_search(state->out->p_classes.table, id); 585255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_class) { 586255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "class %s vanished", id); 587255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 588255e72915d4cbddceb435e13d81601755714e9fSE Android } 589255e72915d4cbddceb435e13d81601755714e9fSE Android 590255e72915d4cbddceb435e13d81601755714e9fSE Android /* constraints */ 591255e72915d4cbddceb435e13d81601755714e9fSE Android if (constraint_node_clone 592255e72915d4cbddceb435e13d81601755714e9fSE Android (&new_class->constraints, class->constraints, state) == -1 593255e72915d4cbddceb435e13d81601755714e9fSE Android || constraint_node_clone(&new_class->validatetrans, 594255e72915d4cbddceb435e13d81601755714e9fSE Android class->validatetrans, state) == -1) { 595255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 596255e72915d4cbddceb435e13d81601755714e9fSE Android } 597255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 598255e72915d4cbddceb435e13d81601755714e9fSE Android} 599255e72915d4cbddceb435e13d81601755714e9fSE Android 600255e72915d4cbddceb435e13d81601755714e9fSE Android/* 601255e72915d4cbddceb435e13d81601755714e9fSE Android * The boundaries have to be copied after the types/roles/users are copied, 602255e72915d4cbddceb435e13d81601755714e9fSE Android * because it refers hashtab to lookup destinated objects. 603255e72915d4cbddceb435e13d81601755714e9fSE Android */ 604255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_bounds_copy_callback(hashtab_key_t key, 605255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, void *data) 606255e72915d4cbddceb435e13d81601755714e9fSE Android{ 607255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state = (expand_state_t *) data; 608255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type = (type_datum_t *) datum; 609255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *dest; 610255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t bounds_val; 611255e72915d4cbddceb435e13d81601755714e9fSE Android 612255e72915d4cbddceb435e13d81601755714e9fSE Android if (!type->bounds) 613255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 614255e72915d4cbddceb435e13d81601755714e9fSE Android 615255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled((char *)key, state->base, SYM_TYPES)) 616255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 617255e72915d4cbddceb435e13d81601755714e9fSE Android 618255e72915d4cbddceb435e13d81601755714e9fSE Android bounds_val = state->typemap[type->bounds - 1]; 619255e72915d4cbddceb435e13d81601755714e9fSE Android 620255e72915d4cbddceb435e13d81601755714e9fSE Android dest = hashtab_search(state->out->p_types.table, (char *)key); 621255e72915d4cbddceb435e13d81601755714e9fSE Android if (!dest) { 622255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Type lookup failed for %s", (char *)key); 623255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 624255e72915d4cbddceb435e13d81601755714e9fSE Android } 625255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest->bounds != 0 && dest->bounds != bounds_val) { 626255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Inconsistent boundary for %s", (char *)key); 627255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 628255e72915d4cbddceb435e13d81601755714e9fSE Android } 629255e72915d4cbddceb435e13d81601755714e9fSE Android dest->bounds = bounds_val; 630255e72915d4cbddceb435e13d81601755714e9fSE Android 631255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 632255e72915d4cbddceb435e13d81601755714e9fSE Android} 633255e72915d4cbddceb435e13d81601755714e9fSE Android 634255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_bounds_copy_callback(hashtab_key_t key, 635255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, void *data) 636255e72915d4cbddceb435e13d81601755714e9fSE Android{ 637255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state = (expand_state_t *) data; 638255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role = (role_datum_t *) datum; 639255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *dest; 640255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t bounds_val; 641255e72915d4cbddceb435e13d81601755714e9fSE Android 642255e72915d4cbddceb435e13d81601755714e9fSE Android if (!role->bounds) 643255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 644255e72915d4cbddceb435e13d81601755714e9fSE Android 645255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled((char *)key, state->base, SYM_ROLES)) 646255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 647255e72915d4cbddceb435e13d81601755714e9fSE Android 648255e72915d4cbddceb435e13d81601755714e9fSE Android bounds_val = state->rolemap[role->bounds - 1]; 649255e72915d4cbddceb435e13d81601755714e9fSE Android 650255e72915d4cbddceb435e13d81601755714e9fSE Android dest = hashtab_search(state->out->p_roles.table, (char *)key); 651255e72915d4cbddceb435e13d81601755714e9fSE Android if (!dest) { 652255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Role lookup failed for %s", (char *)key); 653255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 654255e72915d4cbddceb435e13d81601755714e9fSE Android } 655255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest->bounds != 0 && dest->bounds != bounds_val) { 656255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Inconsistent boundary for %s", (char *)key); 657255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 658255e72915d4cbddceb435e13d81601755714e9fSE Android } 659255e72915d4cbddceb435e13d81601755714e9fSE Android dest->bounds = bounds_val; 660255e72915d4cbddceb435e13d81601755714e9fSE Android 661255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 662255e72915d4cbddceb435e13d81601755714e9fSE Android} 663255e72915d4cbddceb435e13d81601755714e9fSE Android 664255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int user_bounds_copy_callback(hashtab_key_t key, 665255e72915d4cbddceb435e13d81601755714e9fSE Android hashtab_datum_t datum, void *data) 666255e72915d4cbddceb435e13d81601755714e9fSE Android{ 667255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state = (expand_state_t *) data; 668255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *user = (user_datum_t *) datum; 669255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *dest; 670255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t bounds_val; 671255e72915d4cbddceb435e13d81601755714e9fSE Android 672255e72915d4cbddceb435e13d81601755714e9fSE Android if (!user->bounds) 673255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 674255e72915d4cbddceb435e13d81601755714e9fSE Android 675255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled((char *)key, state->base, SYM_USERS)) 676255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 677255e72915d4cbddceb435e13d81601755714e9fSE Android 678255e72915d4cbddceb435e13d81601755714e9fSE Android bounds_val = state->usermap[user->bounds - 1]; 679255e72915d4cbddceb435e13d81601755714e9fSE Android 680255e72915d4cbddceb435e13d81601755714e9fSE Android dest = hashtab_search(state->out->p_users.table, (char *)key); 681255e72915d4cbddceb435e13d81601755714e9fSE Android if (!dest) { 682255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "User lookup failed for %s", (char *)key); 683255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 684255e72915d4cbddceb435e13d81601755714e9fSE Android } 685255e72915d4cbddceb435e13d81601755714e9fSE Android if (dest->bounds != 0 && dest->bounds != bounds_val) { 686255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Inconsistent boundary for %s", (char *)key); 687255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 688255e72915d4cbddceb435e13d81601755714e9fSE Android } 689255e72915d4cbddceb435e13d81601755714e9fSE Android dest->bounds = bounds_val; 690255e72915d4cbddceb435e13d81601755714e9fSE Android 691255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 692255e72915d4cbddceb435e13d81601755714e9fSE Android} 693255e72915d4cbddceb435e13d81601755714e9fSE Android 694255e72915d4cbddceb435e13d81601755714e9fSE Android/* The aliases have to be copied after the types and attributes to be certain that 695255e72915d4cbddceb435e13d81601755714e9fSE Android * the out symbol table will have the type that the alias refers. Otherwise, we 696255e72915d4cbddceb435e13d81601755714e9fSE Android * won't be able to find the type value for the alias. We can't depend on the 697255e72915d4cbddceb435e13d81601755714e9fSE Android * declaration ordering because of the hash table. 698255e72915d4cbddceb435e13d81601755714e9fSE Android */ 699255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 700255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 701255e72915d4cbddceb435e13d81601755714e9fSE Android{ 702255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 703255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 704255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *alias, *new_alias; 705255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 706255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t prival; 707255e72915d4cbddceb435e13d81601755714e9fSE Android 708255e72915d4cbddceb435e13d81601755714e9fSE Android id = (char *)key; 709255e72915d4cbddceb435e13d81601755714e9fSE Android alias = (type_datum_t *) datum; 710255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 711255e72915d4cbddceb435e13d81601755714e9fSE Android 712255e72915d4cbddceb435e13d81601755714e9fSE Android /* ignore regular types */ 713255e72915d4cbddceb435e13d81601755714e9fSE Android if (alias->flavor == TYPE_TYPE && alias->primary) 714255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 715255e72915d4cbddceb435e13d81601755714e9fSE Android 716255e72915d4cbddceb435e13d81601755714e9fSE Android /* ignore attributes */ 717255e72915d4cbddceb435e13d81601755714e9fSE Android if (alias->flavor == TYPE_ATTRIB) 718255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 719255e72915d4cbddceb435e13d81601755714e9fSE Android 720255e72915d4cbddceb435e13d81601755714e9fSE Android if (alias->flavor == TYPE_ALIAS) 721255e72915d4cbddceb435e13d81601755714e9fSE Android prival = alias->primary; 722255e72915d4cbddceb435e13d81601755714e9fSE Android else 723255e72915d4cbddceb435e13d81601755714e9fSE Android prival = alias->s.value; 724255e72915d4cbddceb435e13d81601755714e9fSE Android 725255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(state->base->p_type_val_to_name[prival - 1], 726255e72915d4cbddceb435e13d81601755714e9fSE Android state->base, SYM_TYPES)) { 727255e72915d4cbddceb435e13d81601755714e9fSE Android /* The primary type for this alias is not enabled, the alias 728255e72915d4cbddceb435e13d81601755714e9fSE Android * shouldn't be either */ 729255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 730255e72915d4cbddceb435e13d81601755714e9fSE Android } 731255e72915d4cbddceb435e13d81601755714e9fSE Android 732255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 733255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying alias %s", id); 734255e72915d4cbddceb435e13d81601755714e9fSE Android 735255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 736255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) { 737255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 738255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 739255e72915d4cbddceb435e13d81601755714e9fSE Android } 740255e72915d4cbddceb435e13d81601755714e9fSE Android 741255e72915d4cbddceb435e13d81601755714e9fSE Android new_alias = (type_datum_t *) malloc(sizeof(type_datum_t)); 742255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_alias) { 743255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 744255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 745255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_ENOMEM; 746255e72915d4cbddceb435e13d81601755714e9fSE Android } 747255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_alias, 0, sizeof(type_datum_t)); 748255e72915d4cbddceb435e13d81601755714e9fSE Android if (alias->flavor == TYPE_TYPE) 749255e72915d4cbddceb435e13d81601755714e9fSE Android new_alias->s.value = state->typemap[alias->s.value - 1]; 750255e72915d4cbddceb435e13d81601755714e9fSE Android else if (alias->flavor == TYPE_ALIAS) 751255e72915d4cbddceb435e13d81601755714e9fSE Android new_alias->s.value = state->typemap[alias->primary - 1]; 752255e72915d4cbddceb435e13d81601755714e9fSE Android else 753255e72915d4cbddceb435e13d81601755714e9fSE Android assert(0); /* unreachable */ 754255e72915d4cbddceb435e13d81601755714e9fSE Android 755255e72915d4cbddceb435e13d81601755714e9fSE Android new_alias->flags = alias->flags; 756255e72915d4cbddceb435e13d81601755714e9fSE Android 757255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->out->p_types.table, 758255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 759255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_alias); 760255e72915d4cbddceb435e13d81601755714e9fSE Android 761255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 762255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 763255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_alias); 764255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 765255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 766255e72915d4cbddceb435e13d81601755714e9fSE Android } 767255e72915d4cbddceb435e13d81601755714e9fSE Android 768255e72915d4cbddceb435e13d81601755714e9fSE Android state->typemap[alias->s.value - 1] = new_alias->s.value; 769255e72915d4cbddceb435e13d81601755714e9fSE Android 770255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_alias->flags & TYPE_FLAGS_PERMISSIVE) 771255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&state->out->permissive_map, new_alias->s.value, 1)) { 772255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 773255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 774255e72915d4cbddceb435e13d81601755714e9fSE Android } 775255e72915d4cbddceb435e13d81601755714e9fSE Android 776255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 777255e72915d4cbddceb435e13d81601755714e9fSE Android} 778255e72915d4cbddceb435e13d81601755714e9fSE Android 779255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_remap_dominates(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *data) 780255e72915d4cbddceb435e13d81601755714e9fSE Android{ 781255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t mapped_roles; 782255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role = (role_datum_t *) datum; 783255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state = (expand_state_t *) data; 784255e72915d4cbddceb435e13d81601755714e9fSE Android 785255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&role->dominates, &mapped_roles, state->rolemap)) 786255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 787255e72915d4cbddceb435e13d81601755714e9fSE Android 788255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&role->dominates); 789255e72915d4cbddceb435e13d81601755714e9fSE Android 790255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&role->dominates, &mapped_roles)) 791255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 792255e72915d4cbddceb435e13d81601755714e9fSE Android 793255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&mapped_roles); 794255e72915d4cbddceb435e13d81601755714e9fSE Android 795255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 796255e72915d4cbddceb435e13d81601755714e9fSE Android} 797255e72915d4cbddceb435e13d81601755714e9fSE Android 798255e72915d4cbddceb435e13d81601755714e9fSE Android/* For the role attribute in the base module, escalate its counterpart's 799255e72915d4cbddceb435e13d81601755714e9fSE Android * types.types ebitmap in the out module to the counterparts of all the 800255e72915d4cbddceb435e13d81601755714e9fSE Android * regular role that belongs to the current role attribute. Note, must be 801255e72915d4cbddceb435e13d81601755714e9fSE Android * invoked after role_copy_callback so that state->rolemap is available. 802255e72915d4cbddceb435e13d81601755714e9fSE Android */ 803255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 804255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 805255e72915d4cbddceb435e13d81601755714e9fSE Android{ 806255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *base_reg_role_id; 807255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role, *new_role, *regular_role; 808255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 809255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode; 810255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 811255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t mapped_roles; 812255e72915d4cbddceb435e13d81601755714e9fSE Android 813255e72915d4cbddceb435e13d81601755714e9fSE Android id = key; 814255e72915d4cbddceb435e13d81601755714e9fSE Android role = (role_datum_t *)datum; 815255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *)data; 816255e72915d4cbddceb435e13d81601755714e9fSE Android 817255e72915d4cbddceb435e13d81601755714e9fSE Android if (strcmp(id, OBJECT_R) == 0) { 818255e72915d4cbddceb435e13d81601755714e9fSE Android /* object_r is never a role attribute by far */ 819255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 820255e72915d4cbddceb435e13d81601755714e9fSE Android } 821255e72915d4cbddceb435e13d81601755714e9fSE Android 8224ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (!is_id_enabled(id, state->base, SYM_ROLES)) { 8234ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley /* identifier's scope is not enabled */ 8244ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return 0; 8254ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 8264ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley 827255e72915d4cbddceb435e13d81601755714e9fSE Android if (role->flavor != ROLE_ATTRIB) 828255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 829255e72915d4cbddceb435e13d81601755714e9fSE Android 830255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 831255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "fixing role attribute %s", id); 832255e72915d4cbddceb435e13d81601755714e9fSE Android 833255e72915d4cbddceb435e13d81601755714e9fSE Android new_role = 834255e72915d4cbddceb435e13d81601755714e9fSE Android (role_datum_t *)hashtab_search(state->out->p_roles.table, id); 835255e72915d4cbddceb435e13d81601755714e9fSE Android 836255e72915d4cbddceb435e13d81601755714e9fSE Android assert(new_role != NULL && new_role->flavor == ROLE_ATTRIB); 837255e72915d4cbddceb435e13d81601755714e9fSE Android 838255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&mapped_roles); 839255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&role->roles, &mapped_roles, state->rolemap)) 840255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 841255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&new_role->roles, &mapped_roles)) { 842255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 843255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&mapped_roles); 844255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 845255e72915d4cbddceb435e13d81601755714e9fSE Android } 846255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&mapped_roles); 847255e72915d4cbddceb435e13d81601755714e9fSE Android 848255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&role->roles, rnode, i) { 849255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, i)) { 850255e72915d4cbddceb435e13d81601755714e9fSE Android /* take advantage of sym_val_to_name[] 851255e72915d4cbddceb435e13d81601755714e9fSE Android * of the base module */ 852255e72915d4cbddceb435e13d81601755714e9fSE Android base_reg_role_id = state->base->p_role_val_to_name[i]; 853255e72915d4cbddceb435e13d81601755714e9fSE Android regular_role = (role_datum_t *)hashtab_search( 854255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_roles.table, 855255e72915d4cbddceb435e13d81601755714e9fSE Android base_reg_role_id); 856255e72915d4cbddceb435e13d81601755714e9fSE Android assert(regular_role != NULL && 857255e72915d4cbddceb435e13d81601755714e9fSE Android regular_role->flavor == ROLE_ROLE); 858255e72915d4cbddceb435e13d81601755714e9fSE Android 859255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(®ular_role->types.types, 860255e72915d4cbddceb435e13d81601755714e9fSE Android &new_role->types.types)) { 861255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 862255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 863255e72915d4cbddceb435e13d81601755714e9fSE Android } 864255e72915d4cbddceb435e13d81601755714e9fSE Android } 865255e72915d4cbddceb435e13d81601755714e9fSE Android } 866255e72915d4cbddceb435e13d81601755714e9fSE Android 867255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 868255e72915d4cbddceb435e13d81601755714e9fSE Android} 869255e72915d4cbddceb435e13d81601755714e9fSE Android 870255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 871255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 872255e72915d4cbddceb435e13d81601755714e9fSE Android{ 873255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 874255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 875255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role; 876255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *new_role; 877255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 878255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t tmp_union_types; 879255e72915d4cbddceb435e13d81601755714e9fSE Android 880255e72915d4cbddceb435e13d81601755714e9fSE Android id = key; 881255e72915d4cbddceb435e13d81601755714e9fSE Android role = (role_datum_t *) datum; 882255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 883255e72915d4cbddceb435e13d81601755714e9fSE Android 884255e72915d4cbddceb435e13d81601755714e9fSE Android if (strcmp(id, OBJECT_R) == 0) { 885255e72915d4cbddceb435e13d81601755714e9fSE Android /* object_r is always value 1 */ 886255e72915d4cbddceb435e13d81601755714e9fSE Android state->rolemap[role->s.value - 1] = 1; 887255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 888255e72915d4cbddceb435e13d81601755714e9fSE Android } 889255e72915d4cbddceb435e13d81601755714e9fSE Android 890255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_ROLES)) { 891255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 892255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 893255e72915d4cbddceb435e13d81601755714e9fSE Android } 894255e72915d4cbddceb435e13d81601755714e9fSE Android 895255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 896255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying role %s", id); 897255e72915d4cbddceb435e13d81601755714e9fSE Android 898255e72915d4cbddceb435e13d81601755714e9fSE Android new_role = 899255e72915d4cbddceb435e13d81601755714e9fSE Android (role_datum_t *) hashtab_search(state->out->p_roles.table, id); 900255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_role) { 901255e72915d4cbddceb435e13d81601755714e9fSE Android new_role = (role_datum_t *) malloc(sizeof(role_datum_t)); 902255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_role) { 903255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 904255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 905255e72915d4cbddceb435e13d81601755714e9fSE Android } 906255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_role, 0, sizeof(role_datum_t)); 907255e72915d4cbddceb435e13d81601755714e9fSE Android 908255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 909255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) { 910255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 911b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu free(new_role); 912255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 913255e72915d4cbddceb435e13d81601755714e9fSE Android } 914255e72915d4cbddceb435e13d81601755714e9fSE Android 915255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_roles.nprim++; 916255e72915d4cbddceb435e13d81601755714e9fSE Android new_role->flavor = role->flavor; 917255e72915d4cbddceb435e13d81601755714e9fSE Android new_role->s.value = state->out->p_roles.nprim; 918255e72915d4cbddceb435e13d81601755714e9fSE Android state->rolemap[role->s.value - 1] = new_role->s.value; 919255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->out->p_roles.table, 920255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 921255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_role); 922255e72915d4cbddceb435e13d81601755714e9fSE Android 923255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 924255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 925255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_role); 926255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 927255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 928255e72915d4cbddceb435e13d81601755714e9fSE Android } 929255e72915d4cbddceb435e13d81601755714e9fSE Android } 930255e72915d4cbddceb435e13d81601755714e9fSE Android 931255e72915d4cbddceb435e13d81601755714e9fSE Android /* The dominates bitmap is going to be wrong for the moment, 932255e72915d4cbddceb435e13d81601755714e9fSE Android * we'll come back later and remap them, after we are sure all 933255e72915d4cbddceb435e13d81601755714e9fSE Android * the roles have been added */ 934255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&new_role->dominates, &role->dominates)) { 935255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 936255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 937255e72915d4cbddceb435e13d81601755714e9fSE Android } 938255e72915d4cbddceb435e13d81601755714e9fSE Android 939255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&tmp_union_types); 940255e72915d4cbddceb435e13d81601755714e9fSE Android 941255e72915d4cbddceb435e13d81601755714e9fSE Android /* convert types in the role datum in the global symtab */ 942255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set 943255e72915d4cbddceb435e13d81601755714e9fSE Android (state->out, state->typemap, &role->types, &tmp_union_types, 1)) { 944255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp_union_types); 945255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 946255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 947255e72915d4cbddceb435e13d81601755714e9fSE Android } 948255e72915d4cbddceb435e13d81601755714e9fSE Android 949255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&new_role->types.types, &tmp_union_types)) { 950255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 951255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp_union_types); 952255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 953255e72915d4cbddceb435e13d81601755714e9fSE Android } 954255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp_union_types); 955255e72915d4cbddceb435e13d81601755714e9fSE Android 956255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 957255e72915d4cbddceb435e13d81601755714e9fSE Android} 958255e72915d4cbddceb435e13d81601755714e9fSE Android 959255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l, 960255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * p, sepol_handle_t * h) 961255e72915d4cbddceb435e13d81601755714e9fSE Android{ 962255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_cat_t *cat; 963255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_t *levdatum; 964255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 965255e72915d4cbddceb435e13d81601755714e9fSE Android 966255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_init(l); 967255e72915d4cbddceb435e13d81601755714e9fSE Android 968255e72915d4cbddceb435e13d81601755714e9fSE Android if (!p->mls) 969255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 970255e72915d4cbddceb435e13d81601755714e9fSE Android 971255e72915d4cbddceb435e13d81601755714e9fSE Android /* Required not declared. */ 972255e72915d4cbddceb435e13d81601755714e9fSE Android if (!sl->sens) 973255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 974255e72915d4cbddceb435e13d81601755714e9fSE Android 975255e72915d4cbddceb435e13d81601755714e9fSE Android l->sens = sl->sens; 976255e72915d4cbddceb435e13d81601755714e9fSE Android levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, 977dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley p->p_sens_val_to_name[l->sens - 1]); 978dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!levdatum) { 979dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(h, "%s: Impossible situation found, nothing in p_levels.table.\n", 980dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley __func__); 981dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley errno = ENOENT; 982dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return -1; 983dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 984255e72915d4cbddceb435e13d81601755714e9fSE Android for (cat = sl->cat; cat; cat = cat->next) { 985255e72915d4cbddceb435e13d81601755714e9fSE Android if (cat->low > cat->high) { 986255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(h, "Category range is not valid %s.%s", 987255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_cat_val_to_name[cat->low - 1], 988255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_cat_val_to_name[cat->high - 1]); 989255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 990255e72915d4cbddceb435e13d81601755714e9fSE Android } 991255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = cat->low - 1; i < cat->high; i++) { 992255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 993255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(h, "Category %s can not be associate with " 994255e72915d4cbddceb435e13d81601755714e9fSE Android "level %s", 995255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_cat_val_to_name[i], 996255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_sens_val_to_name[l->sens - 1]); 997255e72915d4cbddceb435e13d81601755714e9fSE Android } 998255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&l->cat, i, 1)) { 999255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(h, "Out of memory!"); 1000255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1001255e72915d4cbddceb435e13d81601755714e9fSE Android } 1002255e72915d4cbddceb435e13d81601755714e9fSE Android } 1003255e72915d4cbddceb435e13d81601755714e9fSE Android } 1004255e72915d4cbddceb435e13d81601755714e9fSE Android 1005255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1006255e72915d4cbddceb435e13d81601755714e9fSE Android} 1007255e72915d4cbddceb435e13d81601755714e9fSE Android 1008255e72915d4cbddceb435e13d81601755714e9fSE Androidint mls_semantic_range_expand(mls_semantic_range_t * sr, mls_range_t * r, 1009255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * p, sepol_handle_t * h) 1010255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1011255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_level_expand(&sr->level[0], &r->level[0], p, h) < 0) 1012255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1013255e72915d4cbddceb435e13d81601755714e9fSE Android 1014255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_level_expand(&sr->level[1], &r->level[1], p, h) < 0) { 1015255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_level_destroy(&sr->level[0]); 1016255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1017255e72915d4cbddceb435e13d81601755714e9fSE Android } 1018255e72915d4cbddceb435e13d81601755714e9fSE Android 1019255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mls_level_dom(&r->level[1], &r->level[0])) { 1020255e72915d4cbddceb435e13d81601755714e9fSE Android mls_range_destroy(r); 1021255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(h, "MLS range high level does not dominate low level"); 1022255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1023255e72915d4cbddceb435e13d81601755714e9fSE Android } 1024255e72915d4cbddceb435e13d81601755714e9fSE Android 1025255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1026255e72915d4cbddceb435e13d81601755714e9fSE Android} 1027255e72915d4cbddceb435e13d81601755714e9fSE Android 1028255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1029255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1030255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1031255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 1032255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 1033255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *user; 1034255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_t *new_user; 1035255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 1036255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t tmp_union; 1037255e72915d4cbddceb435e13d81601755714e9fSE Android 1038255e72915d4cbddceb435e13d81601755714e9fSE Android id = key; 1039255e72915d4cbddceb435e13d81601755714e9fSE Android user = (user_datum_t *) datum; 1040255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 1041255e72915d4cbddceb435e13d81601755714e9fSE Android 1042255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_USERS)) { 1043255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 1044255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1045255e72915d4cbddceb435e13d81601755714e9fSE Android } 1046255e72915d4cbddceb435e13d81601755714e9fSE Android 1047255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 1048255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying user %s", id); 1049255e72915d4cbddceb435e13d81601755714e9fSE Android 1050255e72915d4cbddceb435e13d81601755714e9fSE Android new_user = 1051255e72915d4cbddceb435e13d81601755714e9fSE Android (user_datum_t *) hashtab_search(state->out->p_users.table, id); 1052255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_user) { 1053255e72915d4cbddceb435e13d81601755714e9fSE Android new_user = (user_datum_t *) malloc(sizeof(user_datum_t)); 1054255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_user) { 1055255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1056255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1057255e72915d4cbddceb435e13d81601755714e9fSE Android } 1058255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_user, 0, sizeof(user_datum_t)); 1059255e72915d4cbddceb435e13d81601755714e9fSE Android 1060255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_users.nprim++; 1061255e72915d4cbddceb435e13d81601755714e9fSE Android new_user->s.value = state->out->p_users.nprim; 1062255e72915d4cbddceb435e13d81601755714e9fSE Android state->usermap[user->s.value - 1] = new_user->s.value; 1063255e72915d4cbddceb435e13d81601755714e9fSE Android 1064255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 1065255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) { 1066255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1067b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu free(new_user); 1068255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1069255e72915d4cbddceb435e13d81601755714e9fSE Android } 1070255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->out->p_users.table, 1071255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 1072255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_user); 1073255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 1074255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 1075255e72915d4cbddceb435e13d81601755714e9fSE Android user_datum_destroy(new_user); 1076255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_user); 1077255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 1078255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1079255e72915d4cbddceb435e13d81601755714e9fSE Android } 1080255e72915d4cbddceb435e13d81601755714e9fSE Android 1081255e72915d4cbddceb435e13d81601755714e9fSE Android /* expand the semantic MLS info */ 1082255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_range_expand(&user->range, 1083255e72915d4cbddceb435e13d81601755714e9fSE Android &new_user->exp_range, 1084255e72915d4cbddceb435e13d81601755714e9fSE Android state->out, state->handle)) { 1085255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1086255e72915d4cbddceb435e13d81601755714e9fSE Android } 1087255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_level_expand(&user->dfltlevel, 1088255e72915d4cbddceb435e13d81601755714e9fSE Android &new_user->exp_dfltlevel, 1089255e72915d4cbddceb435e13d81601755714e9fSE Android state->out, state->handle)) { 1090255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1091255e72915d4cbddceb435e13d81601755714e9fSE Android } 1092255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mls_level_between(&new_user->exp_dfltlevel, 1093255e72915d4cbddceb435e13d81601755714e9fSE Android &new_user->exp_range.level[0], 1094255e72915d4cbddceb435e13d81601755714e9fSE Android &new_user->exp_range.level[1])) { 1095255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "default level not within user " 1096255e72915d4cbddceb435e13d81601755714e9fSE Android "range"); 1097255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1098255e72915d4cbddceb435e13d81601755714e9fSE Android } 1099255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1100255e72915d4cbddceb435e13d81601755714e9fSE Android /* require that the MLS info match */ 1101255e72915d4cbddceb435e13d81601755714e9fSE Android mls_range_t tmp_range; 1102255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_t tmp_level; 1103255e72915d4cbddceb435e13d81601755714e9fSE Android 1104255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_range_expand(&user->range, &tmp_range, 1105255e72915d4cbddceb435e13d81601755714e9fSE Android state->out, state->handle)) { 1106255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1107255e72915d4cbddceb435e13d81601755714e9fSE Android } 1108255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_level_expand(&user->dfltlevel, &tmp_level, 1109255e72915d4cbddceb435e13d81601755714e9fSE Android state->out, state->handle)) { 1110255e72915d4cbddceb435e13d81601755714e9fSE Android mls_range_destroy(&tmp_range); 1111255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1112255e72915d4cbddceb435e13d81601755714e9fSE Android } 1113255e72915d4cbddceb435e13d81601755714e9fSE Android if (!mls_range_eq(&new_user->exp_range, &tmp_range) || 1114255e72915d4cbddceb435e13d81601755714e9fSE Android !mls_level_eq(&new_user->exp_dfltlevel, &tmp_level)) { 1115255e72915d4cbddceb435e13d81601755714e9fSE Android mls_range_destroy(&tmp_range); 1116255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_destroy(&tmp_level); 1117255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1118255e72915d4cbddceb435e13d81601755714e9fSE Android } 1119255e72915d4cbddceb435e13d81601755714e9fSE Android mls_range_destroy(&tmp_range); 1120255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_destroy(&tmp_level); 1121255e72915d4cbddceb435e13d81601755714e9fSE Android } 1122255e72915d4cbddceb435e13d81601755714e9fSE Android 1123255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&tmp_union); 1124255e72915d4cbddceb435e13d81601755714e9fSE Android 1125255e72915d4cbddceb435e13d81601755714e9fSE Android /* get global roles for this user */ 1126255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_expand(&user->roles, &tmp_union, state->out, state->base, state->rolemap)) { 1127255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1128255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp_union); 1129255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1130255e72915d4cbddceb435e13d81601755714e9fSE Android } 1131255e72915d4cbddceb435e13d81601755714e9fSE Android 1132255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&new_user->roles.roles, &tmp_union)) { 1133255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1134255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp_union); 1135255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1136255e72915d4cbddceb435e13d81601755714e9fSE Android } 1137255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&tmp_union); 1138255e72915d4cbddceb435e13d81601755714e9fSE Android 1139255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1140255e72915d4cbddceb435e13d81601755714e9fSE Android} 1141255e72915d4cbddceb435e13d81601755714e9fSE Android 1142255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1143255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1144255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1145255e72915d4cbddceb435e13d81601755714e9fSE Android int ret; 1146255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state; 1147255e72915d4cbddceb435e13d81601755714e9fSE Android cond_bool_datum_t *bool, *new_bool; 1148255e72915d4cbddceb435e13d81601755714e9fSE Android char *id, *new_id; 1149255e72915d4cbddceb435e13d81601755714e9fSE Android 1150255e72915d4cbddceb435e13d81601755714e9fSE Android id = key; 1151255e72915d4cbddceb435e13d81601755714e9fSE Android bool = (cond_bool_datum_t *) datum; 1152255e72915d4cbddceb435e13d81601755714e9fSE Android state = (expand_state_t *) data; 1153255e72915d4cbddceb435e13d81601755714e9fSE Android 1154255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_BOOLS)) { 1155255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 1156255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1157255e72915d4cbddceb435e13d81601755714e9fSE Android } 1158255e72915d4cbddceb435e13d81601755714e9fSE Android 1159fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (bool->flags & COND_BOOL_FLAGS_TUNABLE) { 1160fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* Skip tunables */ 1161fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley return 0; 1162fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 1163fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 1164255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 1165255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying boolean %s", id); 1166255e72915d4cbddceb435e13d81601755714e9fSE Android 1167255e72915d4cbddceb435e13d81601755714e9fSE Android new_bool = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 1168255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_bool) { 1169255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1170255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1171255e72915d4cbddceb435e13d81601755714e9fSE Android } 1172255e72915d4cbddceb435e13d81601755714e9fSE Android 1173255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 1174255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) { 1175255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1176255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_bool); 1177255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1178255e72915d4cbddceb435e13d81601755714e9fSE Android } 1179255e72915d4cbddceb435e13d81601755714e9fSE Android 1180255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_bools.nprim++; 1181255e72915d4cbddceb435e13d81601755714e9fSE Android new_bool->s.value = state->out->p_bools.nprim; 1182255e72915d4cbddceb435e13d81601755714e9fSE Android 1183255e72915d4cbddceb435e13d81601755714e9fSE Android ret = hashtab_insert(state->out->p_bools.table, 1184255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 1185255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_bool); 1186255e72915d4cbddceb435e13d81601755714e9fSE Android if (ret) { 1187255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "hashtab overflow"); 1188255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_bool); 1189255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 1190255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1191255e72915d4cbddceb435e13d81601755714e9fSE Android } 1192255e72915d4cbddceb435e13d81601755714e9fSE Android 1193255e72915d4cbddceb435e13d81601755714e9fSE Android state->boolmap[bool->s.value - 1] = new_bool->s.value; 1194255e72915d4cbddceb435e13d81601755714e9fSE Android 1195255e72915d4cbddceb435e13d81601755714e9fSE Android new_bool->state = bool->state; 1196fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley new_bool->flags = bool->flags; 1197255e72915d4cbddceb435e13d81601755714e9fSE Android 1198255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1199255e72915d4cbddceb435e13d81601755714e9fSE Android} 1200255e72915d4cbddceb435e13d81601755714e9fSE Android 1201255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1202255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1203255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1204255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state = (expand_state_t *) data; 1205255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_t *level = (level_datum_t *) datum, *new_level = NULL; 1206255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = (char *)key, *new_id = NULL; 1207255e72915d4cbddceb435e13d81601755714e9fSE Android 1208255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_LEVELS)) { 1209255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 1210255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1211255e72915d4cbddceb435e13d81601755714e9fSE Android } 1212255e72915d4cbddceb435e13d81601755714e9fSE Android 1213255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 1214255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying sensitivity level %s", id); 1215255e72915d4cbddceb435e13d81601755714e9fSE Android 1216255e72915d4cbddceb435e13d81601755714e9fSE Android new_level = (level_datum_t *) malloc(sizeof(level_datum_t)); 1217255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_level) 1218255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1219255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_init(new_level); 1220255e72915d4cbddceb435e13d81601755714e9fSE Android new_level->level = (mls_level_t *) malloc(sizeof(mls_level_t)); 1221255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_level->level) 1222255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1223255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_init(new_level->level); 1224255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 1225255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) 1226255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1227255e72915d4cbddceb435e13d81601755714e9fSE Android 1228255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_level_cpy(new_level->level, level->level)) { 1229255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1230255e72915d4cbddceb435e13d81601755714e9fSE Android } 1231255e72915d4cbddceb435e13d81601755714e9fSE Android new_level->isalias = level->isalias; 1232255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_levels.nprim++; 1233255e72915d4cbddceb435e13d81601755714e9fSE Android 1234255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_insert(state->out->p_levels.table, 1235255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, 1236255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_datum_t) new_level)) { 1237255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1238255e72915d4cbddceb435e13d81601755714e9fSE Android } 1239255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1240255e72915d4cbddceb435e13d81601755714e9fSE Android 1241255e72915d4cbddceb435e13d81601755714e9fSE Android out_of_mem: 1242255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1243255e72915d4cbddceb435e13d81601755714e9fSE Android if (new_level != NULL && new_level->level != NULL) { 1244255e72915d4cbddceb435e13d81601755714e9fSE Android mls_level_destroy(new_level->level); 1245255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_level->level); 1246255e72915d4cbddceb435e13d81601755714e9fSE Android } 1247255e72915d4cbddceb435e13d81601755714e9fSE Android level_datum_destroy(new_level); 1248255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_level); 1249255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 1250255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1251255e72915d4cbddceb435e13d81601755714e9fSE Android} 1252255e72915d4cbddceb435e13d81601755714e9fSE Android 1253255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int cats_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1254255e72915d4cbddceb435e13d81601755714e9fSE Android void *data) 1255255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1256255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state = (expand_state_t *) data; 1257255e72915d4cbddceb435e13d81601755714e9fSE Android cat_datum_t *cat = (cat_datum_t *) datum, *new_cat = NULL; 1258255e72915d4cbddceb435e13d81601755714e9fSE Android char *id = (char *)key, *new_id = NULL; 1259255e72915d4cbddceb435e13d81601755714e9fSE Android 1260255e72915d4cbddceb435e13d81601755714e9fSE Android if (!is_id_enabled(id, state->base, SYM_CATS)) { 1261255e72915d4cbddceb435e13d81601755714e9fSE Android /* identifier's scope is not enabled */ 1262255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1263255e72915d4cbddceb435e13d81601755714e9fSE Android } 1264255e72915d4cbddceb435e13d81601755714e9fSE Android 1265255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 1266255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "copying category attribute %s", id); 1267255e72915d4cbddceb435e13d81601755714e9fSE Android 1268255e72915d4cbddceb435e13d81601755714e9fSE Android new_cat = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 1269255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_cat) 1270255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1271255e72915d4cbddceb435e13d81601755714e9fSE Android cat_datum_init(new_cat); 1272255e72915d4cbddceb435e13d81601755714e9fSE Android new_id = strdup(id); 1273255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_id) 1274255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1275255e72915d4cbddceb435e13d81601755714e9fSE Android 1276255e72915d4cbddceb435e13d81601755714e9fSE Android new_cat->s.value = cat->s.value; 1277255e72915d4cbddceb435e13d81601755714e9fSE Android new_cat->isalias = cat->isalias; 1278255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_cats.nprim++; 1279255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_insert(state->out->p_cats.table, 1280255e72915d4cbddceb435e13d81601755714e9fSE Android (hashtab_key_t) new_id, (hashtab_datum_t) new_cat)) { 1281255e72915d4cbddceb435e13d81601755714e9fSE Android goto out_of_mem; 1282255e72915d4cbddceb435e13d81601755714e9fSE Android } 1283255e72915d4cbddceb435e13d81601755714e9fSE Android 1284255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1285255e72915d4cbddceb435e13d81601755714e9fSE Android 1286255e72915d4cbddceb435e13d81601755714e9fSE Android out_of_mem: 1287255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1288255e72915d4cbddceb435e13d81601755714e9fSE Android cat_datum_destroy(new_cat); 1289255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_cat); 1290255e72915d4cbddceb435e13d81601755714e9fSE Android free(new_id); 1291255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1292255e72915d4cbddceb435e13d81601755714e9fSE Android} 1293255e72915d4cbddceb435e13d81601755714e9fSE Android 1294255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_role_allows(expand_state_t * state, role_allow_rule_t * rules) 1295255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1296255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 1297255e72915d4cbddceb435e13d81601755714e9fSE Android role_allow_t *cur_allow, *n, *l; 1298255e72915d4cbddceb435e13d81601755714e9fSE Android role_allow_rule_t *cur; 1299255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t roles, new_roles; 1300255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *snode, *tnode; 1301255e72915d4cbddceb435e13d81601755714e9fSE Android 1302255e72915d4cbddceb435e13d81601755714e9fSE Android /* start at the end of the list */ 1303255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = state->out->role_allow; l && l->next; l = l->next) ; 1304255e72915d4cbddceb435e13d81601755714e9fSE Android 1305255e72915d4cbddceb435e13d81601755714e9fSE Android cur = rules; 1306255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1307255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&roles); 1308255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&new_roles); 1309255e72915d4cbddceb435e13d81601755714e9fSE Android 1310255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) { 1311255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1312255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1313255e72915d4cbddceb435e13d81601755714e9fSE Android } 1314255e72915d4cbddceb435e13d81601755714e9fSE Android 1315255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_expand(&cur->new_roles, &new_roles, state->out, state->base, state->rolemap)) { 1316255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1317255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1318255e72915d4cbddceb435e13d81601755714e9fSE Android } 1319255e72915d4cbddceb435e13d81601755714e9fSE Android 1320255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&roles, snode, i) { 1321255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 1322255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1323255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&new_roles, tnode, j) { 1324255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 1325255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1326255e72915d4cbddceb435e13d81601755714e9fSE Android /* check for duplicates */ 1327255e72915d4cbddceb435e13d81601755714e9fSE Android cur_allow = state->out->role_allow; 1328255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur_allow) { 1329255e72915d4cbddceb435e13d81601755714e9fSE Android if ((cur_allow->role == i + 1) && 1330255e72915d4cbddceb435e13d81601755714e9fSE Android (cur_allow->new_role == j + 1)) 1331255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1332255e72915d4cbddceb435e13d81601755714e9fSE Android cur_allow = cur_allow->next; 1333255e72915d4cbddceb435e13d81601755714e9fSE Android } 1334255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur_allow) 1335255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1336255e72915d4cbddceb435e13d81601755714e9fSE Android n = (role_allow_t *) 1337255e72915d4cbddceb435e13d81601755714e9fSE Android malloc(sizeof(role_allow_t)); 1338255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n) { 1339255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1340255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1341255e72915d4cbddceb435e13d81601755714e9fSE Android } 1342255e72915d4cbddceb435e13d81601755714e9fSE Android memset(n, 0, sizeof(role_allow_t)); 1343255e72915d4cbddceb435e13d81601755714e9fSE Android n->role = i + 1; 1344255e72915d4cbddceb435e13d81601755714e9fSE Android n->new_role = j + 1; 1345255e72915d4cbddceb435e13d81601755714e9fSE Android if (l) { 1346255e72915d4cbddceb435e13d81601755714e9fSE Android l->next = n; 1347255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1348255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->role_allow = n; 1349255e72915d4cbddceb435e13d81601755714e9fSE Android } 1350255e72915d4cbddceb435e13d81601755714e9fSE Android l = n; 1351255e72915d4cbddceb435e13d81601755714e9fSE Android } 1352255e72915d4cbddceb435e13d81601755714e9fSE Android } 1353255e72915d4cbddceb435e13d81601755714e9fSE Android 1354255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&roles); 1355255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&new_roles); 1356255e72915d4cbddceb435e13d81601755714e9fSE Android 1357255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1358255e72915d4cbddceb435e13d81601755714e9fSE Android } 1359255e72915d4cbddceb435e13d81601755714e9fSE Android 1360255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1361255e72915d4cbddceb435e13d81601755714e9fSE Android} 1362255e72915d4cbddceb435e13d81601755714e9fSE Android 1363255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules) 1364255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1365255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j, k; 1366255e72915d4cbddceb435e13d81601755714e9fSE Android role_trans_t *n, *l, *cur_trans; 1367255e72915d4cbddceb435e13d81601755714e9fSE Android role_trans_rule_t *cur; 1368255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t roles, types; 1369255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode, *tnode, *cnode; 1370255e72915d4cbddceb435e13d81601755714e9fSE Android 1371255e72915d4cbddceb435e13d81601755714e9fSE Android /* start at the end of the list */ 1372255e72915d4cbddceb435e13d81601755714e9fSE Android for (l = state->out->role_tr; l && l->next; l = l->next) ; 1373255e72915d4cbddceb435e13d81601755714e9fSE Android 1374255e72915d4cbddceb435e13d81601755714e9fSE Android cur = rules; 1375255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1376255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&roles); 1377255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&types); 1378255e72915d4cbddceb435e13d81601755714e9fSE Android 1379255e72915d4cbddceb435e13d81601755714e9fSE Android if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) { 1380255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1381255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1382255e72915d4cbddceb435e13d81601755714e9fSE Android } 1383255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set 1384255e72915d4cbddceb435e13d81601755714e9fSE Android (state->out, state->typemap, &cur->types, &types, 1)) { 1385255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1386255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1387255e72915d4cbddceb435e13d81601755714e9fSE Android } 1388255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&roles, rnode, i) { 1389255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(rnode, i)) 1390255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1391255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&types, tnode, j) { 1392255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 1393255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1394255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&cur->classes, cnode, k) { 1395255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(cnode, k)) 1396255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1397255e72915d4cbddceb435e13d81601755714e9fSE Android 1398255e72915d4cbddceb435e13d81601755714e9fSE Android cur_trans = state->out->role_tr; 1399255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur_trans) { 1400fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley unsigned int mapped_role; 1401fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 1402fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley mapped_role = state->rolemap[cur->new_role - 1]; 1403fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 1404255e72915d4cbddceb435e13d81601755714e9fSE Android if ((cur_trans->role == 1405255e72915d4cbddceb435e13d81601755714e9fSE Android i + 1) && 1406255e72915d4cbddceb435e13d81601755714e9fSE Android (cur_trans->type == 1407255e72915d4cbddceb435e13d81601755714e9fSE Android j + 1) && 1408255e72915d4cbddceb435e13d81601755714e9fSE Android (cur_trans->tclass == 1409255e72915d4cbddceb435e13d81601755714e9fSE Android k + 1)) { 1410fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (cur_trans->new_role == mapped_role) { 1411255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1412255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1413255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 1414fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley "Conflicting role trans rule %s %s : %s { %s vs %s }", 1415255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_role_val_to_name[i], 1416255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_type_val_to_name[j], 1417255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_class_val_to_name[k], 1418fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley state->out->p_role_val_to_name[mapped_role - 1], 1419fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley state->out->p_role_val_to_name[cur_trans->new_role - 1]); 1420255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1421255e72915d4cbddceb435e13d81601755714e9fSE Android } 1422255e72915d4cbddceb435e13d81601755714e9fSE Android } 1423255e72915d4cbddceb435e13d81601755714e9fSE Android cur_trans = cur_trans->next; 1424255e72915d4cbddceb435e13d81601755714e9fSE Android } 1425255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur_trans) 1426255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1427255e72915d4cbddceb435e13d81601755714e9fSE Android 1428255e72915d4cbddceb435e13d81601755714e9fSE Android n = (role_trans_t *) 1429255e72915d4cbddceb435e13d81601755714e9fSE Android malloc(sizeof(role_trans_t)); 1430255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n) { 1431255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 1432255e72915d4cbddceb435e13d81601755714e9fSE Android "Out of memory!"); 1433255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1434255e72915d4cbddceb435e13d81601755714e9fSE Android } 1435255e72915d4cbddceb435e13d81601755714e9fSE Android memset(n, 0, sizeof(role_trans_t)); 1436255e72915d4cbddceb435e13d81601755714e9fSE Android n->role = i + 1; 1437255e72915d4cbddceb435e13d81601755714e9fSE Android n->type = j + 1; 1438255e72915d4cbddceb435e13d81601755714e9fSE Android n->tclass = k + 1; 1439255e72915d4cbddceb435e13d81601755714e9fSE Android n->new_role = state->rolemap 1440255e72915d4cbddceb435e13d81601755714e9fSE Android [cur->new_role - 1]; 1441255e72915d4cbddceb435e13d81601755714e9fSE Android if (l) 1442255e72915d4cbddceb435e13d81601755714e9fSE Android l->next = n; 1443255e72915d4cbddceb435e13d81601755714e9fSE Android else 1444255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->role_tr = n; 1445255e72915d4cbddceb435e13d81601755714e9fSE Android 1446255e72915d4cbddceb435e13d81601755714e9fSE Android l = n; 1447255e72915d4cbddceb435e13d81601755714e9fSE Android } 1448255e72915d4cbddceb435e13d81601755714e9fSE Android } 1449255e72915d4cbddceb435e13d81601755714e9fSE Android } 1450255e72915d4cbddceb435e13d81601755714e9fSE Android 1451255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&roles); 1452255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&types); 1453255e72915d4cbddceb435e13d81601755714e9fSE Android 1454255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1455255e72915d4cbddceb435e13d81601755714e9fSE Android } 1456255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1457255e72915d4cbddceb435e13d81601755714e9fSE Android} 1458255e72915d4cbddceb435e13d81601755714e9fSE Android 1459255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules) 1460255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1461255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 1462dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley filename_trans_t *new_trans, *cur_trans, *end; 1463255e72915d4cbddceb435e13d81601755714e9fSE Android filename_trans_rule_t *cur_rule; 1464255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t stypes, ttypes; 1465255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *snode, *tnode; 1466dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley struct linear_probe probe; 1467dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1468dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley /* 1469dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * Linear probing speeds-up finding filename_trans rules with certain 1470dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley * "stype" value. 1471dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley */ 1472dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (linear_probe_create(&probe, 4096)) { /* Assume 4096 is enough for most cases */ 1473dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(state->handle, "Out of memory!"); 1474dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return -1; 1475dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1476255e72915d4cbddceb435e13d81601755714e9fSE Android 1477255e72915d4cbddceb435e13d81601755714e9fSE Android cur_rule = rules; 1478255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur_rule) { 1479fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley uint32_t mapped_otype; 1480fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 1481255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&stypes); 1482255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&ttypes); 1483255e72915d4cbddceb435e13d81601755714e9fSE Android 1484255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set(state->out, state->typemap, 1485255e72915d4cbddceb435e13d81601755714e9fSE Android &cur_rule->stypes, &stypes, 1)) { 1486255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1487255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1488255e72915d4cbddceb435e13d81601755714e9fSE Android } 1489255e72915d4cbddceb435e13d81601755714e9fSE Android 1490255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set(state->out, state->typemap, 1491255e72915d4cbddceb435e13d81601755714e9fSE Android &cur_rule->ttypes, &ttypes, 1)) { 1492255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1493255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1494255e72915d4cbddceb435e13d81601755714e9fSE Android } 1495255e72915d4cbddceb435e13d81601755714e9fSE Android 1496fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley mapped_otype = state->typemap[cur_rule->otype - 1]; 1497fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 1498dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (ebitmap_length(&stypes) > probe.length) { 1499dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley linear_probe_destroy(&probe); 1500dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (linear_probe_create(&probe, ebitmap_length(&stypes))) { 1501dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(state->handle, "Out of memory!"); 1502dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley return -1; 1503dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1504dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1505dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1506255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&stypes, snode, i) { 1507255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 1508255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1509255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&ttypes, tnode, j) { 1510255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 1511255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1512255e72915d4cbddceb435e13d81601755714e9fSE Android 1513dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cur_trans = linear_probe_find(&probe, i); 1514dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley while (cur_trans != NULL) { 1515dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if ((cur_trans->ttype == j + 1) && 1516255e72915d4cbddceb435e13d81601755714e9fSE Android (cur_trans->tclass == cur_rule->tclass) && 1517255e72915d4cbddceb435e13d81601755714e9fSE Android (!strcmp(cur_trans->name, cur_rule->name))) { 1518255e72915d4cbddceb435e13d81601755714e9fSE Android /* duplicate rule, who cares */ 1519fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (cur_trans->otype == mapped_otype) 1520255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1521255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Conflicting filename trans rules %s %s %s : %s otype1:%s otype2:%s", 1522255e72915d4cbddceb435e13d81601755714e9fSE Android cur_trans->name, 1523255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_type_val_to_name[i], 1524255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_type_val_to_name[j], 1525255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_class_val_to_name[cur_trans->tclass - 1], 1526255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_type_val_to_name[cur_trans->otype - 1], 1527fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley state->out->p_type_val_to_name[mapped_otype - 1]); 1528dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1529255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1530255e72915d4cbddceb435e13d81601755714e9fSE Android } 1531255e72915d4cbddceb435e13d81601755714e9fSE Android cur_trans = cur_trans->next; 1532255e72915d4cbddceb435e13d81601755714e9fSE Android } 1533255e72915d4cbddceb435e13d81601755714e9fSE Android /* duplicate rule, who cares */ 1534255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur_trans) 1535255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1536255e72915d4cbddceb435e13d81601755714e9fSE Android 1537255e72915d4cbddceb435e13d81601755714e9fSE Android new_trans = malloc(sizeof(*new_trans)); 1538255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_trans) { 1539255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1540255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1541255e72915d4cbddceb435e13d81601755714e9fSE Android } 1542255e72915d4cbddceb435e13d81601755714e9fSE Android memset(new_trans, 0, sizeof(*new_trans)); 1543255e72915d4cbddceb435e13d81601755714e9fSE Android 1544255e72915d4cbddceb435e13d81601755714e9fSE Android new_trans->name = strdup(cur_rule->name); 1545255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_trans->name) { 1546255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1547255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1548255e72915d4cbddceb435e13d81601755714e9fSE Android } 1549255e72915d4cbddceb435e13d81601755714e9fSE Android new_trans->stype = i + 1; 1550255e72915d4cbddceb435e13d81601755714e9fSE Android new_trans->ttype = j + 1; 1551255e72915d4cbddceb435e13d81601755714e9fSE Android new_trans->tclass = cur_rule->tclass; 1552fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley new_trans->otype = mapped_otype; 1553dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley linear_probe_insert(&probe, i, new_trans); 1554255e72915d4cbddceb435e13d81601755714e9fSE Android } 1555255e72915d4cbddceb435e13d81601755714e9fSE Android } 1556255e72915d4cbddceb435e13d81601755714e9fSE Android 1557dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cur_trans = linear_probe_dump(&probe, &end); 1558dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (cur_trans != NULL) { 1559dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley end->next = state->out->filename_trans; 1560dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley state->out->filename_trans = cur_trans; 1561dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley } 1562dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley 1563255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 1564255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&ttypes); 1565255e72915d4cbddceb435e13d81601755714e9fSE Android 1566255e72915d4cbddceb435e13d81601755714e9fSE Android cur_rule = cur_rule->next; 1567255e72915d4cbddceb435e13d81601755714e9fSE Android } 1568255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1569255e72915d4cbddceb435e13d81601755714e9fSE Android} 1570255e72915d4cbddceb435e13d81601755714e9fSE Android 1571255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t tclass, 1572255e72915d4cbddceb435e13d81601755714e9fSE Android mls_semantic_range_t * trange, 1573255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t * state) 1574255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1575255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_t *rt, *check_rt = state->out->range_tr; 1576255e72915d4cbddceb435e13d81601755714e9fSE Android mls_range_t exp_range; 1577255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = -1; 1578255e72915d4cbddceb435e13d81601755714e9fSE Android 1579255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_semantic_range_expand(trange, &exp_range, state->out, 1580255e72915d4cbddceb435e13d81601755714e9fSE Android state->handle)) 1581255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1582255e72915d4cbddceb435e13d81601755714e9fSE Android 1583255e72915d4cbddceb435e13d81601755714e9fSE Android /* check for duplicates/conflicts */ 1584255e72915d4cbddceb435e13d81601755714e9fSE Android while (check_rt) { 1585255e72915d4cbddceb435e13d81601755714e9fSE Android if ((check_rt->source_type == stype) && 1586255e72915d4cbddceb435e13d81601755714e9fSE Android (check_rt->target_type == ttype) && 1587255e72915d4cbddceb435e13d81601755714e9fSE Android (check_rt->target_class == tclass)) { 1588255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_range_eq(&check_rt->target_range, &exp_range)) { 1589255e72915d4cbddceb435e13d81601755714e9fSE Android /* duplicate */ 1590255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1591255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1592255e72915d4cbddceb435e13d81601755714e9fSE Android /* conflict */ 1593255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 1594255e72915d4cbddceb435e13d81601755714e9fSE Android "Conflicting range trans rule %s %s : %s", 1595255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_type_val_to_name[stype - 1], 1596255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_type_val_to_name[ttype - 1], 1597255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->p_class_val_to_name[tclass - 1598255e72915d4cbddceb435e13d81601755714e9fSE Android 1]); 1599255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1600255e72915d4cbddceb435e13d81601755714e9fSE Android } 1601255e72915d4cbddceb435e13d81601755714e9fSE Android } 1602255e72915d4cbddceb435e13d81601755714e9fSE Android check_rt = check_rt->next; 1603255e72915d4cbddceb435e13d81601755714e9fSE Android } 1604255e72915d4cbddceb435e13d81601755714e9fSE Android if (check_rt) { 1605255e72915d4cbddceb435e13d81601755714e9fSE Android /* this is a dup - skip */ 1606255e72915d4cbddceb435e13d81601755714e9fSE Android rc = 0; 1607255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1608255e72915d4cbddceb435e13d81601755714e9fSE Android } 1609255e72915d4cbddceb435e13d81601755714e9fSE Android 1610255e72915d4cbddceb435e13d81601755714e9fSE Android rt = (range_trans_t *) calloc(1, sizeof(range_trans_t)); 1611255e72915d4cbddceb435e13d81601755714e9fSE Android if (!rt) { 1612255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1613255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1614255e72915d4cbddceb435e13d81601755714e9fSE Android } 1615255e72915d4cbddceb435e13d81601755714e9fSE Android 1616255e72915d4cbddceb435e13d81601755714e9fSE Android rt->next = state->out->range_tr; 1617255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->range_tr = rt; 1618255e72915d4cbddceb435e13d81601755714e9fSE Android 1619255e72915d4cbddceb435e13d81601755714e9fSE Android rt->source_type = stype; 1620255e72915d4cbddceb435e13d81601755714e9fSE Android rt->target_type = ttype; 1621255e72915d4cbddceb435e13d81601755714e9fSE Android rt->target_class = tclass; 1622255e72915d4cbddceb435e13d81601755714e9fSE Android if (mls_range_cpy(&rt->target_range, &exp_range)) { 1623255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1624255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 1625255e72915d4cbddceb435e13d81601755714e9fSE Android } 1626255e72915d4cbddceb435e13d81601755714e9fSE Android 1627255e72915d4cbddceb435e13d81601755714e9fSE Android rc = 0; 1628255e72915d4cbddceb435e13d81601755714e9fSE Android 1629255e72915d4cbddceb435e13d81601755714e9fSE Android out: 1630255e72915d4cbddceb435e13d81601755714e9fSE Android mls_range_destroy(&exp_range); 1631255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 1632255e72915d4cbddceb435e13d81601755714e9fSE Android} 1633255e72915d4cbddceb435e13d81601755714e9fSE Android 1634255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_range_trans(expand_state_t * state, 1635255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_rule_t * rules) 1636255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1637255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j, k; 1638255e72915d4cbddceb435e13d81601755714e9fSE Android range_trans_rule_t *rule; 1639255e72915d4cbddceb435e13d81601755714e9fSE Android 1640255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t stypes, ttypes; 1641255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *snode, *tnode, *cnode; 1642255e72915d4cbddceb435e13d81601755714e9fSE Android 1643255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->verbose) 1644255e72915d4cbddceb435e13d81601755714e9fSE Android INFO(state->handle, "expanding range transitions"); 1645255e72915d4cbddceb435e13d81601755714e9fSE Android 1646255e72915d4cbddceb435e13d81601755714e9fSE Android for (rule = rules; rule; rule = rule->next) { 1647255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&stypes); 1648255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&ttypes); 1649255e72915d4cbddceb435e13d81601755714e9fSE Android 1650255e72915d4cbddceb435e13d81601755714e9fSE Android /* expand the type sets */ 1651255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set(state->out, state->typemap, 1652255e72915d4cbddceb435e13d81601755714e9fSE Android &rule->stypes, &stypes, 1)) { 1653255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1654255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1655255e72915d4cbddceb435e13d81601755714e9fSE Android } 1656255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set(state->out, state->typemap, 1657255e72915d4cbddceb435e13d81601755714e9fSE Android &rule->ttypes, &ttypes, 1)) { 1658255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 1659255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 1660255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1661255e72915d4cbddceb435e13d81601755714e9fSE Android } 1662255e72915d4cbddceb435e13d81601755714e9fSE Android 1663255e72915d4cbddceb435e13d81601755714e9fSE Android /* loop on source type */ 1664255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&stypes, snode, i) { 1665255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 1666255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1667255e72915d4cbddceb435e13d81601755714e9fSE Android /* loop on target type */ 1668255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&ttypes, tnode, j) { 1669255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 1670255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1671255e72915d4cbddceb435e13d81601755714e9fSE Android /* loop on target class */ 1672255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&rule->tclasses, cnode, k) { 1673255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(cnode, k)) 1674255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1675255e72915d4cbddceb435e13d81601755714e9fSE Android 1676255e72915d4cbddceb435e13d81601755714e9fSE Android if (exp_rangetr_helper(i + 1, 1677255e72915d4cbddceb435e13d81601755714e9fSE Android j + 1, 1678255e72915d4cbddceb435e13d81601755714e9fSE Android k + 1, 1679255e72915d4cbddceb435e13d81601755714e9fSE Android &rule->trange, 1680255e72915d4cbddceb435e13d81601755714e9fSE Android state)) { 1681255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 1682255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&ttypes); 1683255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1684255e72915d4cbddceb435e13d81601755714e9fSE Android } 1685255e72915d4cbddceb435e13d81601755714e9fSE Android } 1686255e72915d4cbddceb435e13d81601755714e9fSE Android } 1687255e72915d4cbddceb435e13d81601755714e9fSE Android } 1688255e72915d4cbddceb435e13d81601755714e9fSE Android 1689255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 1690255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&ttypes); 1691255e72915d4cbddceb435e13d81601755714e9fSE Android } 1692255e72915d4cbddceb435e13d81601755714e9fSE Android 1693255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 1694255e72915d4cbddceb435e13d81601755714e9fSE Android} 1695255e72915d4cbddceb435e13d81601755714e9fSE Android 1696255e72915d4cbddceb435e13d81601755714e9fSE Android/* Search for an AV tab node within a hash table with the given key. 1697255e72915d4cbddceb435e13d81601755714e9fSE Android * If the node does not exist, create it and return it; otherwise 1698255e72915d4cbddceb435e13d81601755714e9fSE Android * return the pre-existing one. 1699255e72915d4cbddceb435e13d81601755714e9fSE Android*/ 1700255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic avtab_ptr_t find_avtab_node(sepol_handle_t * handle, 1701255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_t * avtab, avtab_key_t * key, 1702255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** cond) 1703255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1704255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 1705255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_datum_t avdatum; 1706255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t *nl; 1707255e72915d4cbddceb435e13d81601755714e9fSE Android 1708255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node(avtab, key); 1709255e72915d4cbddceb435e13d81601755714e9fSE Android 1710255e72915d4cbddceb435e13d81601755714e9fSE Android /* If this is for conditional policies, keep searching in case 1711255e72915d4cbddceb435e13d81601755714e9fSE Android the node is part of my conditional avtab. */ 1712255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond) { 1713255e72915d4cbddceb435e13d81601755714e9fSE Android while (node) { 1714255e72915d4cbddceb435e13d81601755714e9fSE Android if (node->parse_context == cond) 1715255e72915d4cbddceb435e13d81601755714e9fSE Android break; 1716255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node_next(node, key->specified); 1717255e72915d4cbddceb435e13d81601755714e9fSE Android } 1718255e72915d4cbddceb435e13d81601755714e9fSE Android } 1719255e72915d4cbddceb435e13d81601755714e9fSE Android 1720255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node) { 1721255e72915d4cbddceb435e13d81601755714e9fSE Android memset(&avdatum, 0, sizeof avdatum); 1722255e72915d4cbddceb435e13d81601755714e9fSE Android /* this is used to get the node - insertion is actually unique */ 1723255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_insert_nonunique(avtab, key, &avdatum); 1724255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node) { 1725255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "hash table overflow"); 1726255e72915d4cbddceb435e13d81601755714e9fSE Android return NULL; 1727255e72915d4cbddceb435e13d81601755714e9fSE Android } 1728255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond) { 1729255e72915d4cbddceb435e13d81601755714e9fSE Android node->parse_context = cond; 1730255e72915d4cbddceb435e13d81601755714e9fSE Android nl = (cond_av_list_t *) malloc(sizeof(cond_av_list_t)); 1731255e72915d4cbddceb435e13d81601755714e9fSE Android if (!nl) { 1732255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Memory error"); 1733255e72915d4cbddceb435e13d81601755714e9fSE Android return NULL; 1734255e72915d4cbddceb435e13d81601755714e9fSE Android } 1735255e72915d4cbddceb435e13d81601755714e9fSE Android memset(nl, 0, sizeof(cond_av_list_t)); 1736255e72915d4cbddceb435e13d81601755714e9fSE Android nl->node = node; 1737255e72915d4cbddceb435e13d81601755714e9fSE Android nl->next = *cond; 1738255e72915d4cbddceb435e13d81601755714e9fSE Android *cond = nl; 1739255e72915d4cbddceb435e13d81601755714e9fSE Android } 1740255e72915d4cbddceb435e13d81601755714e9fSE Android } 1741255e72915d4cbddceb435e13d81601755714e9fSE Android 1742255e72915d4cbddceb435e13d81601755714e9fSE Android return node; 1743255e72915d4cbddceb435e13d81601755714e9fSE Android} 1744255e72915d4cbddceb435e13d81601755714e9fSE Android 1745255e72915d4cbddceb435e13d81601755714e9fSE Android#define EXPAND_RULE_SUCCESS 1 1746255e72915d4cbddceb435e13d81601755714e9fSE Android#define EXPAND_RULE_CONFLICT 0 1747255e72915d4cbddceb435e13d81601755714e9fSE Android#define EXPAND_RULE_ERROR -1 1748255e72915d4cbddceb435e13d81601755714e9fSE Android 1749255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_terule_helper(sepol_handle_t * handle, 1750255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * p, uint32_t * typemap, 1751255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t specified, cond_av_list_t ** cond, 1752255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** other, uint32_t stype, 1753255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t ttype, class_perm_node_t * perms, 1754255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_t * avtab, int enabled) 1755255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1756255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t avkey; 1757255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_datum_t *avdatump; 1758255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 1759255e72915d4cbddceb435e13d81601755714e9fSE Android class_perm_node_t *cur; 1760255e72915d4cbddceb435e13d81601755714e9fSE Android int conflict; 1761255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t oldtype = 0, spec = 0; 1762255e72915d4cbddceb435e13d81601755714e9fSE Android 1763255e72915d4cbddceb435e13d81601755714e9fSE Android if (specified & AVRULE_TRANSITION) { 1764255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_TRANSITION; 1765255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_MEMBER) { 1766255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_MEMBER; 1767255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_CHANGE) { 1768255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_CHANGE; 1769255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1770255e72915d4cbddceb435e13d81601755714e9fSE Android assert(0); /* unreachable */ 1771255e72915d4cbddceb435e13d81601755714e9fSE Android } 1772255e72915d4cbddceb435e13d81601755714e9fSE Android 1773255e72915d4cbddceb435e13d81601755714e9fSE Android cur = perms; 1774255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1775255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t remapped_data = 1776255e72915d4cbddceb435e13d81601755714e9fSE Android typemap ? typemap[cur->data - 1] : cur->data; 1777255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.source_type = stype + 1; 1778255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_type = ttype + 1; 1779255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_class = cur->class; 1780255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.specified = spec; 1781255e72915d4cbddceb435e13d81601755714e9fSE Android 1782255e72915d4cbddceb435e13d81601755714e9fSE Android conflict = 0; 1783255e72915d4cbddceb435e13d81601755714e9fSE Android /* check to see if the expanded TE already exists -- 1784255e72915d4cbddceb435e13d81601755714e9fSE Android * either in the global scope or in another 1785255e72915d4cbddceb435e13d81601755714e9fSE Android * conditional AV tab */ 1786255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node(&p->te_avtab, &avkey); 1787255e72915d4cbddceb435e13d81601755714e9fSE Android if (node) { 1788255e72915d4cbddceb435e13d81601755714e9fSE Android conflict = 1; 1789255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1790255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node(&p->te_cond_avtab, &avkey); 1791255e72915d4cbddceb435e13d81601755714e9fSE Android if (node && node->parse_context != other) { 1792255e72915d4cbddceb435e13d81601755714e9fSE Android conflict = 2; 1793255e72915d4cbddceb435e13d81601755714e9fSE Android } 1794255e72915d4cbddceb435e13d81601755714e9fSE Android } 1795255e72915d4cbddceb435e13d81601755714e9fSE Android 1796255e72915d4cbddceb435e13d81601755714e9fSE Android if (conflict) { 1797255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump = &node->datum; 1798255e72915d4cbddceb435e13d81601755714e9fSE Android if (specified & AVRULE_TRANSITION) { 1799255e72915d4cbddceb435e13d81601755714e9fSE Android oldtype = avdatump->data; 1800255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_MEMBER) { 1801255e72915d4cbddceb435e13d81601755714e9fSE Android oldtype = avdatump->data; 1802255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_CHANGE) { 1803255e72915d4cbddceb435e13d81601755714e9fSE Android oldtype = avdatump->data; 1804255e72915d4cbddceb435e13d81601755714e9fSE Android } 1805255e72915d4cbddceb435e13d81601755714e9fSE Android 1806255e72915d4cbddceb435e13d81601755714e9fSE Android if (oldtype == remapped_data) { 1807255e72915d4cbddceb435e13d81601755714e9fSE Android /* if the duplicate is inside the same scope (eg., unconditional 1808255e72915d4cbddceb435e13d81601755714e9fSE Android * or in same conditional then ignore it */ 1809255e72915d4cbddceb435e13d81601755714e9fSE Android if ((conflict == 1 && cond == NULL) 1810255e72915d4cbddceb435e13d81601755714e9fSE Android || node->parse_context == cond) 1811255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_SUCCESS; 1812255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "duplicate TE rule for %s %s:%s %s", 1813255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_type_val_to_name[avkey.source_type - 1814255e72915d4cbddceb435e13d81601755714e9fSE Android 1], 1815255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_type_val_to_name[avkey.target_type - 1816255e72915d4cbddceb435e13d81601755714e9fSE Android 1], 1817255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_class_val_to_name[avkey.target_class - 1818255e72915d4cbddceb435e13d81601755714e9fSE Android 1], 1819255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_type_val_to_name[oldtype - 1]); 1820255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_CONFLICT; 1821255e72915d4cbddceb435e13d81601755714e9fSE Android } 1822255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, 1823255e72915d4cbddceb435e13d81601755714e9fSE Android "conflicting TE rule for (%s, %s:%s): old was %s, new is %s", 1824255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_type_val_to_name[avkey.source_type - 1], 1825255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_type_val_to_name[avkey.target_type - 1], 1826255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_class_val_to_name[avkey.target_class - 1], 1827255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_type_val_to_name[oldtype - 1], 1828255e72915d4cbddceb435e13d81601755714e9fSE Android p->p_type_val_to_name[remapped_data - 1]); 1829255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_CONFLICT; 1830255e72915d4cbddceb435e13d81601755714e9fSE Android } 1831255e72915d4cbddceb435e13d81601755714e9fSE Android 1832255e72915d4cbddceb435e13d81601755714e9fSE Android node = find_avtab_node(handle, avtab, &avkey, cond); 1833255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node) 1834255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 1835255e72915d4cbddceb435e13d81601755714e9fSE Android if (enabled) { 1836255e72915d4cbddceb435e13d81601755714e9fSE Android node->key.specified |= AVTAB_ENABLED; 1837255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1838255e72915d4cbddceb435e13d81601755714e9fSE Android node->key.specified &= ~AVTAB_ENABLED; 1839255e72915d4cbddceb435e13d81601755714e9fSE Android } 1840255e72915d4cbddceb435e13d81601755714e9fSE Android 1841255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump = &node->datum; 1842255e72915d4cbddceb435e13d81601755714e9fSE Android if (specified & AVRULE_TRANSITION) { 1843255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data = remapped_data; 1844255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_MEMBER) { 1845255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data = remapped_data; 1846255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_CHANGE) { 1847255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data = remapped_data; 1848255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1849255e72915d4cbddceb435e13d81601755714e9fSE Android assert(0); /* should never occur */ 1850255e72915d4cbddceb435e13d81601755714e9fSE Android } 1851255e72915d4cbddceb435e13d81601755714e9fSE Android 1852255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1853255e72915d4cbddceb435e13d81601755714e9fSE Android } 1854255e72915d4cbddceb435e13d81601755714e9fSE Android 1855255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_SUCCESS; 1856255e72915d4cbddceb435e13d81601755714e9fSE Android} 1857255e72915d4cbddceb435e13d81601755714e9fSE Android 1858255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_avrule_helper(sepol_handle_t * handle, 1859255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t specified, 1860255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** cond, 1861255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t stype, uint32_t ttype, 1862255e72915d4cbddceb435e13d81601755714e9fSE Android class_perm_node_t * perms, avtab_t * avtab, 1863255e72915d4cbddceb435e13d81601755714e9fSE Android int enabled) 1864255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1865255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t avkey; 1866255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_datum_t *avdatump; 1867255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 1868255e72915d4cbddceb435e13d81601755714e9fSE Android class_perm_node_t *cur; 1869255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t spec = 0; 1870255e72915d4cbddceb435e13d81601755714e9fSE Android 1871255e72915d4cbddceb435e13d81601755714e9fSE Android if (specified & AVRULE_ALLOWED) { 1872255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_ALLOWED; 1873255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_AUDITALLOW) { 1874255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_AUDITALLOW; 1875255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_AUDITDENY) { 1876255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_AUDITDENY; 1877255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_DONTAUDIT) { 1878255e72915d4cbddceb435e13d81601755714e9fSE Android if (handle && handle->disable_dontaudit) 1879255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_SUCCESS; 1880255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_AUDITDENY; 1881255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_NEVERALLOW) { 1882255e72915d4cbddceb435e13d81601755714e9fSE Android spec = AVTAB_NEVERALLOW; 1883255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1884255e72915d4cbddceb435e13d81601755714e9fSE Android assert(0); /* unreachable */ 1885255e72915d4cbddceb435e13d81601755714e9fSE Android } 1886255e72915d4cbddceb435e13d81601755714e9fSE Android 1887255e72915d4cbddceb435e13d81601755714e9fSE Android cur = perms; 1888255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 1889255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.source_type = stype + 1; 1890255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_type = ttype + 1; 1891255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.target_class = cur->class; 1892255e72915d4cbddceb435e13d81601755714e9fSE Android avkey.specified = spec; 1893255e72915d4cbddceb435e13d81601755714e9fSE Android 1894255e72915d4cbddceb435e13d81601755714e9fSE Android node = find_avtab_node(handle, avtab, &avkey, cond); 1895255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node) 1896255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_ERROR; 1897255e72915d4cbddceb435e13d81601755714e9fSE Android if (enabled) { 1898255e72915d4cbddceb435e13d81601755714e9fSE Android node->key.specified |= AVTAB_ENABLED; 1899255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1900255e72915d4cbddceb435e13d81601755714e9fSE Android node->key.specified &= ~AVTAB_ENABLED; 1901255e72915d4cbddceb435e13d81601755714e9fSE Android } 1902255e72915d4cbddceb435e13d81601755714e9fSE Android 1903255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump = &node->datum; 1904255e72915d4cbddceb435e13d81601755714e9fSE Android if (specified & AVRULE_ALLOWED) { 1905255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data |= cur->data; 1906255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_AUDITALLOW) { 1907255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data |= cur->data; 1908255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_NEVERALLOW) { 1909255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data |= cur->data; 1910255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_AUDITDENY) { 1911255e72915d4cbddceb435e13d81601755714e9fSE Android /* Since a '0' in an auditdeny mask represents 1912255e72915d4cbddceb435e13d81601755714e9fSE Android * a permission we do NOT want to audit 1913255e72915d4cbddceb435e13d81601755714e9fSE Android * (dontaudit), we use the '&' operand to 1914255e72915d4cbddceb435e13d81601755714e9fSE Android * ensure that all '0's in the mask are 1915255e72915d4cbddceb435e13d81601755714e9fSE Android * retained (much unlike the allow and 1916255e72915d4cbddceb435e13d81601755714e9fSE Android * auditallow cases). 1917255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1918255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data &= cur->data; 1919255e72915d4cbddceb435e13d81601755714e9fSE Android } else if (specified & AVRULE_DONTAUDIT) { 1920255e72915d4cbddceb435e13d81601755714e9fSE Android if (avdatump->data) 1921255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data &= ~cur->data; 1922255e72915d4cbddceb435e13d81601755714e9fSE Android else 1923255e72915d4cbddceb435e13d81601755714e9fSE Android avdatump->data = ~cur->data; 1924255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 1925255e72915d4cbddceb435e13d81601755714e9fSE Android assert(0); /* should never occur */ 1926255e72915d4cbddceb435e13d81601755714e9fSE Android } 1927255e72915d4cbddceb435e13d81601755714e9fSE Android 1928255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 1929255e72915d4cbddceb435e13d81601755714e9fSE Android } 1930255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_SUCCESS; 1931255e72915d4cbddceb435e13d81601755714e9fSE Android} 1932255e72915d4cbddceb435e13d81601755714e9fSE Android 1933255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_rule_helper(sepol_handle_t * handle, 1934255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * p, uint32_t * typemap, 1935255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t * source_rule, avtab_t * dest_avtab, 1936255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** cond, cond_av_list_t ** other, 1937255e72915d4cbddceb435e13d81601755714e9fSE Android int enabled, 1938255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t * stypes, ebitmap_t * ttypes) 1939255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1940255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 1941255e72915d4cbddceb435e13d81601755714e9fSE Android int retval; 1942255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *snode, *tnode; 1943255e72915d4cbddceb435e13d81601755714e9fSE Android 1944255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(stypes, snode, i) { 1945255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 1946255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1947255e72915d4cbddceb435e13d81601755714e9fSE Android if (source_rule->flags & RULE_SELF) { 1948255e72915d4cbddceb435e13d81601755714e9fSE Android if (source_rule->specified & AVRULE_AV) { 19494ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley retval = expand_avrule_helper(handle, source_rule->specified, 19504ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley cond, i, i, source_rule->perms, 19514ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley dest_avtab, enabled); 19524ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (retval != EXPAND_RULE_SUCCESS) 1953255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 1954255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 19554ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley retval = expand_terule_helper(handle, p, typemap, 19564ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley source_rule->specified, cond, 19574ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley other, i, i, source_rule->perms, 19584ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley dest_avtab, enabled); 19594ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (retval != EXPAND_RULE_SUCCESS) 1960255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 1961255e72915d4cbddceb435e13d81601755714e9fSE Android } 1962255e72915d4cbddceb435e13d81601755714e9fSE Android } 1963255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(ttypes, tnode, j) { 1964255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 1965255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 1966255e72915d4cbddceb435e13d81601755714e9fSE Android if (source_rule->specified & AVRULE_AV) { 19674ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley retval = expand_avrule_helper(handle, source_rule->specified, 19684ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley cond, i, j, source_rule->perms, 19694ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley dest_avtab, enabled); 19704ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (retval != EXPAND_RULE_SUCCESS) 1971255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 1972255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 19734ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley retval = expand_terule_helper(handle, p, typemap, 19744ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley source_rule->specified, cond, 19754ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley other, i, j, source_rule->perms, 19764ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley dest_avtab, enabled); 19774ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (retval != EXPAND_RULE_SUCCESS) 1978255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 1979255e72915d4cbddceb435e13d81601755714e9fSE Android } 1980255e72915d4cbddceb435e13d81601755714e9fSE Android } 1981255e72915d4cbddceb435e13d81601755714e9fSE Android } 1982255e72915d4cbddceb435e13d81601755714e9fSE Android 1983255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_SUCCESS; 1984255e72915d4cbddceb435e13d81601755714e9fSE Android} 1985255e72915d4cbddceb435e13d81601755714e9fSE Android 1986255e72915d4cbddceb435e13d81601755714e9fSE Android/* 1987255e72915d4cbddceb435e13d81601755714e9fSE Android * Expand a rule into a given avtab - checking for conflicting type 1988255e72915d4cbddceb435e13d81601755714e9fSE Android * rules in the destination policy. Return EXPAND_RULE_SUCCESS on 1989255e72915d4cbddceb435e13d81601755714e9fSE Android * success, EXPAND_RULE_CONFLICT if the rule conflicts with something 1990255e72915d4cbddceb435e13d81601755714e9fSE Android * (and hence was not added), or EXPAND_RULE_ERROR on error. 1991255e72915d4cbddceb435e13d81601755714e9fSE Android */ 1992255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int convert_and_expand_rule(sepol_handle_t * handle, 1993255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * dest_pol, uint32_t * typemap, 1994255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t * source_rule, avtab_t * dest_avtab, 1995255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** cond, 1996255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** other, int enabled, 1997255e72915d4cbddceb435e13d81601755714e9fSE Android int do_neverallow) 1998255e72915d4cbddceb435e13d81601755714e9fSE Android{ 1999255e72915d4cbddceb435e13d81601755714e9fSE Android int retval; 2000255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t stypes, ttypes; 2001255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned char alwaysexpand; 2002255e72915d4cbddceb435e13d81601755714e9fSE Android 2003255e72915d4cbddceb435e13d81601755714e9fSE Android if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW) 2004255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_SUCCESS; 2005255e72915d4cbddceb435e13d81601755714e9fSE Android 2006255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&stypes); 2007255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&ttypes); 2008255e72915d4cbddceb435e13d81601755714e9fSE Android 2009255e72915d4cbddceb435e13d81601755714e9fSE Android /* Force expansion for type rules and for self rules. */ 2010255e72915d4cbddceb435e13d81601755714e9fSE Android alwaysexpand = ((source_rule->specified & AVRULE_TYPE) || 2011255e72915d4cbddceb435e13d81601755714e9fSE Android (source_rule->flags & RULE_SELF)); 2012255e72915d4cbddceb435e13d81601755714e9fSE Android 2013255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set 2014255e72915d4cbddceb435e13d81601755714e9fSE Android (dest_pol, typemap, &source_rule->stypes, &stypes, alwaysexpand)) 2015255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_ERROR; 2016255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set 2017255e72915d4cbddceb435e13d81601755714e9fSE Android (dest_pol, typemap, &source_rule->ttypes, &ttypes, alwaysexpand)) 2018255e72915d4cbddceb435e13d81601755714e9fSE Android return EXPAND_RULE_ERROR; 2019255e72915d4cbddceb435e13d81601755714e9fSE Android 2020255e72915d4cbddceb435e13d81601755714e9fSE Android retval = expand_rule_helper(handle, dest_pol, typemap, 2021255e72915d4cbddceb435e13d81601755714e9fSE Android source_rule, dest_avtab, 2022255e72915d4cbddceb435e13d81601755714e9fSE Android cond, other, enabled, &stypes, &ttypes); 2023255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 2024255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&ttypes); 2025255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 2026255e72915d4cbddceb435e13d81601755714e9fSE Android} 2027255e72915d4cbddceb435e13d81601755714e9fSE Android 2028255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int cond_avrule_list_copy(policydb_t * dest_pol, avrule_t * source_rules, 2029255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_t * dest_avtab, cond_av_list_t ** list, 2030255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** other, uint32_t * typemap, 2031255e72915d4cbddceb435e13d81601755714e9fSE Android int enabled, expand_state_t * state) 2032255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2033255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t *cur; 2034255e72915d4cbddceb435e13d81601755714e9fSE Android 2035255e72915d4cbddceb435e13d81601755714e9fSE Android cur = source_rules; 2036255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 2037255e72915d4cbddceb435e13d81601755714e9fSE Android if (convert_and_expand_rule(state->handle, dest_pol, 2038255e72915d4cbddceb435e13d81601755714e9fSE Android typemap, cur, dest_avtab, 2039255e72915d4cbddceb435e13d81601755714e9fSE Android list, other, enabled, 2040255e72915d4cbddceb435e13d81601755714e9fSE Android 0) != EXPAND_RULE_SUCCESS) { 2041255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2042255e72915d4cbddceb435e13d81601755714e9fSE Android } 2043255e72915d4cbddceb435e13d81601755714e9fSE Android 2044255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 2045255e72915d4cbddceb435e13d81601755714e9fSE Android } 2046255e72915d4cbddceb435e13d81601755714e9fSE Android 2047255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2048255e72915d4cbddceb435e13d81601755714e9fSE Android} 2049255e72915d4cbddceb435e13d81601755714e9fSE Android 2050255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int cond_node_map_bools(expand_state_t * state, cond_node_t * cn) 2051255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2052255e72915d4cbddceb435e13d81601755714e9fSE Android cond_expr_t *cur; 2053255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 2054255e72915d4cbddceb435e13d81601755714e9fSE Android 2055255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cn->expr; 2056255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur) { 2057255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur->bool) 2058255e72915d4cbddceb435e13d81601755714e9fSE Android cur->bool = state->boolmap[cur->bool - 1]; 2059255e72915d4cbddceb435e13d81601755714e9fSE Android cur = cur->next; 2060255e72915d4cbddceb435e13d81601755714e9fSE Android } 2061255e72915d4cbddceb435e13d81601755714e9fSE Android 2062255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++) 2063255e72915d4cbddceb435e13d81601755714e9fSE Android cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1]; 2064255e72915d4cbddceb435e13d81601755714e9fSE Android 2065255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_normalize_expr(state->out, cn)) { 2066255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Error while normalizing conditional"); 2067255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2068255e72915d4cbddceb435e13d81601755714e9fSE Android } 2069255e72915d4cbddceb435e13d81601755714e9fSE Android 2070255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2071255e72915d4cbddceb435e13d81601755714e9fSE Android} 2072255e72915d4cbddceb435e13d81601755714e9fSE Android 2073255e72915d4cbddceb435e13d81601755714e9fSE Android/* copy the nodes in *reverse* order -- the result is that the last 2074255e72915d4cbddceb435e13d81601755714e9fSE Android * given conditional appears first in the policy, so as to match the 2075255e72915d4cbddceb435e13d81601755714e9fSE Android * behavior of the upstream compiler */ 2076255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int cond_node_copy(expand_state_t * state, cond_node_t * cn) 2077255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2078255e72915d4cbddceb435e13d81601755714e9fSE Android cond_node_t *new_cond, *tmp; 2079255e72915d4cbddceb435e13d81601755714e9fSE Android 2080255e72915d4cbddceb435e13d81601755714e9fSE Android if (cn == NULL) { 2081255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2082255e72915d4cbddceb435e13d81601755714e9fSE Android } 2083255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_node_copy(state, cn->next)) { 2084255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2085255e72915d4cbddceb435e13d81601755714e9fSE Android } 2086fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2087fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* If current cond_node_t is of tunable, its effective branch 2088fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * has been appended to its home decl->avrules list during link 2089fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * and now we should just skip it. */ 2090fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (cn->flags & COND_NODE_FLAGS_TUNABLE) 2091fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley return 0; 2092fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2093255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_normalize_expr(state->base, cn)) { 2094255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Error while normalizing conditional"); 2095255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2096255e72915d4cbddceb435e13d81601755714e9fSE Android } 2097255e72915d4cbddceb435e13d81601755714e9fSE Android 2098255e72915d4cbddceb435e13d81601755714e9fSE Android /* create a new temporary conditional node with the booleans 2099255e72915d4cbddceb435e13d81601755714e9fSE Android * mapped */ 2100255e72915d4cbddceb435e13d81601755714e9fSE Android tmp = cond_node_create(state->base, cn); 2101255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp) { 2102255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory"); 2103255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2104255e72915d4cbddceb435e13d81601755714e9fSE Android } 2105255e72915d4cbddceb435e13d81601755714e9fSE Android 2106255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_node_map_bools(state, tmp)) { 2107dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley cond_node_destroy(tmp); 2108b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu free(tmp); 2109dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(state->handle, "Error mapping booleans"); 2110255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2111255e72915d4cbddceb435e13d81601755714e9fSE Android } 2112255e72915d4cbddceb435e13d81601755714e9fSE Android 2113255e72915d4cbddceb435e13d81601755714e9fSE Android new_cond = cond_node_search(state->out, state->out->cond_list, tmp); 2114255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_cond) { 2115255e72915d4cbddceb435e13d81601755714e9fSE Android cond_node_destroy(tmp); 2116255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp); 2117255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2118255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2119255e72915d4cbddceb435e13d81601755714e9fSE Android } 2120255e72915d4cbddceb435e13d81601755714e9fSE Android cond_node_destroy(tmp); 2121255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp); 2122255e72915d4cbddceb435e13d81601755714e9fSE Android 2123255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_avrule_list_copy 2124255e72915d4cbddceb435e13d81601755714e9fSE Android (state->out, cn->avtrue_list, &state->out->te_cond_avtab, 2125255e72915d4cbddceb435e13d81601755714e9fSE Android &new_cond->true_list, &new_cond->false_list, state->typemap, 2126255e72915d4cbddceb435e13d81601755714e9fSE Android new_cond->cur_state, state)) 2127255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2128255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_avrule_list_copy 2129255e72915d4cbddceb435e13d81601755714e9fSE Android (state->out, cn->avfalse_list, &state->out->te_cond_avtab, 2130255e72915d4cbddceb435e13d81601755714e9fSE Android &new_cond->false_list, &new_cond->true_list, state->typemap, 2131255e72915d4cbddceb435e13d81601755714e9fSE Android !new_cond->cur_state, state)) 2132255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2133255e72915d4cbddceb435e13d81601755714e9fSE Android 2134255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2135255e72915d4cbddceb435e13d81601755714e9fSE Android} 2136255e72915d4cbddceb435e13d81601755714e9fSE Android 2137255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int context_copy(context_struct_t * dst, context_struct_t * src, 2138255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t * state) 2139255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2140255e72915d4cbddceb435e13d81601755714e9fSE Android dst->user = state->usermap[src->user - 1]; 2141255e72915d4cbddceb435e13d81601755714e9fSE Android dst->role = state->rolemap[src->role - 1]; 2142255e72915d4cbddceb435e13d81601755714e9fSE Android dst->type = state->typemap[src->type - 1]; 2143255e72915d4cbddceb435e13d81601755714e9fSE Android return mls_context_cpy(dst, src); 2144255e72915d4cbddceb435e13d81601755714e9fSE Android} 2145255e72915d4cbddceb435e13d81601755714e9fSE Android 2146255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int ocontext_copy_xen(expand_state_t *state) 2147255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2148255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 2149255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *n, *l; 2150255e72915d4cbddceb435e13d81601755714e9fSE Android 2151255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < OCON_NUM; i++) { 2152255e72915d4cbddceb435e13d81601755714e9fSE Android l = NULL; 2153255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = state->base->ocontexts[i]; c; c = c->next) { 2154255e72915d4cbddceb435e13d81601755714e9fSE Android n = malloc(sizeof(ocontext_t)); 2155255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n) { 2156255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2157255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2158255e72915d4cbddceb435e13d81601755714e9fSE Android } 2159255e72915d4cbddceb435e13d81601755714e9fSE Android memset(n, 0, sizeof(ocontext_t)); 2160255e72915d4cbddceb435e13d81601755714e9fSE Android if (l) 2161255e72915d4cbddceb435e13d81601755714e9fSE Android l->next = n; 2162255e72915d4cbddceb435e13d81601755714e9fSE Android else 2163255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->ocontexts[i] = n; 2164255e72915d4cbddceb435e13d81601755714e9fSE Android l = n; 2165255e72915d4cbddceb435e13d81601755714e9fSE Android switch (i) { 2166255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_XEN_ISID: 21674ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (c->context[0].user == 0) { 21684ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ERR(state->handle, 21694ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley "Missing context for %s initial sid", 21704ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley c->u.name); 21714ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return -1; 21724ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 2173255e72915d4cbddceb435e13d81601755714e9fSE Android n->sid[0] = c->sid[0]; 2174255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2175255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_XEN_PIRQ: 2176255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.pirq = c->u.pirq; 2177255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2178255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_XEN_IOPORT: 2179255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.ioport.low_ioport = c->u.ioport.low_ioport; 2180255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.ioport.high_ioport = 2181255e72915d4cbddceb435e13d81601755714e9fSE Android c->u.ioport.high_ioport; 2182255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2183255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_XEN_IOMEM: 2184255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.iomem.low_iomem = c->u.iomem.low_iomem; 2185255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.iomem.high_iomem = c->u.iomem.high_iomem; 2186255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2187255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_XEN_PCIDEVICE: 2188255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.device = c->u.device; 2189255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2190255e72915d4cbddceb435e13d81601755714e9fSE Android default: 2191255e72915d4cbddceb435e13d81601755714e9fSE Android /* shouldn't get here */ 2192255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Unknown ocontext"); 2193255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2194255e72915d4cbddceb435e13d81601755714e9fSE Android } 21954ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (context_copy(&n->context[0], &c->context[0], 21964ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley state)) { 21974ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ERR(state->handle, "Out of memory!"); 21984ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return -1; 21994ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 2200255e72915d4cbddceb435e13d81601755714e9fSE Android } 2201255e72915d4cbddceb435e13d81601755714e9fSE Android } 2202255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2203255e72915d4cbddceb435e13d81601755714e9fSE Android} 2204255e72915d4cbddceb435e13d81601755714e9fSE Android 2205255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int ocontext_copy_selinux(expand_state_t *state) 2206255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2207255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 2208255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *n, *l; 2209255e72915d4cbddceb435e13d81601755714e9fSE Android 2210255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < OCON_NUM; i++) { 2211255e72915d4cbddceb435e13d81601755714e9fSE Android l = NULL; 2212255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = state->base->ocontexts[i]; c; c = c->next) { 2213255e72915d4cbddceb435e13d81601755714e9fSE Android n = malloc(sizeof(ocontext_t)); 2214255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n) { 2215255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2216255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2217255e72915d4cbddceb435e13d81601755714e9fSE Android } 2218255e72915d4cbddceb435e13d81601755714e9fSE Android memset(n, 0, sizeof(ocontext_t)); 2219255e72915d4cbddceb435e13d81601755714e9fSE Android if (l) 2220255e72915d4cbddceb435e13d81601755714e9fSE Android l->next = n; 2221255e72915d4cbddceb435e13d81601755714e9fSE Android else 2222255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->ocontexts[i] = n; 2223255e72915d4cbddceb435e13d81601755714e9fSE Android l = n; 2224255e72915d4cbddceb435e13d81601755714e9fSE Android switch (i) { 2225255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_ISID: 22264ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (c->context[0].user == 0) { 22274ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ERR(state->handle, 22284ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley "Missing context for %s initial sid", 22294ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley c->u.name); 22304ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return -1; 22314ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 2232255e72915d4cbddceb435e13d81601755714e9fSE Android n->sid[0] = c->sid[0]; 2233255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2234255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_FS: /* FALLTHROUGH */ 2235255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_NETIF: 2236255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.name = strdup(c->u.name); 2237255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n->u.name) { 2238255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2239255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2240255e72915d4cbddceb435e13d81601755714e9fSE Android } 2241255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_copy 2242255e72915d4cbddceb435e13d81601755714e9fSE Android (&n->context[1], &c->context[1], state)) { 2243255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2244255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2245255e72915d4cbddceb435e13d81601755714e9fSE Android } 2246255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2247255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_PORT: 2248255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.port.protocol = c->u.port.protocol; 2249255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.port.low_port = c->u.port.low_port; 2250255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.port.high_port = c->u.port.high_port; 2251255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2252255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_NODE: 2253255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.node.addr = c->u.node.addr; 2254255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.node.mask = c->u.node.mask; 2255255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2256255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_FSUSE: 2257255e72915d4cbddceb435e13d81601755714e9fSE Android n->v.behavior = c->v.behavior; 2258255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.name = strdup(c->u.name); 2259255e72915d4cbddceb435e13d81601755714e9fSE Android if (!n->u.name) { 2260255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2261255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2262255e72915d4cbddceb435e13d81601755714e9fSE Android } 2263255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2264255e72915d4cbddceb435e13d81601755714e9fSE Android case OCON_NODE6: 2265255e72915d4cbddceb435e13d81601755714e9fSE Android for (j = 0; j < 4; j++) 2266255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.node6.addr[j] = c->u.node6.addr[j]; 2267255e72915d4cbddceb435e13d81601755714e9fSE Android for (j = 0; j < 4; j++) 2268255e72915d4cbddceb435e13d81601755714e9fSE Android n->u.node6.mask[j] = c->u.node6.mask[j]; 2269255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2270255e72915d4cbddceb435e13d81601755714e9fSE Android default: 2271255e72915d4cbddceb435e13d81601755714e9fSE Android /* shouldn't get here */ 2272255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Unknown ocontext"); 2273255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2274255e72915d4cbddceb435e13d81601755714e9fSE Android } 22754ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (context_copy(&n->context[0], &c->context[0], state)) { 22764ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley ERR(state->handle, "Out of memory!"); 22774ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley return -1; 22784ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley } 2279255e72915d4cbddceb435e13d81601755714e9fSE Android } 2280255e72915d4cbddceb435e13d81601755714e9fSE Android } 2281255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2282255e72915d4cbddceb435e13d81601755714e9fSE Android} 2283255e72915d4cbddceb435e13d81601755714e9fSE Android 2284255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int ocontext_copy(expand_state_t *state, uint32_t target) 2285255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2286255e72915d4cbddceb435e13d81601755714e9fSE Android int rc = -1; 2287255e72915d4cbddceb435e13d81601755714e9fSE Android switch (target) { 2288255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_TARGET_SELINUX: 2289255e72915d4cbddceb435e13d81601755714e9fSE Android rc = ocontext_copy_selinux(state); 2290255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2291255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_TARGET_XEN: 2292255e72915d4cbddceb435e13d81601755714e9fSE Android rc = ocontext_copy_xen(state); 2293255e72915d4cbddceb435e13d81601755714e9fSE Android break; 2294255e72915d4cbddceb435e13d81601755714e9fSE Android default: 2295255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Unknown target"); 2296255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2297255e72915d4cbddceb435e13d81601755714e9fSE Android } 2298255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 2299255e72915d4cbddceb435e13d81601755714e9fSE Android} 2300255e72915d4cbddceb435e13d81601755714e9fSE Android 2301255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int genfs_copy(expand_state_t * state) 2302255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2303255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *newc, *l; 2304255e72915d4cbddceb435e13d81601755714e9fSE Android genfs_t *genfs, *newgenfs, *end; 2305255e72915d4cbddceb435e13d81601755714e9fSE Android 2306255e72915d4cbddceb435e13d81601755714e9fSE Android end = NULL; 2307255e72915d4cbddceb435e13d81601755714e9fSE Android for (genfs = state->base->genfs; genfs; genfs = genfs->next) { 2308255e72915d4cbddceb435e13d81601755714e9fSE Android newgenfs = malloc(sizeof(genfs_t)); 2309255e72915d4cbddceb435e13d81601755714e9fSE Android if (!newgenfs) { 2310255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2311255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2312255e72915d4cbddceb435e13d81601755714e9fSE Android } 2313255e72915d4cbddceb435e13d81601755714e9fSE Android memset(newgenfs, 0, sizeof(genfs_t)); 2314255e72915d4cbddceb435e13d81601755714e9fSE Android newgenfs->fstype = strdup(genfs->fstype); 2315255e72915d4cbddceb435e13d81601755714e9fSE Android if (!newgenfs->fstype) { 2316b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu free(newgenfs); 2317dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley ERR(state->handle, "Out of memory!"); 2318255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2319255e72915d4cbddceb435e13d81601755714e9fSE Android } 2320dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (!end) 2321dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley state->out->genfs = newgenfs; 2322dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley else 2323dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley end->next = newgenfs; 2324dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley end = newgenfs; 2325255e72915d4cbddceb435e13d81601755714e9fSE Android 2326255e72915d4cbddceb435e13d81601755714e9fSE Android l = NULL; 2327255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = genfs->head; c; c = c->next) { 2328255e72915d4cbddceb435e13d81601755714e9fSE Android newc = malloc(sizeof(ocontext_t)); 2329255e72915d4cbddceb435e13d81601755714e9fSE Android if (!newc) { 2330255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2331255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2332255e72915d4cbddceb435e13d81601755714e9fSE Android } 2333255e72915d4cbddceb435e13d81601755714e9fSE Android memset(newc, 0, sizeof(ocontext_t)); 2334255e72915d4cbddceb435e13d81601755714e9fSE Android newc->u.name = strdup(c->u.name); 2335255e72915d4cbddceb435e13d81601755714e9fSE Android if (!newc->u.name) { 2336255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2337b0e0162a246f2c051427154909c0ecd694cc4805Alice Chu free(newc); 2338255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2339255e72915d4cbddceb435e13d81601755714e9fSE Android } 2340255e72915d4cbddceb435e13d81601755714e9fSE Android newc->v.sclass = c->v.sclass; 2341255e72915d4cbddceb435e13d81601755714e9fSE Android context_copy(&newc->context[0], &c->context[0], state); 2342255e72915d4cbddceb435e13d81601755714e9fSE Android if (l) 2343255e72915d4cbddceb435e13d81601755714e9fSE Android l->next = newc; 2344255e72915d4cbddceb435e13d81601755714e9fSE Android else 2345255e72915d4cbddceb435e13d81601755714e9fSE Android newgenfs->head = newc; 2346255e72915d4cbddceb435e13d81601755714e9fSE Android l = newc; 2347255e72915d4cbddceb435e13d81601755714e9fSE Android } 2348255e72915d4cbddceb435e13d81601755714e9fSE Android } 2349255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2350255e72915d4cbddceb435e13d81601755714e9fSE Android} 2351255e72915d4cbddceb435e13d81601755714e9fSE Android 2352255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int type_attr_map(hashtab_key_t key 2353255e72915d4cbddceb435e13d81601755714e9fSE Android __attribute__ ((unused)), hashtab_datum_t datum, 2354255e72915d4cbddceb435e13d81601755714e9fSE Android void *ptr) 2355255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2356255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *type; 2357255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t *state = ptr; 2358255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *p = state->out; 2359255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 2360255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *tnode; 2361255e72915d4cbddceb435e13d81601755714e9fSE Android 2362255e72915d4cbddceb435e13d81601755714e9fSE Android type = (type_datum_t *) datum; 2363255e72915d4cbddceb435e13d81601755714e9fSE Android if (type->flavor == TYPE_ATTRIB) { 2364255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&p->attr_type_map[type->s.value - 1], 2365255e72915d4cbddceb435e13d81601755714e9fSE Android &type->types)) { 2366255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2367255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2368255e72915d4cbddceb435e13d81601755714e9fSE Android } 2369255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&type->types, tnode, i) { 2370255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, i)) 2371255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2372255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&p->type_attr_map[i], 2373255e72915d4cbddceb435e13d81601755714e9fSE Android type->s.value - 1, 1)) { 2374255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of memory!"); 2375255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2376255e72915d4cbddceb435e13d81601755714e9fSE Android } 2377255e72915d4cbddceb435e13d81601755714e9fSE Android } 2378255e72915d4cbddceb435e13d81601755714e9fSE Android } 2379255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2380255e72915d4cbddceb435e13d81601755714e9fSE Android} 2381255e72915d4cbddceb435e13d81601755714e9fSE Android 2382255e72915d4cbddceb435e13d81601755714e9fSE Android/* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy. 2383255e72915d4cbddceb435e13d81601755714e9fSE Android * this should not be called until after all the blocks have been processed and the attributes in target policy 2384255e72915d4cbddceb435e13d81601755714e9fSE Android * are complete. */ 2385255e72915d4cbddceb435e13d81601755714e9fSE Androidint expand_convert_type_set(policydb_t * p, uint32_t * typemap, 2386255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_t * set, ebitmap_t * types, 2387255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned char alwaysexpand) 2388255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2389255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_t tmpset; 2390255e72915d4cbddceb435e13d81601755714e9fSE Android 2391255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_init(&tmpset); 2392255e72915d4cbddceb435e13d81601755714e9fSE Android 2393255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&set->types, &tmpset.types, typemap)) 2394255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2395255e72915d4cbddceb435e13d81601755714e9fSE Android 2396255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&set->negset, &tmpset.negset, typemap)) 2397255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2398255e72915d4cbddceb435e13d81601755714e9fSE Android 2399255e72915d4cbddceb435e13d81601755714e9fSE Android tmpset.flags = set->flags; 2400255e72915d4cbddceb435e13d81601755714e9fSE Android 2401255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_expand(&tmpset, types, p, alwaysexpand)) 2402255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2403255e72915d4cbddceb435e13d81601755714e9fSE Android 2404255e72915d4cbddceb435e13d81601755714e9fSE Android type_set_destroy(&tmpset); 2405255e72915d4cbddceb435e13d81601755714e9fSE Android 2406255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2407255e72915d4cbddceb435e13d81601755714e9fSE Android} 2408255e72915d4cbddceb435e13d81601755714e9fSE Android 2409255e72915d4cbddceb435e13d81601755714e9fSE Android/* Expand a rule into a given avtab - checking for conflicting type 2410255e72915d4cbddceb435e13d81601755714e9fSE Android * rules. Return 1 on success, 0 if the rule conflicts with something 2411255e72915d4cbddceb435e13d81601755714e9fSE Android * (and hence was not added), or -1 on error. */ 2412255e72915d4cbddceb435e13d81601755714e9fSE Androidint expand_rule(sepol_handle_t * handle, 2413255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * source_pol, 2414255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t * source_rule, avtab_t * dest_avtab, 2415255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** cond, cond_av_list_t ** other, int enabled) 2416255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2417255e72915d4cbddceb435e13d81601755714e9fSE Android int retval; 2418255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t stypes, ttypes; 2419255e72915d4cbddceb435e13d81601755714e9fSE Android 2420255e72915d4cbddceb435e13d81601755714e9fSE Android if (source_rule->specified & AVRULE_NEVERALLOW) 2421255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 2422255e72915d4cbddceb435e13d81601755714e9fSE Android 2423255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&stypes); 2424255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&ttypes); 2425255e72915d4cbddceb435e13d81601755714e9fSE Android 2426255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_expand(&source_rule->stypes, &stypes, source_pol, 1)) 2427255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2428255e72915d4cbddceb435e13d81601755714e9fSE Android if (type_set_expand(&source_rule->ttypes, &ttypes, source_pol, 1)) 2429255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2430255e72915d4cbddceb435e13d81601755714e9fSE Android retval = expand_rule_helper(handle, source_pol, NULL, 2431255e72915d4cbddceb435e13d81601755714e9fSE Android source_rule, dest_avtab, 2432255e72915d4cbddceb435e13d81601755714e9fSE Android cond, other, enabled, &stypes, &ttypes); 2433255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 2434255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&ttypes); 2435255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 2436255e72915d4cbddceb435e13d81601755714e9fSE Android} 2437255e72915d4cbddceb435e13d81601755714e9fSE Android 2438255e72915d4cbddceb435e13d81601755714e9fSE Android/* Expand a role set into an ebitmap containing the roles. 2439255e72915d4cbddceb435e13d81601755714e9fSE Android * This handles the attribute and flags. 2440255e72915d4cbddceb435e13d81601755714e9fSE Android * Attribute expansion depends on if the rolemap is available. 2441255e72915d4cbddceb435e13d81601755714e9fSE Android * During module compile the rolemap is not available, the 2442255e72915d4cbddceb435e13d81601755714e9fSE Android * possible duplicates of a regular role and the role attribute 2443255e72915d4cbddceb435e13d81601755714e9fSE Android * the regular role belongs to could be properly handled by 2444255e72915d4cbddceb435e13d81601755714e9fSE Android * copy_role_trans and copy_role_allow. 2445255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2446255e72915d4cbddceb435e13d81601755714e9fSE Androidint role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap) 2447255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2448255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 2449255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *rnode; 2450255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t mapped_roles, roles; 2451255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *p = out; 2452255e72915d4cbddceb435e13d81601755714e9fSE Android role_datum_t *role; 2453255e72915d4cbddceb435e13d81601755714e9fSE Android 2454255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(r); 2455255e72915d4cbddceb435e13d81601755714e9fSE Android 2456255e72915d4cbddceb435e13d81601755714e9fSE Android if (x->flags & ROLE_STAR) { 2457255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < p->p_roles.nprim++; i++) 2458255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(r, i, 1)) 2459255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2460255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2461255e72915d4cbddceb435e13d81601755714e9fSE Android } 2462255e72915d4cbddceb435e13d81601755714e9fSE Android 2463255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&mapped_roles); 2464255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&roles); 2465255e72915d4cbddceb435e13d81601755714e9fSE Android 2466255e72915d4cbddceb435e13d81601755714e9fSE Android if (rolemap) { 2467255e72915d4cbddceb435e13d81601755714e9fSE Android assert(base != NULL); 2468255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&x->roles, rnode, i) { 2469255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, i)) { 2470255e72915d4cbddceb435e13d81601755714e9fSE Android /* take advantage of p_role_val_to_struct[] 2471255e72915d4cbddceb435e13d81601755714e9fSE Android * of the base module */ 2472255e72915d4cbddceb435e13d81601755714e9fSE Android role = base->role_val_to_struct[i]; 2473255e72915d4cbddceb435e13d81601755714e9fSE Android assert(role != NULL); 2474255e72915d4cbddceb435e13d81601755714e9fSE Android if (role->flavor == ROLE_ATTRIB) { 2475255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union(&roles, 2476255e72915d4cbddceb435e13d81601755714e9fSE Android &role->roles)) 2477255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 2478255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2479255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&roles, i, 1)) 2480255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 2481255e72915d4cbddceb435e13d81601755714e9fSE Android } 2482255e72915d4cbddceb435e13d81601755714e9fSE Android } 2483255e72915d4cbddceb435e13d81601755714e9fSE Android } 2484255e72915d4cbddceb435e13d81601755714e9fSE Android if (map_ebitmap(&roles, &mapped_roles, rolemap)) 2485255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 2486255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2487255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&mapped_roles, &x->roles)) 2488255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 2489255e72915d4cbddceb435e13d81601755714e9fSE Android } 2490255e72915d4cbddceb435e13d81601755714e9fSE Android 2491255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&mapped_roles, rnode, i) { 2492255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(rnode, i)) { 2493255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(r, i, 1)) 2494255e72915d4cbddceb435e13d81601755714e9fSE Android goto bad; 2495255e72915d4cbddceb435e13d81601755714e9fSE Android } 2496255e72915d4cbddceb435e13d81601755714e9fSE Android } 2497255e72915d4cbddceb435e13d81601755714e9fSE Android 2498255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&mapped_roles); 2499255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&roles); 2500255e72915d4cbddceb435e13d81601755714e9fSE Android 2501255e72915d4cbddceb435e13d81601755714e9fSE Android /* if role is to be complimented, invert the entire bitmap here */ 2502255e72915d4cbddceb435e13d81601755714e9fSE Android if (x->flags & ROLE_COMP) { 2503255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < ebitmap_length(r); i++) { 2504255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_get_bit(r, i)) { 2505255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(r, i, 0)) 2506255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2507255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2508255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(r, i, 1)) 2509255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2510255e72915d4cbddceb435e13d81601755714e9fSE Android } 2511255e72915d4cbddceb435e13d81601755714e9fSE Android } 2512255e72915d4cbddceb435e13d81601755714e9fSE Android } 2513255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2514255e72915d4cbddceb435e13d81601755714e9fSE Android 2515255e72915d4cbddceb435e13d81601755714e9fSE Androidbad: 2516255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&mapped_roles); 2517255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&roles); 2518255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2519255e72915d4cbddceb435e13d81601755714e9fSE Android} 2520255e72915d4cbddceb435e13d81601755714e9fSE Android 2521255e72915d4cbddceb435e13d81601755714e9fSE Android/* Expand a type set into an ebitmap containing the types. This 2522255e72915d4cbddceb435e13d81601755714e9fSE Android * handles the negset, attributes, and flags. 2523255e72915d4cbddceb435e13d81601755714e9fSE Android * Attribute expansion depends on several factors: 2524255e72915d4cbddceb435e13d81601755714e9fSE Android * - if alwaysexpand is 1, then they will be expanded, 2525255e72915d4cbddceb435e13d81601755714e9fSE Android * - if the type set has a negset or flags, then they will be expanded, 2526255e72915d4cbddceb435e13d81601755714e9fSE Android * - otherwise, they will not be expanded. 2527255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2528255e72915d4cbddceb435e13d81601755714e9fSE Androidint type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, 2529255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned char alwaysexpand) 2530255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2531255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 2532255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t types, neg_types; 2533255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *tnode; 2534255e72915d4cbddceb435e13d81601755714e9fSE Android 2535255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&types); 2536255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(t); 2537255e72915d4cbddceb435e13d81601755714e9fSE Android 2538255e72915d4cbddceb435e13d81601755714e9fSE Android if (alwaysexpand || ebitmap_length(&set->negset) || set->flags) { 2539255e72915d4cbddceb435e13d81601755714e9fSE Android /* First go through the types and OR all the attributes to types */ 2540255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&set->types, tnode, i) { 2541255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(tnode, i)) { 2542255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->type_val_to_struct[i]->flavor == 2543255e72915d4cbddceb435e13d81601755714e9fSE Android TYPE_ATTRIB) { 2544255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union 2545255e72915d4cbddceb435e13d81601755714e9fSE Android (&types, 2546255e72915d4cbddceb435e13d81601755714e9fSE Android &p->type_val_to_struct[i]-> 2547255e72915d4cbddceb435e13d81601755714e9fSE Android types)) { 2548255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2549255e72915d4cbddceb435e13d81601755714e9fSE Android } 2550255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2551255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&types, i, 1)) { 2552255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2553255e72915d4cbddceb435e13d81601755714e9fSE Android } 2554255e72915d4cbddceb435e13d81601755714e9fSE Android } 2555255e72915d4cbddceb435e13d81601755714e9fSE Android } 2556255e72915d4cbddceb435e13d81601755714e9fSE Android } 2557255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2558255e72915d4cbddceb435e13d81601755714e9fSE Android /* No expansion of attributes, just copy the set as is. */ 2559255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&types, &set->types)) 2560255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2561255e72915d4cbddceb435e13d81601755714e9fSE Android } 2562255e72915d4cbddceb435e13d81601755714e9fSE Android 2563255e72915d4cbddceb435e13d81601755714e9fSE Android /* Now do the same thing for negset */ 2564255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&neg_types); 2565255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&set->negset, tnode, i) { 2566255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(tnode, i)) { 2567255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->type_val_to_struct[i] && 2568255e72915d4cbddceb435e13d81601755714e9fSE Android p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { 2569255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_union 2570255e72915d4cbddceb435e13d81601755714e9fSE Android (&neg_types, 2571255e72915d4cbddceb435e13d81601755714e9fSE Android &p->type_val_to_struct[i]->types)) { 2572255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2573255e72915d4cbddceb435e13d81601755714e9fSE Android } 2574255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2575255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&neg_types, i, 1)) { 2576255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2577255e72915d4cbddceb435e13d81601755714e9fSE Android } 2578255e72915d4cbddceb435e13d81601755714e9fSE Android } 2579255e72915d4cbddceb435e13d81601755714e9fSE Android } 2580255e72915d4cbddceb435e13d81601755714e9fSE Android } 2581255e72915d4cbddceb435e13d81601755714e9fSE Android 2582255e72915d4cbddceb435e13d81601755714e9fSE Android if (set->flags & TYPE_STAR) { 2583255e72915d4cbddceb435e13d81601755714e9fSE Android /* set all types not in neg_types */ 2584255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < p->p_types.nprim; i++) { 2585255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_get_bit(&neg_types, i)) 2586255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2587255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->type_val_to_struct[i] && 2588255e72915d4cbddceb435e13d81601755714e9fSE Android p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) 2589255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2590255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(t, i, 1)) 2591255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2592255e72915d4cbddceb435e13d81601755714e9fSE Android } 2593255e72915d4cbddceb435e13d81601755714e9fSE Android goto out; 2594255e72915d4cbddceb435e13d81601755714e9fSE Android } 2595255e72915d4cbddceb435e13d81601755714e9fSE Android 2596255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(&types, tnode, i) { 2597255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_node_get_bit(tnode, i) 2598255e72915d4cbddceb435e13d81601755714e9fSE Android && (!ebitmap_get_bit(&neg_types, i))) 2599255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(t, i, 1)) 2600255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2601255e72915d4cbddceb435e13d81601755714e9fSE Android } 2602255e72915d4cbddceb435e13d81601755714e9fSE Android 2603255e72915d4cbddceb435e13d81601755714e9fSE Android if (set->flags & TYPE_COMP) { 2604255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < p->p_types.nprim; i++) { 2605255e72915d4cbddceb435e13d81601755714e9fSE Android if (p->type_val_to_struct[i] && 2606255e72915d4cbddceb435e13d81601755714e9fSE Android p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { 2607255e72915d4cbddceb435e13d81601755714e9fSE Android assert(!ebitmap_get_bit(t, i)); 2608255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 2609255e72915d4cbddceb435e13d81601755714e9fSE Android } 2610255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_get_bit(t, i)) { 2611255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(t, i, 0)) 2612255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2613255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2614255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(t, i, 1)) 2615255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2616255e72915d4cbddceb435e13d81601755714e9fSE Android } 2617255e72915d4cbddceb435e13d81601755714e9fSE Android } 2618255e72915d4cbddceb435e13d81601755714e9fSE Android } 2619255e72915d4cbddceb435e13d81601755714e9fSE Android 2620255e72915d4cbddceb435e13d81601755714e9fSE Android out: 2621255e72915d4cbddceb435e13d81601755714e9fSE Android 2622255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&types); 2623255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&neg_types); 2624255e72915d4cbddceb435e13d81601755714e9fSE Android 2625255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2626255e72915d4cbddceb435e13d81601755714e9fSE Android} 2627255e72915d4cbddceb435e13d81601755714e9fSE Android 2628255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap, 2629255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t * source_rule) 2630255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2631255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t stypes, ttypes; 2632255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t *avrule; 2633255e72915d4cbddceb435e13d81601755714e9fSE Android class_perm_node_t *cur_perm, *new_perm, *tail_perm; 2634255e72915d4cbddceb435e13d81601755714e9fSE Android 2635255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&stypes); 2636255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&ttypes); 2637255e72915d4cbddceb435e13d81601755714e9fSE Android 2638255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set 2639255e72915d4cbddceb435e13d81601755714e9fSE Android (dest_pol, typemap, &source_rule->stypes, &stypes, 1)) 2640255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2641255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_convert_type_set 2642255e72915d4cbddceb435e13d81601755714e9fSE Android (dest_pol, typemap, &source_rule->ttypes, &ttypes, 1)) 2643255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2644255e72915d4cbddceb435e13d81601755714e9fSE Android 2645255e72915d4cbddceb435e13d81601755714e9fSE Android avrule = (avrule_t *) malloc(sizeof(avrule_t)); 2646255e72915d4cbddceb435e13d81601755714e9fSE Android if (!avrule) 2647255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2648255e72915d4cbddceb435e13d81601755714e9fSE Android 2649255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_init(avrule); 2650255e72915d4cbddceb435e13d81601755714e9fSE Android avrule->specified = AVRULE_NEVERALLOW; 2651255e72915d4cbddceb435e13d81601755714e9fSE Android avrule->line = source_rule->line; 2652255e72915d4cbddceb435e13d81601755714e9fSE Android avrule->flags = source_rule->flags; 2653c71644b06ebd417ef060f3f07472125516f86c41Stephen Smalley avrule->source_line = source_rule->source_line; 26542066a66a2ab0c1b7d691d5a180b0ec1e47b0fb12Nick Kralevich if (source_rule->source_filename) { 26552066a66a2ab0c1b7d691d5a180b0ec1e47b0fb12Nick Kralevich avrule->source_filename = strdup(source_rule->source_filename); 26562066a66a2ab0c1b7d691d5a180b0ec1e47b0fb12Nick Kralevich if (!avrule->source_filename) 26572066a66a2ab0c1b7d691d5a180b0ec1e47b0fb12Nick Kralevich goto err; 26582066a66a2ab0c1b7d691d5a180b0ec1e47b0fb12Nick Kralevich } 2659255e72915d4cbddceb435e13d81601755714e9fSE Android 2660255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&avrule->stypes.types, &stypes)) 2661255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 2662255e72915d4cbddceb435e13d81601755714e9fSE Android 2663255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&avrule->ttypes.types, &ttypes)) 2664255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 2665255e72915d4cbddceb435e13d81601755714e9fSE Android 2666255e72915d4cbddceb435e13d81601755714e9fSE Android cur_perm = source_rule->perms; 2667255e72915d4cbddceb435e13d81601755714e9fSE Android tail_perm = NULL; 2668255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur_perm) { 2669255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm = 2670255e72915d4cbddceb435e13d81601755714e9fSE Android (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 2671255e72915d4cbddceb435e13d81601755714e9fSE Android if (!new_perm) 2672255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 2673255e72915d4cbddceb435e13d81601755714e9fSE Android class_perm_node_init(new_perm); 2674255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm->class = cur_perm->class; 2675255e72915d4cbddceb435e13d81601755714e9fSE Android assert(new_perm->class); 2676255e72915d4cbddceb435e13d81601755714e9fSE Android 2677255e72915d4cbddceb435e13d81601755714e9fSE Android /* once we have modules with permissions we'll need to map the permissions (and classes) */ 2678255e72915d4cbddceb435e13d81601755714e9fSE Android new_perm->data = cur_perm->data; 2679255e72915d4cbddceb435e13d81601755714e9fSE Android 2680255e72915d4cbddceb435e13d81601755714e9fSE Android if (!avrule->perms) 2681255e72915d4cbddceb435e13d81601755714e9fSE Android avrule->perms = new_perm; 2682255e72915d4cbddceb435e13d81601755714e9fSE Android 2683255e72915d4cbddceb435e13d81601755714e9fSE Android if (tail_perm) 2684255e72915d4cbddceb435e13d81601755714e9fSE Android tail_perm->next = new_perm; 2685255e72915d4cbddceb435e13d81601755714e9fSE Android tail_perm = new_perm; 2686255e72915d4cbddceb435e13d81601755714e9fSE Android cur_perm = cur_perm->next; 2687255e72915d4cbddceb435e13d81601755714e9fSE Android } 2688255e72915d4cbddceb435e13d81601755714e9fSE Android 2689255e72915d4cbddceb435e13d81601755714e9fSE Android /* just prepend the avrule to the first branch; it'll never be 2690255e72915d4cbddceb435e13d81601755714e9fSE Android written to disk */ 2691255e72915d4cbddceb435e13d81601755714e9fSE Android if (!dest_pol->global->branch_list->avrules) 2692255e72915d4cbddceb435e13d81601755714e9fSE Android dest_pol->global->branch_list->avrules = avrule; 2693255e72915d4cbddceb435e13d81601755714e9fSE Android else { 2694255e72915d4cbddceb435e13d81601755714e9fSE Android avrule->next = dest_pol->global->branch_list->avrules; 2695255e72915d4cbddceb435e13d81601755714e9fSE Android dest_pol->global->branch_list->avrules = avrule; 2696255e72915d4cbddceb435e13d81601755714e9fSE Android } 2697255e72915d4cbddceb435e13d81601755714e9fSE Android 2698255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 2699255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&ttypes); 2700255e72915d4cbddceb435e13d81601755714e9fSE Android 2701255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 2702255e72915d4cbddceb435e13d81601755714e9fSE Android 2703255e72915d4cbddceb435e13d81601755714e9fSE Android err: 2704255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&stypes); 2705255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&ttypes); 2706255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&avrule->stypes.types); 2707255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_destroy(&avrule->ttypes.types); 2708255e72915d4cbddceb435e13d81601755714e9fSE Android cur_perm = avrule->perms; 2709255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur_perm) { 2710255e72915d4cbddceb435e13d81601755714e9fSE Android tail_perm = cur_perm->next; 2711255e72915d4cbddceb435e13d81601755714e9fSE Android free(cur_perm); 2712255e72915d4cbddceb435e13d81601755714e9fSE Android cur_perm = tail_perm; 2713255e72915d4cbddceb435e13d81601755714e9fSE Android } 2714255e72915d4cbddceb435e13d81601755714e9fSE Android free(avrule); 2715255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2716255e72915d4cbddceb435e13d81601755714e9fSE Android} 2717255e72915d4cbddceb435e13d81601755714e9fSE Android 2718255e72915d4cbddceb435e13d81601755714e9fSE Android/* 2719255e72915d4cbddceb435e13d81601755714e9fSE Android * Expands the avrule blocks for a policy. RBAC rules are copied. Neverallow 2720255e72915d4cbddceb435e13d81601755714e9fSE Android * rules are copied or expanded as per the settings in the state object; all 2721255e72915d4cbddceb435e13d81601755714e9fSE Android * other AV rules are expanded. If neverallow rules are expanded, they are not 2722255e72915d4cbddceb435e13d81601755714e9fSE Android * copied, otherwise they are copied for later use by the assertion checker. 2723255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2724255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int copy_and_expand_avrule_block(expand_state_t * state) 2725255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2726255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *curblock = state->base->global; 2727255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *prevblock; 2728255e72915d4cbddceb435e13d81601755714e9fSE Android int retval = -1; 2729255e72915d4cbddceb435e13d81601755714e9fSE Android 2730255e72915d4cbddceb435e13d81601755714e9fSE Android if (avtab_alloc(&state->out->te_avtab, MAX_AVTAB_SIZE)) { 2731255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of Memory!"); 2732255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2733255e72915d4cbddceb435e13d81601755714e9fSE Android } 2734255e72915d4cbddceb435e13d81601755714e9fSE Android 2735255e72915d4cbddceb435e13d81601755714e9fSE Android if (avtab_alloc(&state->out->te_cond_avtab, MAX_AVTAB_SIZE)) { 2736255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, "Out of Memory!"); 2737255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2738255e72915d4cbddceb435e13d81601755714e9fSE Android } 2739255e72915d4cbddceb435e13d81601755714e9fSE Android 2740255e72915d4cbddceb435e13d81601755714e9fSE Android while (curblock) { 2741255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl = curblock->enabled; 2742255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_t *cur_avrule; 2743255e72915d4cbddceb435e13d81601755714e9fSE Android 2744255e72915d4cbddceb435e13d81601755714e9fSE Android if (decl == NULL) { 2745255e72915d4cbddceb435e13d81601755714e9fSE Android /* nothing was enabled within this block */ 2746255e72915d4cbddceb435e13d81601755714e9fSE Android goto cont; 2747255e72915d4cbddceb435e13d81601755714e9fSE Android } 2748255e72915d4cbddceb435e13d81601755714e9fSE Android 2749255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy role allows and role trans */ 2750255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_role_allows(state, decl->role_allow_rules) != 0 || 2751255e72915d4cbddceb435e13d81601755714e9fSE Android copy_role_trans(state, decl->role_tr_rules) != 0) { 2752255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2753255e72915d4cbddceb435e13d81601755714e9fSE Android } 2754255e72915d4cbddceb435e13d81601755714e9fSE Android 2755255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_filename_trans(state, decl->filename_trans_rules)) 2756255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2757255e72915d4cbddceb435e13d81601755714e9fSE Android 2758255e72915d4cbddceb435e13d81601755714e9fSE Android /* expand the range transition rules */ 2759255e72915d4cbddceb435e13d81601755714e9fSE Android if (expand_range_trans(state, decl->range_tr_rules)) 2760255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2761255e72915d4cbddceb435e13d81601755714e9fSE Android 2762255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy rules */ 2763255e72915d4cbddceb435e13d81601755714e9fSE Android cur_avrule = decl->avrules; 2764255e72915d4cbddceb435e13d81601755714e9fSE Android while (cur_avrule != NULL) { 2765255e72915d4cbddceb435e13d81601755714e9fSE Android if (!(state->expand_neverallow) 2766255e72915d4cbddceb435e13d81601755714e9fSE Android && cur_avrule->specified & AVRULE_NEVERALLOW) { 2767255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy this over directly so that assertions are checked later */ 2768255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_neverallow 2769255e72915d4cbddceb435e13d81601755714e9fSE Android (state->out, state->typemap, cur_avrule)) 2770255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(state->handle, 2771255e72915d4cbddceb435e13d81601755714e9fSE Android "Error while copying neverallow."); 2772255e72915d4cbddceb435e13d81601755714e9fSE Android } else { 2773255e72915d4cbddceb435e13d81601755714e9fSE Android if (cur_avrule->specified & AVRULE_NEVERALLOW) { 2774255e72915d4cbddceb435e13d81601755714e9fSE Android state->out->unsupported_format = 1; 2775255e72915d4cbddceb435e13d81601755714e9fSE Android } 2776255e72915d4cbddceb435e13d81601755714e9fSE Android if (convert_and_expand_rule 2777255e72915d4cbddceb435e13d81601755714e9fSE Android (state->handle, state->out, state->typemap, 2778255e72915d4cbddceb435e13d81601755714e9fSE Android cur_avrule, &state->out->te_avtab, NULL, 2779255e72915d4cbddceb435e13d81601755714e9fSE Android NULL, 0, 2780255e72915d4cbddceb435e13d81601755714e9fSE Android state->expand_neverallow) != 2781255e72915d4cbddceb435e13d81601755714e9fSE Android EXPAND_RULE_SUCCESS) { 2782255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2783255e72915d4cbddceb435e13d81601755714e9fSE Android } 2784255e72915d4cbddceb435e13d81601755714e9fSE Android } 2785255e72915d4cbddceb435e13d81601755714e9fSE Android cur_avrule = cur_avrule->next; 2786255e72915d4cbddceb435e13d81601755714e9fSE Android } 2787255e72915d4cbddceb435e13d81601755714e9fSE Android 2788255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy conditional rules */ 2789255e72915d4cbddceb435e13d81601755714e9fSE Android if (cond_node_copy(state, decl->cond_list)) 2790255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2791255e72915d4cbddceb435e13d81601755714e9fSE Android 2792255e72915d4cbddceb435e13d81601755714e9fSE Android cont: 2793255e72915d4cbddceb435e13d81601755714e9fSE Android prevblock = curblock; 2794255e72915d4cbddceb435e13d81601755714e9fSE Android curblock = curblock->next; 2795255e72915d4cbddceb435e13d81601755714e9fSE Android 2796255e72915d4cbddceb435e13d81601755714e9fSE Android if (state->handle && state->handle->expand_consume_base) { 2797255e72915d4cbddceb435e13d81601755714e9fSE Android /* set base top avrule block in case there 2798255e72915d4cbddceb435e13d81601755714e9fSE Android * is an error condition and the policy needs 2799255e72915d4cbddceb435e13d81601755714e9fSE Android * to be destroyed */ 2800255e72915d4cbddceb435e13d81601755714e9fSE Android state->base->global = curblock; 2801255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_destroy(prevblock); 2802255e72915d4cbddceb435e13d81601755714e9fSE Android } 2803255e72915d4cbddceb435e13d81601755714e9fSE Android } 2804255e72915d4cbddceb435e13d81601755714e9fSE Android 2805255e72915d4cbddceb435e13d81601755714e9fSE Android retval = 0; 2806255e72915d4cbddceb435e13d81601755714e9fSE Android 2807255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 2808255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 2809255e72915d4cbddceb435e13d81601755714e9fSE Android} 2810255e72915d4cbddceb435e13d81601755714e9fSE Android 2811255e72915d4cbddceb435e13d81601755714e9fSE Android/* 2812255e72915d4cbddceb435e13d81601755714e9fSE Android * This function allows external users of the library (such as setools) to 2813255e72915d4cbddceb435e13d81601755714e9fSE Android * expand only the avrules and optionally perform expansion of neverallow rules 2814255e72915d4cbddceb435e13d81601755714e9fSE Android * or expand into the same policy for analysis purposes. 2815255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2816255e72915d4cbddceb435e13d81601755714e9fSE Androidint expand_module_avrules(sepol_handle_t * handle, policydb_t * base, 2817255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * out, uint32_t * typemap, 2818255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t * boolmap, uint32_t * rolemap, 2819255e72915d4cbddceb435e13d81601755714e9fSE Android uint32_t * usermap, int verbose, 2820255e72915d4cbddceb435e13d81601755714e9fSE Android int expand_neverallow) 2821255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2822255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t state; 2823255e72915d4cbddceb435e13d81601755714e9fSE Android 2824255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_init(&state); 2825255e72915d4cbddceb435e13d81601755714e9fSE Android 2826255e72915d4cbddceb435e13d81601755714e9fSE Android state.base = base; 2827255e72915d4cbddceb435e13d81601755714e9fSE Android state.out = out; 2828255e72915d4cbddceb435e13d81601755714e9fSE Android state.typemap = typemap; 2829255e72915d4cbddceb435e13d81601755714e9fSE Android state.boolmap = boolmap; 2830255e72915d4cbddceb435e13d81601755714e9fSE Android state.rolemap = rolemap; 2831255e72915d4cbddceb435e13d81601755714e9fSE Android state.usermap = usermap; 2832255e72915d4cbddceb435e13d81601755714e9fSE Android state.handle = handle; 2833255e72915d4cbddceb435e13d81601755714e9fSE Android state.verbose = verbose; 2834255e72915d4cbddceb435e13d81601755714e9fSE Android state.expand_neverallow = expand_neverallow; 2835255e72915d4cbddceb435e13d81601755714e9fSE Android 2836255e72915d4cbddceb435e13d81601755714e9fSE Android return copy_and_expand_avrule_block(&state); 2837255e72915d4cbddceb435e13d81601755714e9fSE Android} 2838255e72915d4cbddceb435e13d81601755714e9fSE Android 2839fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalleystatic void discard_tunables(sepol_handle_t *sh, policydb_t *pol) 2840fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley{ 2841fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley avrule_block_t *block; 2842fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley avrule_decl_t *decl; 2843fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cond_node_t *cur_node; 2844fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cond_expr_t *cur_expr; 2845fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley int cur_state, preserve_tunables = 0; 2846fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley avrule_t *tail, *to_be_appended; 2847fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2848fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (sh && sh->preserve_tunables) 2849fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley preserve_tunables = 1; 2850fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2851fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* Iterate through all cond_node of all enabled decls, if a cond_node 2852fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * is about tunable, calculate its state value and concatenate one of 2853fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * its avrule list to the current decl->avrules list. On the other 2854fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * hand, the disabled unused branch of a tunable would be discarded. 2855fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * 2856fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * Note, such tunable cond_node would be skipped over in expansion, 2857fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * so we won't have to worry about removing it from decl->cond_list 2858fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * here :-) 2859fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * 2860fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * If tunables are requested to be preserved then they would be 2861fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * "transformed" as booleans by having their TUNABLE flag cleared. 2862fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley */ 2863fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley for (block = pol->global; block != NULL; block = block->next) { 2864fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley decl = block->enabled; 2865fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (decl == NULL || decl->enabled == 0) 2866fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley continue; 2867fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2868fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley tail = decl->avrules; 2869fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley while (tail && tail->next) 2870fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley tail = tail->next; 2871fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2872fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley for (cur_node = decl->cond_list; cur_node != NULL; 2873fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_node = cur_node->next) { 2874fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley int booleans, tunables, i; 2875fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cond_bool_datum_t *booldatum; 2876fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cond_bool_datum_t *tmp[COND_EXPR_MAXDEPTH]; 2877fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2878fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley booleans = tunables = 0; 2879fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley memset(tmp, 0, sizeof(cond_bool_datum_t *) * COND_EXPR_MAXDEPTH); 2880fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2881fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley for (cur_expr = cur_node->expr; cur_expr != NULL; 2882fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_expr = cur_expr->next) { 2883fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (cur_expr->expr_type != COND_BOOL) 2884fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley continue; 2885fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley booldatum = pol->bool_val_to_struct[cur_expr->bool - 1]; 2886fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (booldatum->flags & COND_BOOL_FLAGS_TUNABLE) 2887fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley tmp[tunables++] = booldatum; 2888fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley else 2889fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley booleans++; 2890fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 2891fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2892fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* bool_copy_callback() at link phase has ensured 2893fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * that no mixture of tunables and booleans in one 2894fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * expression. However, this would be broken by the 2895fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * request to preserve tunables */ 2896fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (!preserve_tunables) 2897fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley assert(!(booleans && tunables)); 2898fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2899fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (booleans || preserve_tunables) { 2900fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_node->flags &= ~COND_NODE_FLAGS_TUNABLE; 2901fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (tunables) { 2902fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley for (i = 0; i < tunables; i++) 2903fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley tmp[i]->flags &= ~COND_BOOL_FLAGS_TUNABLE; 2904fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 2905fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } else { 2906fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_node->flags |= COND_NODE_FLAGS_TUNABLE; 2907fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_state = cond_evaluate_expr(pol, cur_node->expr); 2908fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (cur_state == -1) { 2909fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley printf("Expression result was " 2910fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley "undefined, skipping all" 2911fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley "rules\n"); 2912fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley continue; 2913fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 2914fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2915fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley to_be_appended = (cur_state == 1) ? 2916fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_node->avtrue_list : cur_node->avfalse_list; 2917fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2918fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (tail) 2919fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley tail->next = to_be_appended; 2920fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley else 2921fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley tail = decl->avrules = to_be_appended; 2922fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2923fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* Now that the effective branch has been 2924fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * appended, neutralize its original pointer */ 2925fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley if (cur_state == 1) 2926fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_node->avtrue_list = NULL; 2927fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley else 2928fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley cur_node->avfalse_list = NULL; 2929fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2930fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* Update the tail of decl->avrules for 2931fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * further concatenation */ 2932fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley while (tail && tail->next) 2933fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley tail = tail->next; 2934fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 2935fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 2936fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley } 2937fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley} 2938fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2939255e72915d4cbddceb435e13d81601755714e9fSE Android/* Linking should always be done before calling expand, even if 2940255e72915d4cbddceb435e13d81601755714e9fSE Android * there is only a base since all optionals are dealt with at link time 2941255e72915d4cbddceb435e13d81601755714e9fSE Android * the base passed in should be indexed and avrule blocks should be 2942255e72915d4cbddceb435e13d81601755714e9fSE Android * enabled. 2943255e72915d4cbddceb435e13d81601755714e9fSE Android */ 2944255e72915d4cbddceb435e13d81601755714e9fSE Androidint expand_module(sepol_handle_t * handle, 2945255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t * base, policydb_t * out, int verbose, int check) 2946255e72915d4cbddceb435e13d81601755714e9fSE Android{ 2947255e72915d4cbddceb435e13d81601755714e9fSE Android int retval = -1; 2948255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i; 2949255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_t state; 2950255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_block_t *curblock; 2951255e72915d4cbddceb435e13d81601755714e9fSE Android 2952fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley /* Append tunable's avtrue_list or avfalse_list to the avrules list 2953fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * of its home decl depending on its state value, so that the effect 2954fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * rules of a tunable would be added to te_avtab permanently. Whereas 2955fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * the disabled unused branch would be discarded. 2956fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * 2957fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * Originally this function is called at the very end of link phase, 2958fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * however, we need to keep the linked policy intact for analysis 2959fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley * purpose. */ 2960fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley discard_tunables(handle, base); 2961fb82f8ed213dd54eebc6bdd5557984c3ba870496Stephen Smalley 2962255e72915d4cbddceb435e13d81601755714e9fSE Android expand_state_init(&state); 2963255e72915d4cbddceb435e13d81601755714e9fSE Android 2964255e72915d4cbddceb435e13d81601755714e9fSE Android state.verbose = verbose; 2965255e72915d4cbddceb435e13d81601755714e9fSE Android state.typemap = NULL; 2966255e72915d4cbddceb435e13d81601755714e9fSE Android state.base = base; 2967255e72915d4cbddceb435e13d81601755714e9fSE Android state.out = out; 2968255e72915d4cbddceb435e13d81601755714e9fSE Android state.handle = handle; 2969255e72915d4cbddceb435e13d81601755714e9fSE Android 2970255e72915d4cbddceb435e13d81601755714e9fSE Android if (base->policy_type != POLICY_BASE) { 2971255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Target of expand was not a base policy."); 2972255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 2973255e72915d4cbddceb435e13d81601755714e9fSE Android } 2974255e72915d4cbddceb435e13d81601755714e9fSE Android 2975255e72915d4cbddceb435e13d81601755714e9fSE Android state.out->policy_type = POLICY_KERN; 2976255e72915d4cbddceb435e13d81601755714e9fSE Android state.out->policyvers = POLICYDB_VERSION_MAX; 2977255e72915d4cbddceb435e13d81601755714e9fSE Android 2978255e72915d4cbddceb435e13d81601755714e9fSE Android /* Copy mls state from base to out */ 2979255e72915d4cbddceb435e13d81601755714e9fSE Android out->mls = base->mls; 2980255e72915d4cbddceb435e13d81601755714e9fSE Android out->handle_unknown = base->handle_unknown; 2981255e72915d4cbddceb435e13d81601755714e9fSE Android 2982255e72915d4cbddceb435e13d81601755714e9fSE Android /* Copy target from base to out */ 2983255e72915d4cbddceb435e13d81601755714e9fSE Android out->target_platform = base->target_platform; 2984255e72915d4cbddceb435e13d81601755714e9fSE Android 2985255e72915d4cbddceb435e13d81601755714e9fSE Android /* Copy policy capabilities */ 2986255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_cpy(&out->policycaps, &base->policycaps)) { 2987255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 2988255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2989255e72915d4cbddceb435e13d81601755714e9fSE Android } 2990255e72915d4cbddceb435e13d81601755714e9fSE Android 2991255e72915d4cbddceb435e13d81601755714e9fSE Android if ((state.typemap = 2992255e72915d4cbddceb435e13d81601755714e9fSE Android (uint32_t *) calloc(state.base->p_types.nprim, 2993255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(uint32_t))) == NULL) { 2994255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 2995255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 2996255e72915d4cbddceb435e13d81601755714e9fSE Android } 2997255e72915d4cbddceb435e13d81601755714e9fSE Android 2998255e72915d4cbddceb435e13d81601755714e9fSE Android state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t)); 2999255e72915d4cbddceb435e13d81601755714e9fSE Android if (!state.boolmap) { 3000255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 3001255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3002255e72915d4cbddceb435e13d81601755714e9fSE Android } 3003255e72915d4cbddceb435e13d81601755714e9fSE Android 3004255e72915d4cbddceb435e13d81601755714e9fSE Android state.rolemap = (uint32_t *)calloc(state.base->p_roles.nprim, sizeof(uint32_t)); 3005255e72915d4cbddceb435e13d81601755714e9fSE Android if (!state.rolemap) { 3006255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 3007255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3008255e72915d4cbddceb435e13d81601755714e9fSE Android } 3009255e72915d4cbddceb435e13d81601755714e9fSE Android 3010255e72915d4cbddceb435e13d81601755714e9fSE Android state.usermap = (uint32_t *)calloc(state.base->p_users.nprim, sizeof(uint32_t)); 3011255e72915d4cbddceb435e13d81601755714e9fSE Android if (!state.usermap) { 3012255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 3013255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3014255e72915d4cbddceb435e13d81601755714e9fSE Android } 3015255e72915d4cbddceb435e13d81601755714e9fSE Android 3016255e72915d4cbddceb435e13d81601755714e9fSE Android /* order is important - types must be first */ 3017255e72915d4cbddceb435e13d81601755714e9fSE Android 3018255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy types */ 3019255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_types.table, type_copy_callback, &state)) { 3020255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3021255e72915d4cbddceb435e13d81601755714e9fSE Android } 3022255e72915d4cbddceb435e13d81601755714e9fSE Android 3023255e72915d4cbddceb435e13d81601755714e9fSE Android /* convert attribute type sets */ 3024255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 3025255e72915d4cbddceb435e13d81601755714e9fSE Android (state.base->p_types.table, attr_convert_callback, &state)) { 3026255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3027255e72915d4cbddceb435e13d81601755714e9fSE Android } 3028255e72915d4cbddceb435e13d81601755714e9fSE Android 3029255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy commons */ 3030255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 3031255e72915d4cbddceb435e13d81601755714e9fSE Android (state.base->p_commons.table, common_copy_callback, &state)) { 3032255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3033255e72915d4cbddceb435e13d81601755714e9fSE Android } 3034255e72915d4cbddceb435e13d81601755714e9fSE Android 3035255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy classes, note, this does not copy constraints, constraints can't be 3036255e72915d4cbddceb435e13d81601755714e9fSE Android * copied until after all the blocks have been processed and attributes are complete */ 3037255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 3038255e72915d4cbddceb435e13d81601755714e9fSE Android (state.base->p_classes.table, class_copy_callback, &state)) { 3039255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3040255e72915d4cbddceb435e13d81601755714e9fSE Android } 3041255e72915d4cbddceb435e13d81601755714e9fSE Android 3042255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy type bounds */ 3043255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_types.table, 3044255e72915d4cbddceb435e13d81601755714e9fSE Android type_bounds_copy_callback, &state)) 3045255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3046255e72915d4cbddceb435e13d81601755714e9fSE Android 3047255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy aliases */ 3048255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_types.table, alias_copy_callback, &state)) 3049255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3050255e72915d4cbddceb435e13d81601755714e9fSE Android 3051255e72915d4cbddceb435e13d81601755714e9fSE Android /* index here so that type indexes are available for role_copy_callback */ 3052255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_index_others(handle, out, verbose)) { 3053255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Error while indexing out symbols"); 3054255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3055255e72915d4cbddceb435e13d81601755714e9fSE Android } 3056255e72915d4cbddceb435e13d81601755714e9fSE Android 3057255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy roles */ 3058255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_roles.table, role_copy_callback, &state)) 3059255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3060255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_roles.table, 3061255e72915d4cbddceb435e13d81601755714e9fSE Android role_bounds_copy_callback, &state)) 3062255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3063255e72915d4cbddceb435e13d81601755714e9fSE Android /* escalate the type_set_t in a role attribute to all regular roles 3064255e72915d4cbddceb435e13d81601755714e9fSE Android * that belongs to it. */ 3065255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state)) 3066255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3067255e72915d4cbddceb435e13d81601755714e9fSE Android 3068255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy MLS's sensitivity level and categories - this needs to be done 3069255e72915d4cbddceb435e13d81601755714e9fSE Android * before expanding users (they need to be indexed too) */ 3070255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_levels.table, sens_copy_callback, &state)) 3071255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3072255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_cats.table, cats_copy_callback, &state)) 3073255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3074255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_index_others(handle, out, verbose)) { 3075255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Error while indexing out symbols"); 3076255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3077255e72915d4cbddceb435e13d81601755714e9fSE Android } 3078255e72915d4cbddceb435e13d81601755714e9fSE Android 3079255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy users */ 3080255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_users.table, user_copy_callback, &state)) 3081255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3082255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_users.table, 3083255e72915d4cbddceb435e13d81601755714e9fSE Android user_bounds_copy_callback, &state)) 3084255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3085255e72915d4cbddceb435e13d81601755714e9fSE Android 3086255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy bools */ 3087255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.base->p_bools.table, bool_copy_callback, &state)) 3088255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3089255e72915d4cbddceb435e13d81601755714e9fSE Android 3090255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_index_classes(out)) { 3091255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Error while indexing out classes"); 3092255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3093255e72915d4cbddceb435e13d81601755714e9fSE Android } 3094255e72915d4cbddceb435e13d81601755714e9fSE Android if (policydb_index_others(handle, out, verbose)) { 3095255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Error while indexing out symbols"); 3096255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3097255e72915d4cbddceb435e13d81601755714e9fSE Android } 3098255e72915d4cbddceb435e13d81601755714e9fSE Android 3099255e72915d4cbddceb435e13d81601755714e9fSE Android /* loop through all decls and union attributes, roles, users */ 3100255e72915d4cbddceb435e13d81601755714e9fSE Android for (curblock = state.base->global; curblock != NULL; 3101255e72915d4cbddceb435e13d81601755714e9fSE Android curblock = curblock->next) { 3102255e72915d4cbddceb435e13d81601755714e9fSE Android avrule_decl_t *decl = curblock->enabled; 3103255e72915d4cbddceb435e13d81601755714e9fSE Android 3104255e72915d4cbddceb435e13d81601755714e9fSE Android if (decl == NULL) { 3105255e72915d4cbddceb435e13d81601755714e9fSE Android /* nothing was enabled within this block */ 3106255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3107255e72915d4cbddceb435e13d81601755714e9fSE Android } 3108255e72915d4cbddceb435e13d81601755714e9fSE Android 3109255e72915d4cbddceb435e13d81601755714e9fSE Android /* convert attribute type sets */ 3110255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 3111255e72915d4cbddceb435e13d81601755714e9fSE Android (decl->p_types.table, attr_convert_callback, &state)) { 3112255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3113255e72915d4cbddceb435e13d81601755714e9fSE Android } 3114255e72915d4cbddceb435e13d81601755714e9fSE Android 3115255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy roles */ 3116255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 3117255e72915d4cbddceb435e13d81601755714e9fSE Android (decl->p_roles.table, role_copy_callback, &state)) 3118255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3119255e72915d4cbddceb435e13d81601755714e9fSE Android 3120255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy users */ 3121255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 3122255e72915d4cbddceb435e13d81601755714e9fSE Android (decl->p_users.table, user_copy_callback, &state)) 3123255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3124255e72915d4cbddceb435e13d81601755714e9fSE Android 3125255e72915d4cbddceb435e13d81601755714e9fSE Android } 3126255e72915d4cbddceb435e13d81601755714e9fSE Android 3127255e72915d4cbddceb435e13d81601755714e9fSE Android /* remap role dominates bitmaps */ 3128255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.out->p_roles.table, role_remap_dominates, &state)) { 3129255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3130255e72915d4cbddceb435e13d81601755714e9fSE Android } 3131255e72915d4cbddceb435e13d81601755714e9fSE Android 3132255e72915d4cbddceb435e13d81601755714e9fSE Android if (copy_and_expand_avrule_block(&state) < 0) { 3133255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Error during expand"); 3134255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3135255e72915d4cbddceb435e13d81601755714e9fSE Android } 3136255e72915d4cbddceb435e13d81601755714e9fSE Android 3137255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy constraints */ 3138255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map 3139255e72915d4cbddceb435e13d81601755714e9fSE Android (state.base->p_classes.table, constraint_copy_callback, &state)) { 3140255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3141255e72915d4cbddceb435e13d81601755714e9fSE Android } 3142255e72915d4cbddceb435e13d81601755714e9fSE Android 3143255e72915d4cbddceb435e13d81601755714e9fSE Android cond_optimize_lists(state.out->cond_list); 3144dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley if (evaluate_conds(state.out)) 3145dedcd596b31e0e4fc15d75b3a8b5e6b61e6c28b3Stephen Smalley goto cleanup; 3146255e72915d4cbddceb435e13d81601755714e9fSE Android 3147255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy ocontexts */ 3148255e72915d4cbddceb435e13d81601755714e9fSE Android if (ocontext_copy(&state, out->target_platform)) 3149255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3150255e72915d4cbddceb435e13d81601755714e9fSE Android 3151255e72915d4cbddceb435e13d81601755714e9fSE Android /* copy genfs */ 3152255e72915d4cbddceb435e13d81601755714e9fSE Android if (genfs_copy(&state)) 3153255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3154255e72915d4cbddceb435e13d81601755714e9fSE Android 3155255e72915d4cbddceb435e13d81601755714e9fSE Android /* Build the type<->attribute maps and remove attributes. */ 3156255e72915d4cbddceb435e13d81601755714e9fSE Android state.out->attr_type_map = malloc(state.out->p_types.nprim * 3157255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(ebitmap_t)); 3158255e72915d4cbddceb435e13d81601755714e9fSE Android state.out->type_attr_map = malloc(state.out->p_types.nprim * 3159255e72915d4cbddceb435e13d81601755714e9fSE Android sizeof(ebitmap_t)); 3160255e72915d4cbddceb435e13d81601755714e9fSE Android if (!state.out->attr_type_map || !state.out->type_attr_map) { 3161255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 3162255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3163255e72915d4cbddceb435e13d81601755714e9fSE Android } 3164255e72915d4cbddceb435e13d81601755714e9fSE Android for (i = 0; i < state.out->p_types.nprim; i++) { 3165255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&state.out->type_attr_map[i]); 3166255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_init(&state.out->attr_type_map[i]); 3167255e72915d4cbddceb435e13d81601755714e9fSE Android /* add the type itself as the degenerate case */ 3168255e72915d4cbddceb435e13d81601755714e9fSE Android if (ebitmap_set_bit(&state.out->type_attr_map[i], i, 1)) { 3169255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "Out of memory!"); 3170255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3171255e72915d4cbddceb435e13d81601755714e9fSE Android } 3172255e72915d4cbddceb435e13d81601755714e9fSE Android } 3173255e72915d4cbddceb435e13d81601755714e9fSE Android if (hashtab_map(state.out->p_types.table, type_attr_map, &state)) 3174255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3175255e72915d4cbddceb435e13d81601755714e9fSE Android if (check) { 3176255e72915d4cbddceb435e13d81601755714e9fSE Android if (hierarchy_check_constraints(handle, state.out)) 3177255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3178255e72915d4cbddceb435e13d81601755714e9fSE Android 3179255e72915d4cbddceb435e13d81601755714e9fSE Android if (check_assertions 3180255e72915d4cbddceb435e13d81601755714e9fSE Android (handle, state.out, 3181255e72915d4cbddceb435e13d81601755714e9fSE Android state.out->global->branch_list->avrules)) 3182255e72915d4cbddceb435e13d81601755714e9fSE Android goto cleanup; 3183255e72915d4cbddceb435e13d81601755714e9fSE Android } 3184255e72915d4cbddceb435e13d81601755714e9fSE Android 3185255e72915d4cbddceb435e13d81601755714e9fSE Android retval = 0; 3186255e72915d4cbddceb435e13d81601755714e9fSE Android 3187255e72915d4cbddceb435e13d81601755714e9fSE Android cleanup: 3188255e72915d4cbddceb435e13d81601755714e9fSE Android free(state.typemap); 3189255e72915d4cbddceb435e13d81601755714e9fSE Android free(state.boolmap); 3190255e72915d4cbddceb435e13d81601755714e9fSE Android free(state.rolemap); 3191255e72915d4cbddceb435e13d81601755714e9fSE Android free(state.usermap); 3192255e72915d4cbddceb435e13d81601755714e9fSE Android return retval; 3193255e72915d4cbddceb435e13d81601755714e9fSE Android} 3194255e72915d4cbddceb435e13d81601755714e9fSE Android 3195255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d) 3196255e72915d4cbddceb435e13d81601755714e9fSE Android{ 3197255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 3198255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_datum_t *avd; 3199255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 3200255e72915d4cbddceb435e13d81601755714e9fSE Android 3201255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node(a, k); 3202255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node) { 3203255e72915d4cbddceb435e13d81601755714e9fSE Android rc = avtab_insert(a, k, d); 3204255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3205255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Out of memory!"); 3206255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 3207255e72915d4cbddceb435e13d81601755714e9fSE Android } 3208255e72915d4cbddceb435e13d81601755714e9fSE Android 3209255e72915d4cbddceb435e13d81601755714e9fSE Android if ((k->specified & AVTAB_ENABLED) != 3210255e72915d4cbddceb435e13d81601755714e9fSE Android (node->key.specified & AVTAB_ENABLED)) { 3211255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_insert_nonunique(a, k, d); 3212255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node) { 3213255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Out of memory!"); 3214255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3215255e72915d4cbddceb435e13d81601755714e9fSE Android } 3216255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3217255e72915d4cbddceb435e13d81601755714e9fSE Android } 3218255e72915d4cbddceb435e13d81601755714e9fSE Android 3219255e72915d4cbddceb435e13d81601755714e9fSE Android avd = &node->datum; 3220255e72915d4cbddceb435e13d81601755714e9fSE Android switch (k->specified & ~AVTAB_ENABLED) { 3221255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_ALLOWED: 3222255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_AUDITALLOW: 3223255e72915d4cbddceb435e13d81601755714e9fSE Android avd->data |= d->data; 3224255e72915d4cbddceb435e13d81601755714e9fSE Android break; 3225255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_AUDITDENY: 3226255e72915d4cbddceb435e13d81601755714e9fSE Android avd->data &= d->data; 3227255e72915d4cbddceb435e13d81601755714e9fSE Android break; 3228255e72915d4cbddceb435e13d81601755714e9fSE Android default: 3229255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Type conflict!"); 3230255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3231255e72915d4cbddceb435e13d81601755714e9fSE Android } 3232255e72915d4cbddceb435e13d81601755714e9fSE Android 3233255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3234255e72915d4cbddceb435e13d81601755714e9fSE Android} 3235255e72915d4cbddceb435e13d81601755714e9fSE Android 3236255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct expand_avtab_data { 3237255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_t *expa; 3238255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *p; 3239255e72915d4cbddceb435e13d81601755714e9fSE Android 3240255e72915d4cbddceb435e13d81601755714e9fSE Android}; 3241255e72915d4cbddceb435e13d81601755714e9fSE Android 3242255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args) 3243255e72915d4cbddceb435e13d81601755714e9fSE Android{ 3244255e72915d4cbddceb435e13d81601755714e9fSE Android struct expand_avtab_data *ptr = args; 3245255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_t *expa = ptr->expa; 3246255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *p = ptr->p; 3247255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; 3248255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; 3249255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; 3250255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; 3251255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *snode, *tnode; 3252255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 3253255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t newkey; 3254255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 3255255e72915d4cbddceb435e13d81601755714e9fSE Android 3256255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_class = k->target_class; 3257255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.specified = k->specified; 3258255e72915d4cbddceb435e13d81601755714e9fSE Android 32594ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { 3260255e72915d4cbddceb435e13d81601755714e9fSE Android /* Both are individual types, no expansion required. */ 3261255e72915d4cbddceb435e13d81601755714e9fSE Android return expand_avtab_insert(expa, k, d); 3262255e72915d4cbddceb435e13d81601755714e9fSE Android } 3263255e72915d4cbddceb435e13d81601755714e9fSE Android 32644ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (stype->flavor != TYPE_ATTRIB) { 3265255e72915d4cbddceb435e13d81601755714e9fSE Android /* Source is an individual type, target is an attribute. */ 3266255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.source_type = k->source_type; 3267255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(tattr, tnode, j) { 3268255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 3269255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3270255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_type = j + 1; 3271255e72915d4cbddceb435e13d81601755714e9fSE Android rc = expand_avtab_insert(expa, &newkey, d); 3272255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3273255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3274255e72915d4cbddceb435e13d81601755714e9fSE Android } 3275255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3276255e72915d4cbddceb435e13d81601755714e9fSE Android } 3277255e72915d4cbddceb435e13d81601755714e9fSE Android 32784ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (ttype->flavor != TYPE_ATTRIB) { 3279255e72915d4cbddceb435e13d81601755714e9fSE Android /* Target is an individual type, source is an attribute. */ 3280255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_type = k->target_type; 3281255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(sattr, snode, i) { 3282255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 3283255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3284255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.source_type = i + 1; 3285255e72915d4cbddceb435e13d81601755714e9fSE Android rc = expand_avtab_insert(expa, &newkey, d); 3286255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3287255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3288255e72915d4cbddceb435e13d81601755714e9fSE Android } 3289255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3290255e72915d4cbddceb435e13d81601755714e9fSE Android } 3291255e72915d4cbddceb435e13d81601755714e9fSE Android 3292255e72915d4cbddceb435e13d81601755714e9fSE Android /* Both source and target type are attributes. */ 3293255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(sattr, snode, i) { 3294255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 3295255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3296255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(tattr, tnode, j) { 3297255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 3298255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3299255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.source_type = i + 1; 3300255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_type = j + 1; 3301255e72915d4cbddceb435e13d81601755714e9fSE Android rc = expand_avtab_insert(expa, &newkey, d); 3302255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3303255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3304255e72915d4cbddceb435e13d81601755714e9fSE Android } 3305255e72915d4cbddceb435e13d81601755714e9fSE Android } 3306255e72915d4cbddceb435e13d81601755714e9fSE Android 3307255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3308255e72915d4cbddceb435e13d81601755714e9fSE Android} 3309255e72915d4cbddceb435e13d81601755714e9fSE Android 3310255e72915d4cbddceb435e13d81601755714e9fSE Androidint expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa) 3311255e72915d4cbddceb435e13d81601755714e9fSE Android{ 3312255e72915d4cbddceb435e13d81601755714e9fSE Android struct expand_avtab_data data; 3313255e72915d4cbddceb435e13d81601755714e9fSE Android 3314255e72915d4cbddceb435e13d81601755714e9fSE Android if (avtab_alloc(expa, MAX_AVTAB_SIZE)) { 3315255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Out of memory!"); 3316255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3317255e72915d4cbddceb435e13d81601755714e9fSE Android } 3318255e72915d4cbddceb435e13d81601755714e9fSE Android 3319255e72915d4cbddceb435e13d81601755714e9fSE Android data.expa = expa; 3320255e72915d4cbddceb435e13d81601755714e9fSE Android data.p = p; 3321255e72915d4cbddceb435e13d81601755714e9fSE Android return avtab_map(a, expand_avtab_node, &data); 3322255e72915d4cbddceb435e13d81601755714e9fSE Android} 3323255e72915d4cbddceb435e13d81601755714e9fSE Android 3324255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int expand_cond_insert(cond_av_list_t ** l, 3325255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_t * expa, 3326255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t * k, avtab_datum_t * d) 3327255e72915d4cbddceb435e13d81601755714e9fSE Android{ 3328255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 3329255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_datum_t *avd; 3330255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t *nl; 3331255e72915d4cbddceb435e13d81601755714e9fSE Android 3332255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_search_node(expa, k); 3333255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node || 3334255e72915d4cbddceb435e13d81601755714e9fSE Android (k->specified & AVTAB_ENABLED) != 3335255e72915d4cbddceb435e13d81601755714e9fSE Android (node->key.specified & AVTAB_ENABLED)) { 3336255e72915d4cbddceb435e13d81601755714e9fSE Android node = avtab_insert_nonunique(expa, k, d); 3337255e72915d4cbddceb435e13d81601755714e9fSE Android if (!node) { 3338255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Out of memory!"); 3339255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3340255e72915d4cbddceb435e13d81601755714e9fSE Android } 3341255e72915d4cbddceb435e13d81601755714e9fSE Android node->parse_context = (void *)1; 3342255e72915d4cbddceb435e13d81601755714e9fSE Android nl = (cond_av_list_t *) malloc(sizeof(*nl)); 3343255e72915d4cbddceb435e13d81601755714e9fSE Android if (!nl) { 3344255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Out of memory!"); 3345255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3346255e72915d4cbddceb435e13d81601755714e9fSE Android } 3347255e72915d4cbddceb435e13d81601755714e9fSE Android memset(nl, 0, sizeof(*nl)); 3348255e72915d4cbddceb435e13d81601755714e9fSE Android nl->node = node; 3349255e72915d4cbddceb435e13d81601755714e9fSE Android nl->next = *l; 3350255e72915d4cbddceb435e13d81601755714e9fSE Android *l = nl; 3351255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3352255e72915d4cbddceb435e13d81601755714e9fSE Android } 3353255e72915d4cbddceb435e13d81601755714e9fSE Android 3354255e72915d4cbddceb435e13d81601755714e9fSE Android avd = &node->datum; 3355255e72915d4cbddceb435e13d81601755714e9fSE Android switch (k->specified & ~AVTAB_ENABLED) { 3356255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_ALLOWED: 3357255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_AUDITALLOW: 3358255e72915d4cbddceb435e13d81601755714e9fSE Android avd->data |= d->data; 3359255e72915d4cbddceb435e13d81601755714e9fSE Android break; 3360255e72915d4cbddceb435e13d81601755714e9fSE Android case AVTAB_AUDITDENY: 3361255e72915d4cbddceb435e13d81601755714e9fSE Android avd->data &= d->data; 3362255e72915d4cbddceb435e13d81601755714e9fSE Android break; 3363255e72915d4cbddceb435e13d81601755714e9fSE Android default: 3364255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Type conflict!"); 3365255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3366255e72915d4cbddceb435e13d81601755714e9fSE Android } 3367255e72915d4cbddceb435e13d81601755714e9fSE Android 3368255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3369255e72915d4cbddceb435e13d81601755714e9fSE Android} 3370255e72915d4cbddceb435e13d81601755714e9fSE Android 3371255e72915d4cbddceb435e13d81601755714e9fSE Androidint expand_cond_av_node(policydb_t * p, 3372255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node, 3373255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** newl, avtab_t * expa) 3374255e72915d4cbddceb435e13d81601755714e9fSE Android{ 3375255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t *k = &node->key; 3376255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_datum_t *d = &node->datum; 3377255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; 3378255e72915d4cbddceb435e13d81601755714e9fSE Android type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; 3379255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; 3380255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; 3381255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_node_t *snode, *tnode; 3382255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int i, j; 3383255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_key_t newkey; 3384255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 3385255e72915d4cbddceb435e13d81601755714e9fSE Android 3386255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_class = k->target_class; 3387255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.specified = k->specified; 3388255e72915d4cbddceb435e13d81601755714e9fSE Android 33894ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { 3390255e72915d4cbddceb435e13d81601755714e9fSE Android /* Both are individual types, no expansion required. */ 3391255e72915d4cbddceb435e13d81601755714e9fSE Android return expand_cond_insert(newl, expa, k, d); 3392255e72915d4cbddceb435e13d81601755714e9fSE Android } 3393255e72915d4cbddceb435e13d81601755714e9fSE Android 33944ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (stype->flavor != TYPE_ATTRIB) { 3395255e72915d4cbddceb435e13d81601755714e9fSE Android /* Source is an individual type, target is an attribute. */ 3396255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.source_type = k->source_type; 3397255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(tattr, tnode, j) { 3398255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 3399255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3400255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_type = j + 1; 3401255e72915d4cbddceb435e13d81601755714e9fSE Android rc = expand_cond_insert(newl, expa, &newkey, d); 3402255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3403255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3404255e72915d4cbddceb435e13d81601755714e9fSE Android } 3405255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3406255e72915d4cbddceb435e13d81601755714e9fSE Android } 3407255e72915d4cbddceb435e13d81601755714e9fSE Android 34084ebc669d5dc59771284b2d61eb4cce53e6a7069eStephen Smalley if (ttype->flavor != TYPE_ATTRIB) { 3409255e72915d4cbddceb435e13d81601755714e9fSE Android /* Target is an individual type, source is an attribute. */ 3410255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_type = k->target_type; 3411255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(sattr, snode, i) { 3412255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 3413255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3414255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.source_type = i + 1; 3415255e72915d4cbddceb435e13d81601755714e9fSE Android rc = expand_cond_insert(newl, expa, &newkey, d); 3416255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3417255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3418255e72915d4cbddceb435e13d81601755714e9fSE Android } 3419255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3420255e72915d4cbddceb435e13d81601755714e9fSE Android } 3421255e72915d4cbddceb435e13d81601755714e9fSE Android 3422255e72915d4cbddceb435e13d81601755714e9fSE Android /* Both source and target type are attributes. */ 3423255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(sattr, snode, i) { 3424255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(snode, i)) 3425255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3426255e72915d4cbddceb435e13d81601755714e9fSE Android ebitmap_for_each_bit(tattr, tnode, j) { 3427255e72915d4cbddceb435e13d81601755714e9fSE Android if (!ebitmap_node_get_bit(tnode, j)) 3428255e72915d4cbddceb435e13d81601755714e9fSE Android continue; 3429255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.source_type = i + 1; 3430255e72915d4cbddceb435e13d81601755714e9fSE Android newkey.target_type = j + 1; 3431255e72915d4cbddceb435e13d81601755714e9fSE Android rc = expand_cond_insert(newl, expa, &newkey, d); 3432255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3433255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3434255e72915d4cbddceb435e13d81601755714e9fSE Android } 3435255e72915d4cbddceb435e13d81601755714e9fSE Android } 3436255e72915d4cbddceb435e13d81601755714e9fSE Android 3437255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3438255e72915d4cbddceb435e13d81601755714e9fSE Android} 3439255e72915d4cbddceb435e13d81601755714e9fSE Android 3440255e72915d4cbddceb435e13d81601755714e9fSE Androidint expand_cond_av_list(policydb_t * p, cond_av_list_t * l, 3441255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t ** newl, avtab_t * expa) 3442255e72915d4cbddceb435e13d81601755714e9fSE Android{ 3443255e72915d4cbddceb435e13d81601755714e9fSE Android cond_av_list_t *cur; 3444255e72915d4cbddceb435e13d81601755714e9fSE Android avtab_ptr_t node; 3445255e72915d4cbddceb435e13d81601755714e9fSE Android int rc; 3446255e72915d4cbddceb435e13d81601755714e9fSE Android 3447255e72915d4cbddceb435e13d81601755714e9fSE Android if (avtab_alloc(expa, MAX_AVTAB_SIZE)) { 3448255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(NULL, "Out of memory!"); 3449255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 3450255e72915d4cbddceb435e13d81601755714e9fSE Android } 3451255e72915d4cbddceb435e13d81601755714e9fSE Android 3452255e72915d4cbddceb435e13d81601755714e9fSE Android *newl = NULL; 3453255e72915d4cbddceb435e13d81601755714e9fSE Android for (cur = l; cur; cur = cur->next) { 3454255e72915d4cbddceb435e13d81601755714e9fSE Android node = cur->node; 3455255e72915d4cbddceb435e13d81601755714e9fSE Android rc = expand_cond_av_node(p, node, newl, expa); 3456255e72915d4cbddceb435e13d81601755714e9fSE Android if (rc) 3457255e72915d4cbddceb435e13d81601755714e9fSE Android return rc; 3458255e72915d4cbddceb435e13d81601755714e9fSE Android } 3459255e72915d4cbddceb435e13d81601755714e9fSE Android 3460255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 3461255e72915d4cbddceb435e13d81601755714e9fSE Android} 3462