expand.c revision 13cd4c8960688af11ad23b4c946149015c80d54
113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Jason Tang <jtang@tresys.com> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Joshua Brindle <jbrindle@tresys.com> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2004-2005 Tresys Technology, LLC 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2007 Red Hat, Inc. 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is free software; you can redistribute it and/or 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * modify it under the terms of the GNU Lesser General Public 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License as published by the Free Software Foundation; either 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * version 2.1 of the License, or (at your option) any later version. 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is distributed in the hope that it will be useful, 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * but WITHOUT ANY WARRANTY; without even the implied warranty of 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Lesser General Public License for more details. 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * You should have received a copy of the GNU Lesser General Public 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License along with this library; if not, write to the Free Software 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "context.h" 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/policydb.h> 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/conditional.h> 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/hashtab.h> 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/expand.h> 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/hierarchy.h> 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb/avrule_block.h> 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdarg.h> 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h> 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h> 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <assert.h> 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "debug.h" 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "private.h" 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct expand_state { 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int verbose; 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *typemap; 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *boolmap; 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *rolemap; 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t *usermap; 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *base; 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *out; 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_handle_t *handle; 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int expand_neverallow; 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} expand_state_t; 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void expand_state_init(expand_state_t * state) 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(state, 0, sizeof(expand_state_t)); 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map) 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *tnode; 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(dst); 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(src, tnode, i) { 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, i)) 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!map[i]) 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(dst, map[i] - 1, 1)) 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *type, *new_type; 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)key; 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type = (type_datum_t *) datum; 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((type->flavor == TYPE_TYPE && !type->primary) 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || type->flavor == TYPE_ALIAS) { 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* aliases are handled later */ 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_TYPES)) { 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying type or attribute %s", id); 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_id == NULL) { 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type = (type_datum_t *) malloc(sizeof(type_datum_t)); 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_type) { 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ENOMEM; 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_type, 0, sizeof(type_datum_t)); 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flavor = type->flavor; 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->flags = type->flags; 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->s.value = ++state->out->p_types.nprim; 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_type->s.value > UINT16_MAX) { 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_type); 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "type space overflow"); 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type->primary = 1; 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->typemap[type->s.value - 1] = new_type->s.value; 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->out->p_types.table, 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_type); 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_type); 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_type->flags & TYPE_FLAGS_PERMISSIVE) 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(&state->out->permissive_map, new_type->s.value, 1)) { 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!\n"); 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int attr_convert_callback(hashtab_key_t key, hashtab_datum_t datum, 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id; 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *type, *new_type; 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t tmp_union; 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)key; 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type = (type_datum_t *) datum; 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type->flavor != TYPE_ATTRIB) 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_TYPES)) { 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "converting attribute %s", id); 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_type = hashtab_search(state->out->p_types.table, id); 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_type) { 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "attribute %s vanished!", id); 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (map_ebitmap(&type->types, &tmp_union, state->typemap)) { 17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "out of memory"); 17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* then union tmp_union onto &new_type->types */ 17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(&new_type->types, &tmp_union)) { 17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp_union); 18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int perm_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle symtab_t *s; 19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm_datum_t *perm, *new_perm; 19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = key; 19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle perm = (perm_datum_t *) datum; 19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s = (symtab_t *) data; 19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_perm) { 20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_perm, 0, sizeof(perm_datum_t)); 20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) { 20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_perm); 20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm->s.value = perm->s.value; 21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s->nprim++; 21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(s->table, new_id, (hashtab_datum_t *) new_perm); 21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_perm); 21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle common_datum_t *common, *new_common; 23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)key; 23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle common = (common_datum_t *) datum; 23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying common %s", id); 23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_common = (common_datum_t *) malloc(sizeof(common_datum_t)); 24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_common) { 24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_common, 0, sizeof(common_datum_t)); 24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symtab_init(&new_common->permissions, PERM_SYMTAB_SIZE)) { 24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_common); 24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) { 25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_common); 25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_common->s.value = common->s.value; 25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_commons.nprim++; 26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_insert(state->out->p_commons.table, new_id, 26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t *) new_common); 26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_common); 26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (common->permissions.table, perm_copy_callback, 27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_common->permissions)) { 27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int constraint_node_clone(constraint_node_t ** dst, 28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle constraint_node_t * src, 28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t * state) 28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle constraint_node_t *new_con = NULL, *last_new_con = NULL; 28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle constraint_expr_t *new_expr = NULL; 28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dst = NULL; 28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (src != NULL) { 28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle constraint_expr_t *expr, *expr_l = NULL; 29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_con = 29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (constraint_node_t *) malloc(sizeof(constraint_node_t)); 29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_con) { 29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_con, 0, sizeof(constraint_node_t)); 29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_con->permissions = src->permissions; 29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (expr = src->expr; expr; expr = expr->next) { 29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((new_expr = calloc(1, sizeof(*new_expr))) == NULL) { 29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (constraint_expr_init(new_expr) == -1) { 30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_expr->expr_type = expr->expr_type; 30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_expr->attr = expr->attr; 30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_expr->op = expr->op; 30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_expr->expr_type == CEXPR_NAMES) { 30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_expr->attr & CEXPR_TYPE) { 30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Type sets require expansion and conversion. */ 31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set(state->out, 31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state-> 31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typemap, 31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expr-> 31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_names, 31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_expr-> 31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle names, 1)) { 31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (new_expr->attr & CEXPR_ROLE) { 32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (map_ebitmap(&expr->names, &new_expr->names, state->rolemap)) { 32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (new_expr->attr & CEXPR_USER) { 32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (map_ebitmap(&expr->names, &new_expr->names, state->usermap)) { 32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Other kinds of sets do not. */ 32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&new_expr->names, 33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &expr->names)) { 33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expr_l) { 33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expr_l->next = new_expr; 33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_con->expr = new_expr; 33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expr_l = new_expr; 34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_expr = NULL; 34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (last_new_con == NULL) { 34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *dst = new_con; 34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle last_new_con->next = new_con; 34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle last_new_con = new_con; 34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle src = src->next; 35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out_of_mem: 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_con) 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_con); 35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle constraint_expr_destroy(new_expr); 35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *class, *new_class; 36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)key; 37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class = (class_datum_t *) datum; 37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 37213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_CLASSES)) { 37413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 37513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 37613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying class %s", id); 38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class = (class_datum_t *) malloc(sizeof(class_datum_t)); 38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_class) { 38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_class, 0, sizeof(class_datum_t)); 38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (symtab_init(&new_class->permissions, PERM_SYMTAB_SIZE)) { 38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 38913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_class); 39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->s.value = class->s.value; 39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_classes.nprim++; 39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) { 39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_class); 40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = 40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_insert(state->out->p_classes.table, new_id, 40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t *) new_class); 40613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_class); 40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (class->permissions.table, perm_copy_callback, 41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_class->permissions)) { 41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (class->comkey) { 42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->comkey = strdup(class->comkey); 42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_class->comkey) { 42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->comdatum = 42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_search(state->out->p_commons.table, 42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->comkey); 43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_class->comdatum) { 43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "could not find common datum %s", 43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->comkey); 43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->permissions.nprim += 43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class->comdatum->permissions.nprim; 43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int constraint_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id; 44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_datum_t *class, *new_class; 44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)key; 45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class = (class_datum_t *) datum; 45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_class = hashtab_search(state->out->p_classes.table, id); 45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_class) { 45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "class %s vanished", id); 45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* constraints */ 46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (constraint_node_clone 46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&new_class->constraints, class->constraints, state) == -1 46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || constraint_node_clone(&new_class->validatetrans, 46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class->validatetrans, state) == -1) { 46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 46513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 46613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 46713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 46813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 46913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* The aliases have to be copied after the types and attributes to be certain that 47013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the out symbol table will have the type that the alias refers. Otherwise, we 47113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * won't be able to find the type value for the alias. We can't depend on the 47213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * declaration ordering because of the hash table. 47313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 47413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 47713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 47813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 47913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *alias, *new_alias; 48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = (char *)key; 48313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle alias = (type_datum_t *) datum; 48413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 48513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 48613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* ignore regular types */ 48713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (alias->flavor == TYPE_TYPE && alias->primary) 48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* ignore attributes */ 49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (alias->flavor == TYPE_ATTRIB) 49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying alias %s", id); 49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) { 49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_alias = (type_datum_t *) malloc(sizeof(type_datum_t)); 50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_alias) { 50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return SEPOL_ENOMEM; 50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_alias, 0, sizeof(type_datum_t)); 51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (alias->flavor == TYPE_TYPE) 51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_alias->s.value = state->typemap[alias->s.value - 1]; 51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else if (alias->flavor == TYPE_ALIAS) 51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_alias->s.value = state->typemap[alias->primary - 1]; 51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(0); /* unreachable */ 51613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_alias->flags = alias->flags; 51813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 51913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->out->p_types.table, 52013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 52113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_alias); 52213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 52313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_alias); 52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 52813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 52913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 53013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->typemap[alias->s.value - 1] = new_alias->s.value; 53113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 53213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_alias->flags & TYPE_FLAGS_PERMISSIVE) 53313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(&state->out->permissive_map, new_alias->s.value, 1)) { 53413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 53513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 53613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 53713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 53813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 53913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 54013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 54113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int role_remap_dominates(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *data) 54213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t mapped_roles; 54413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_t *role = (role_datum_t *) datum; 54513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state = (expand_state_t *) data; 54613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 54713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (map_ebitmap(&role->dominates, &mapped_roles, state->rolemap)) 54813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 54913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&role->dominates); 55113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&role->dominates, &mapped_roles)) 55313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 55413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&mapped_roles); 55613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 55813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 55913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 56013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 56113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 56213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 56313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 56413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 56513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_t *role; 56613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_datum_t *new_role; 56713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 56813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t tmp_union_types; 56913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 57013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = key; 57113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role = (role_datum_t *) datum; 57213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 57313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 57413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (strcmp(id, OBJECT_R) == 0) { 57513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* object_r is always value 1 */ 57613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->rolemap[role->s.value - 1] = 1; 57713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 57813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 57913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 58013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_ROLES)) { 58113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 58213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 58313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 58413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 58513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 58613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying role %s", id); 58713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 58813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_role = 58913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (role_datum_t *) hashtab_search(state->out->p_roles.table, id); 59013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_role) { 59113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_role = (role_datum_t *) malloc(sizeof(role_datum_t)); 59213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_role) { 59313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 59413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 59513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 59613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_role, 0, sizeof(role_datum_t)); 59713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 59813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 59913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) { 60013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 60113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 60213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 60313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 60413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_roles.nprim++; 60513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_role->s.value = state->out->p_roles.nprim; 60613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->rolemap[role->s.value - 1] = new_role->s.value; 60713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->out->p_roles.table, 60813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 60913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_role); 61013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 61113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 61213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 61313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_role); 61413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 61513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 61613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 61713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 61813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 61913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* The dominates bitmap is going to be wrong for the moment, 62013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * we'll come back later and remap them, after we are sure all 62113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the roles have been added */ 62213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(&new_role->dominates, &role->dominates)) { 62313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 62413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 62513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 62613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 62713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&tmp_union_types); 62813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 62913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* convert types in the role datum in the global symtab */ 63013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set 63113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->out, state->typemap, &role->types, &tmp_union_types, 1)) { 63213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp_union_types); 63313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 63413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 63513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 63613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 63713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(&new_role->types.types, &tmp_union_types)) { 63813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 63913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp_union_types); 64013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 64113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 64213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp_union_types); 64313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 64413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 64513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 64613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 64713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l, 64813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * p, sepol_handle_t * h) 64913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 65013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_semantic_cat_t *cat; 65113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_t *levdatum; 65213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 65313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 65413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_init(l); 65513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 65613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!p->mls) 65713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 65813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 65913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Required not declared. */ 66013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!sl->sens) 66113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 66213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 66313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l->sens = sl->sens; 66413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, 66513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_sens_val_to_name[l-> 66613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sens - 66713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1]); 66813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (cat = sl->cat; cat; cat = cat->next) { 66913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cat->low > cat->high) { 67013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(h, "Category range is not valid %s.%s", 67113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_cat_val_to_name[cat->low - 1], 67213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_cat_val_to_name[cat->high - 1]); 67313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 67413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 67513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = cat->low - 1; i < cat->high; i++) { 67613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 67713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(h, "Category %s can not be associate with " 67813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "level %s", 67913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_cat_val_to_name[i], 68013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_sens_val_to_name[l->sens - 1]); 68113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 68213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(&l->cat, i, 1)) { 68313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(h, "Out of memory!"); 68413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 68513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 68613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 68713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 68813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 68913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 69013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 69113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 69213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint mls_semantic_range_expand(mls_semantic_range_t * sr, mls_range_t * r, 69313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * p, sepol_handle_t * h) 69413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 69513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_semantic_level_expand(&sr->level[0], &r->level[0], p, h) < 0) 69613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 69713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 69813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_semantic_level_expand(&sr->level[1], &r->level[1], p, h) < 0) { 69913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_semantic_level_destroy(&sr->level[0]); 70013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 70113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 70213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 70313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mls_level_dom(&r->level[1], &r->level[0])) { 70413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_range_destroy(r); 70513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(h, "MLS range high level does not dominate low level"); 70613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 70713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 70813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 70913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 71013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 71113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 71213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 71313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 71413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 71513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 71613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 71713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_t *user; 71813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_t *new_user; 71913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 72013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t tmp_union; 72113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 72213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = key; 72313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user = (user_datum_t *) datum; 72413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 72513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 72613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_USERS)) { 72713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 72813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 72913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 73013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 73113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 73213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying user %s", id); 73313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 73413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_user = 73513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (user_datum_t *) hashtab_search(state->out->p_users.table, id); 73613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_user) { 73713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_user = (user_datum_t *) malloc(sizeof(user_datum_t)); 73813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_user) { 73913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 74013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 74113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 74213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(new_user, 0, sizeof(user_datum_t)); 74313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 74413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_users.nprim++; 74513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_user->s.value = state->out->p_users.nprim; 74613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->usermap[user->s.value - 1] = new_user->s.value; 74713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 74813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 74913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) { 75013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 75113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 75213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 75313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->out->p_users.table, 75413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 75513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_user); 75613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 75713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 75813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_datum_destroy(new_user); 75913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_user); 76013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 76113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 76213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 76313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 76413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* expand the semantic MLS info */ 76513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_semantic_range_expand(&user->range, 76613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_user->exp_range, 76713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out, state->handle)) { 76813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 76913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 77013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_semantic_level_expand(&user->dfltlevel, 77113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_user->exp_dfltlevel, 77213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out, state->handle)) { 77313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 77413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 77513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mls_level_between(&new_user->exp_dfltlevel, 77613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_user->exp_range.level[0], 77713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_user->exp_range.level[1])) { 77813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "default level not within user " 77913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "range"); 78013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 78113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 78213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 78313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* require that the MLS info match */ 78413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_range_t tmp_range; 78513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_t tmp_level; 78613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 78713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_semantic_range_expand(&user->range, &tmp_range, 78813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out, state->handle)) { 78913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 79013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 79113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_semantic_level_expand(&user->dfltlevel, &tmp_level, 79213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out, state->handle)) { 79313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_range_destroy(&tmp_range); 79413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 79513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 79613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!mls_range_eq(&new_user->exp_range, &tmp_range) || 79713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle !mls_level_eq(&new_user->exp_dfltlevel, &tmp_level)) { 79813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_range_destroy(&tmp_range); 79913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_destroy(&tmp_level); 80013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 80113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 80213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_range_destroy(&tmp_range); 80313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_destroy(&tmp_level); 80413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 80513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 80613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&tmp_union); 80713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 80813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* get global roles for this user */ 80913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (role_set_expand(&user->roles, &tmp_union, state->base, state->rolemap)) { 81013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 81113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp_union); 81213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 81313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 81413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 81513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union(&new_user->roles.roles, &tmp_union)) { 81613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 81713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp_union); 81813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 81913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 82013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&tmp_union); 82113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 82213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 82313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 82413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 82513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 82613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 82713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 82813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 82913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state; 83013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_bool_datum_t *bool, *new_bool; 83113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id, *new_id; 83213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 83313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle id = key; 83413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle bool = (cond_bool_datum_t *) datum; 83513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state = (expand_state_t *) data; 83613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 83713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_BOOLS)) { 83813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 83913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 84013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 84113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 84213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 84313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying boolean %s", id); 84413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 84513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_bool = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 84613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_bool) { 84713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 84813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 84913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 85013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 85113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 85213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) { 85313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 85413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_bool); 85513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 85613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 85713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 85813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_bools.nprim++; 85913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_bool->s.value = state->out->p_bools.nprim; 86013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 86113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = hashtab_insert(state->out->p_bools.table, 86213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 86313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_bool); 86413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) { 86513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "hashtab overflow"); 86613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_bool); 86713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 86813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 86913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 87013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->boolmap[bool->s.value - 1] = new_bool->s.value; 87213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_bool->state = bool->state; 87413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 87613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 87713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 87913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 88013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 88113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state = (expand_state_t *) data; 88213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_t *level = (level_datum_t *) datum, *new_level = NULL; 88313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = (char *)key, *new_id = NULL; 88413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 88513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_LEVELS)) { 88613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 88713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 88813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 88913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 89013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 89113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying sensitivity level %s", id); 89213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 89313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_level = (level_datum_t *) malloc(sizeof(level_datum_t)); 89413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_level) 89513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 89613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_init(new_level); 89713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_level->level = (mls_level_t *) malloc(sizeof(mls_level_t)); 89813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_level->level) 89913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 90013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_init(new_level->level); 90113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 90213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) 90313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 90413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 90513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_level_cpy(new_level->level, level->level)) { 90613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 90713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 90813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_level->isalias = level->isalias; 90913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_levels.nprim++; 91013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 91113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert(state->out->p_levels.table, 91213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, 91313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_datum_t) new_level)) { 91413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 91513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 91613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 91713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 91813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out_of_mem: 91913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 92013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (new_level != NULL && new_level->level != NULL) { 92113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_level_destroy(new_level->level); 92213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_level->level); 92313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 92413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle level_datum_destroy(new_level); 92513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_level); 92613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 92713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 92813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 92913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 93013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int cats_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 93113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *data) 93213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 93313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state = (expand_state_t *) data; 93413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_datum_t *cat = (cat_datum_t *) datum, *new_cat = NULL; 93513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *id = (char *)key, *new_id = NULL; 93613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 93713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!is_id_enabled(id, state->base, SYM_CATS)) { 93813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* identifier's scope is not enabled */ 93913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 94013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 94113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 94213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 94313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "copying category attribute %s", id); 94413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 94513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_cat = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 94613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_cat) 94713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 94813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_datum_init(new_cat); 94913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_id = strdup(id); 95013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_id) 95113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 95213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 95313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_cat->s.value = cat->s.value; 95413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_cat->isalias = cat->isalias; 95513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_cats.nprim++; 95613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_insert(state->out->p_cats.table, 95713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (hashtab_key_t) new_id, (hashtab_datum_t) new_cat)) { 95813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out_of_mem; 95913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 96013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 96113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 96213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 96313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out_of_mem: 96413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 96513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cat_datum_destroy(new_cat); 96613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_cat); 96713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(new_id); 96813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 96913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 97013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 97113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_role_allows(expand_state_t * state, role_allow_rule_t * rules) 97213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 97313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 97413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_t *cur_allow, *n, *l; 97513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_allow_rule_t *cur; 97613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t roles, new_roles; 97713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *snode, *tnode; 97813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 97913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* start at the end of the list */ 98013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (l = state->out->role_allow; l && l->next; l = l->next) ; 98113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 98213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = rules; 98313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 98413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&roles); 98513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&new_roles); 98613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 98713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (role_set_expand(&cur->roles, &roles, state->out, state->rolemap)) { 98813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 98913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 99013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 99113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 99213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (role_set_expand(&cur->new_roles, &new_roles, state->out, state->rolemap)) { 99313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 99413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 99513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 99613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 99713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&roles, snode, i) { 99813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(snode, i)) 99913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 100013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&new_roles, tnode, j) { 100113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 100213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 100313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check for duplicates */ 100413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_allow = state->out->role_allow; 100513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur_allow) { 100613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((cur_allow->role == i + 1) && 100713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (cur_allow->new_role == j + 1)) 100813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 100913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_allow = cur_allow->next; 101013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 101113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur_allow) 101213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 101313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n = (role_allow_t *) 101413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle malloc(sizeof(role_allow_t)); 101513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!n) { 101613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 101713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 101813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 101913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(n, 0, sizeof(role_allow_t)); 102013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->role = i + 1; 102113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->new_role = j + 1; 102213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (l) { 102313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l->next = n; 102413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 102513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->role_allow = n; 102613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 102713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l = n; 102813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 102913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 103013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 103113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&roles); 103213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&new_roles); 103313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 103413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 103513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 103613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 103713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 103813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 103913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 104013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules) 104113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 104213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 104313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_trans_t *n, *l, *cur_trans; 104413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle role_trans_rule_t *cur; 104513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t roles, types; 104613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *rnode, *tnode; 104713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 104813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* start at the end of the list */ 104913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (l = state->out->role_tr; l && l->next; l = l->next) ; 105013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 105113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = rules; 105213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 105313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&roles); 105413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&types); 105513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 105613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (role_set_expand(&cur->roles, &roles, state->out, state->rolemap)) { 105713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 105813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 105913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 106013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set 106113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->out, state->typemap, &cur->types, &types, 1)) { 106213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 106313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 106413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 106513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&roles, rnode, i) { 106613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(rnode, i)) 106713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 106813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&types, tnode, j) { 106913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 107013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 107113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 107213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_trans = state->out->role_tr; 107313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur_trans) { 107413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((cur_trans->role == i + 1) && 107513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (cur_trans->type == j + 1)) { 107613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur_trans->new_role == 107713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur->new_role) { 107813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 107913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 108013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 108113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Conflicting role trans rule %s %s : %s", 108213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out-> 108313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p_role_val_to_name 108413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle [i], 108513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out-> 108613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p_type_val_to_name 108713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle [j], 108813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out-> 108913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p_role_val_to_name 109013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle [cur->new_role - 109113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1]); 109213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 109313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 109413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 109513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_trans = cur_trans->next; 109613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 109713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur_trans) 109813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 109913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 110013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n = (role_trans_t *) 110113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle malloc(sizeof(role_trans_t)); 110213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!n) { 110313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 110413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 110513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 110613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(n, 0, sizeof(role_trans_t)); 110713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->role = i + 1; 110813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->type = j + 1; 110913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->new_role = state->rolemap[cur->new_role - 1]; 111013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (l) { 111113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l->next = n; 111213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 111313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->role_tr = n; 111413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 111513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l = n; 111613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 111713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 111813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 111913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&roles); 112013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&types); 112113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 112213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 112313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 112413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 112513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 112613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 112713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t tclass, 112813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_semantic_range_t * trange, 112913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t * state) 113013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 113113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_t *rt, *check_rt = state->out->range_tr; 113213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_range_t exp_range; 113313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc = -1; 113413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 113513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_semantic_range_expand(trange, &exp_range, state->out, 113613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->handle)) 113713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 113813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 113913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check for duplicates/conflicts */ 114013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (check_rt) { 114113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((check_rt->source_type == stype) && 114213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (check_rt->target_type == ttype) && 114313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (check_rt->target_class == tclass)) { 114413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_range_eq(&check_rt->target_range, &exp_range)) { 114513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* duplicate */ 114613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 114713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 114813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* conflict */ 114913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 115013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Conflicting range trans rule %s %s : %s", 115113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_type_val_to_name[stype - 1], 115213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_type_val_to_name[ttype - 1], 115313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->p_class_val_to_name[tclass - 115413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1]); 115513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 115613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 115713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 115813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle check_rt = check_rt->next; 115913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 116013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (check_rt) { 116113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this is a dup - skip */ 116213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = 0; 116313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 116413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 116513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 116613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rt = (range_trans_t *) calloc(1, sizeof(range_trans_t)); 116713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!rt) { 116813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 116913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 117013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 117113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 117213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rt->next = state->out->range_tr; 117313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->range_tr = rt; 117413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 117513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rt->source_type = stype; 117613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rt->target_type = ttype; 117713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rt->target_class = tclass; 117813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_range_cpy(&rt->target_range, &exp_range)) { 117913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 118013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 118113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 118213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 118313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = 0; 118413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 118513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out: 118613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle mls_range_destroy(&exp_range); 118713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return rc; 118813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 118913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 119013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int expand_range_trans(expand_state_t * state, 119113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_rule_t * rules) 119213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 119313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j, k; 119413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle range_trans_rule_t *rule; 119513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 119613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t stypes, ttypes; 119713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *snode, *tnode, *cnode; 119813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 119913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->verbose) 120013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle INFO(state->handle, "expanding range transitions"); 120113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 120213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (rule = rules; rule; rule = rule->next) { 120313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&stypes); 120413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&ttypes); 120513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 120613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* expand the type sets */ 120713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set(state->out, state->typemap, 120813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &rule->stypes, &stypes, 1)) { 120913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 121013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 121113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 121213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set(state->out, state->typemap, 121313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &rule->ttypes, &ttypes, 1)) { 121413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&stypes); 121513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 121613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 121713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 121813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 121913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* loop on source type */ 122013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&stypes, snode, i) { 122113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(snode, i)) 122213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 122313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* loop on target type */ 122413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&ttypes, tnode, j) { 122513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 122613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 122713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* loop on target class */ 122813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&rule->tclasses, cnode, k) { 122913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(cnode, k)) 123013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 123113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 123213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (exp_rangetr_helper(i + 1, 123313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle j + 1, 123413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle k + 1, 123513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &rule->trange, 123613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state)) { 123713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&stypes); 123813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&ttypes); 123913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 124013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 124113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 124213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 124313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 124413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&stypes); 124613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&ttypes); 124713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 124813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 125013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 125113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 125213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Search for an AV tab node within a hash table with the given key. 125313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * If the node does not exist, create it and return it; otherwise 125413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * return the pre-existing one. 125513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle*/ 125613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic avtab_ptr_t find_avtab_node(sepol_handle_t * handle, 125713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_t * avtab, avtab_key_t * key, 125813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** cond) 125913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 126013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_ptr_t node; 126113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_datum_t avdatum; 126213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t *nl; 126313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 126413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_search_node(avtab, key); 126513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 126613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* If this is for conditional policies, keep searching in case 126713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle the node is part of my conditional avtab. */ 126813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond) { 126913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (node) { 127013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node->parse_context == cond) 127113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 127213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_search_node_next(node, key->specified); 127313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 127413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 127513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 127613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node) { 127713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(&avdatum, 0, sizeof avdatum); 127813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* this is used to get the node - insertion is actually unique */ 127913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_insert_nonunique(avtab, key, &avdatum); 128013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node) { 128113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "hash table overflow"); 128213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 128313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 128413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond) { 128513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->parse_context = cond; 128613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nl = (cond_av_list_t *) malloc(sizeof(cond_av_list_t)); 128713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!nl) { 128813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Memory error"); 128913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 129013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 129113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(nl, 0, sizeof(cond_av_list_t)); 129213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nl->node = node; 129313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nl->next = *cond; 129413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *cond = nl; 129513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 129613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 129713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 129813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return node; 129913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 130013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 130113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define EXPAND_RULE_SUCCESS 1 130213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define EXPAND_RULE_CONFLICT 0 130313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define EXPAND_RULE_ERROR -1 130413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 130513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int expand_terule_helper(sepol_handle_t * handle, 130613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * p, uint32_t * typemap, 130713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t specified, cond_av_list_t ** cond, 130813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** other, uint32_t stype, 130913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t ttype, class_perm_node_t * perms, 131013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_t * avtab, int enabled) 131113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 131213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_key_t avkey; 131313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_datum_t *avdatump; 131413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_ptr_t node; 131513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_perm_node_t *cur; 131613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int conflict; 131713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t oldtype = 0, spec = 0; 131813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 131913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (specified & AVRULE_TRANSITION) { 132013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_TRANSITION; 132113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_MEMBER) { 132213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_MEMBER; 132313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_CHANGE) { 132413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_CHANGE; 132513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 132613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(0); /* unreachable */ 132713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 132813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 132913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = perms; 133013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 133113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t remapped_data = 133213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typemap ? typemap[cur->data - 1] : cur->data; 133313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.source_type = stype + 1; 133413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.target_type = ttype + 1; 133513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.target_class = cur->class; 133613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.specified = spec; 133713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 133813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle conflict = 0; 133913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* check to see if the expanded TE already exists -- 134013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * either in the global scope or in another 134113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * conditional AV tab */ 134213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_search_node(&p->te_avtab, &avkey); 134313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node) { 134413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle conflict = 1; 134513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 134613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_search_node(&p->te_cond_avtab, &avkey); 134713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (node && node->parse_context != other) { 134813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle conflict = 2; 134913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 135013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 135113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 135213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (conflict) { 135313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump = &node->datum; 135413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (specified & AVRULE_TRANSITION) { 135513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle oldtype = avdatump->data; 135613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_MEMBER) { 135713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle oldtype = avdatump->data; 135813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_CHANGE) { 135913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle oldtype = avdatump->data; 136013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 136113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 136213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (oldtype == remapped_data) { 136313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* if the duplicate is inside the same scope (eg., unconditional 136413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * or in same conditional then ignore it */ 136513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((conflict == 1 && cond == NULL) 136613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || node->parse_context == cond) 136713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_SUCCESS; 136813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "duplicate TE rule for %s %s:%s %s", 136913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[avkey.source_type - 137013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1], 137113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[avkey.target_type - 137213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1], 137313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_class_val_to_name[avkey.target_class - 137413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1], 137513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[oldtype - 1]); 137613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_CONFLICT; 137713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 137813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, 137913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "conflicting TE rule for (%s, %s:%s): old was %s, new is %s", 138013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[avkey.source_type - 1], 138113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[avkey.target_type - 1], 138213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_class_val_to_name[avkey.target_class - 1], 138313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[oldtype - 1], 138413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[remapped_data - 1]); 138513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_CONFLICT; 138613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 138713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 138813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = find_avtab_node(handle, avtab, &avkey, cond); 138913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node) 139013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 139113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (enabled) { 139213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->key.specified |= AVTAB_ENABLED; 139313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 139413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->key.specified &= ~AVTAB_ENABLED; 139513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 139613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 139713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump = &node->datum; 139813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (specified & AVRULE_TRANSITION) { 139913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data = remapped_data; 140013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_MEMBER) { 140113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data = remapped_data; 140213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_CHANGE) { 140313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data = remapped_data; 140413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 140513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(0); /* should never occur */ 140613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 140713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 140813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 140913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 141013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 141113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_SUCCESS; 141213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 141313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 141413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int expand_avrule_helper(sepol_handle_t * handle, 141513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t specified, 141613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** cond, 141713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t stype, uint32_t ttype, 141813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_perm_node_t * perms, avtab_t * avtab, 141913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int enabled) 142013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 142113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_key_t avkey; 142213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_datum_t *avdatump; 142313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_ptr_t node; 142413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_perm_node_t *cur; 142513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t spec = 0; 142613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 142713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (specified & AVRULE_ALLOWED) { 142813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_ALLOWED; 142913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_AUDITALLOW) { 143013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_AUDITALLOW; 143113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_AUDITDENY) { 143213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_AUDITDENY; 143313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_DONTAUDIT) { 143413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (handle && handle->disable_dontaudit) 143513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_SUCCESS; 143613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_AUDITDENY; 143713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_NEVERALLOW) { 143813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle spec = AVTAB_NEVERALLOW; 143913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 144013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(0); /* unreachable */ 144113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 144213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 144313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = perms; 144413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 144513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.source_type = stype + 1; 144613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.target_type = ttype + 1; 144713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.target_class = cur->class; 144813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avkey.specified = spec; 144913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 145013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = find_avtab_node(handle, avtab, &avkey, cond); 145113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node) 145213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_ERROR; 145313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (enabled) { 145413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->key.specified |= AVTAB_ENABLED; 145513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 145613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->key.specified &= ~AVTAB_ENABLED; 145713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 145813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 145913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump = &node->datum; 146013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (specified & AVRULE_ALLOWED) { 146113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data |= cur->data; 146213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_AUDITALLOW) { 146313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data |= cur->data; 146413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_NEVERALLOW) { 146513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data |= cur->data; 146613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_AUDITDENY) { 146713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Since a '0' in an auditdeny mask represents 146813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * a permission we do NOT want to audit 146913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * (dontaudit), we use the '&' operand to 147013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * ensure that all '0's in the mask are 147113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * retained (much unlike the allow and 147213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * auditallow cases). 147313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 147413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data &= cur->data; 147513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else if (specified & AVRULE_DONTAUDIT) { 147613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (avdatump->data) 147713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data &= ~cur->data; 147813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 147913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avdatump->data = ~cur->data; 148013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 148113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(0); /* should never occur */ 148213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 148313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 148413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 148513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 148613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_SUCCESS; 148713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 148813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 148913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int expand_rule_helper(sepol_handle_t * handle, 149013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * p, uint32_t * typemap, 149113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t * source_rule, avtab_t * dest_avtab, 149213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** cond, cond_av_list_t ** other, 149313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int enabled, 149413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t * stypes, ebitmap_t * ttypes) 149513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 149613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 149713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 149813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *snode, *tnode; 149913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 150013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(stypes, snode, i) { 150113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(snode, i)) 150213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 150313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (source_rule->flags & RULE_SELF) { 150413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (source_rule->specified & AVRULE_AV) { 150513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((retval = 150613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_avrule_helper(handle, 150713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule-> 150813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle specified, cond, i, i, 150913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule->perms, 151013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_avtab, 151113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle enabled)) != 151213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle EXPAND_RULE_SUCCESS) { 151313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 151413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 151513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 151613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((retval = 151713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_terule_helper(handle, p, 151813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typemap, 151913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule-> 152013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle specified, cond, 152113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle other, i, i, 152213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule->perms, 152313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_avtab, 152413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle enabled)) != 152513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle EXPAND_RULE_SUCCESS) { 152613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 152713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 152813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 152913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 153013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(ttypes, tnode, j) { 153113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 153213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 153313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (source_rule->specified & AVRULE_AV) { 153413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((retval = 153513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_avrule_helper(handle, 153613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule-> 153713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle specified, cond, i, j, 153813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule->perms, 153913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_avtab, 154013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle enabled)) != 154113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle EXPAND_RULE_SUCCESS) { 154213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 154313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 154413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 154513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((retval = 154613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_terule_helper(handle, p, 154713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typemap, 154813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule-> 154913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle specified, cond, 155013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle other, i, j, 155113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule->perms, 155213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_avtab, 155313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle enabled)) != 155413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle EXPAND_RULE_SUCCESS) { 155513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 155613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 155713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 155813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 155913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 156013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 156113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_SUCCESS; 156213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 156313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 156413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* 156513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Expand a rule into a given avtab - checking for conflicting type 156613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * rules in the destination policy. Return EXPAND_RULE_SUCCESS on 156713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * success, EXPAND_RULE_CONFLICT if the rule conflicts with something 156813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * (and hence was not added), or EXPAND_RULE_ERROR on error. 156913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 157013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int convert_and_expand_rule(sepol_handle_t * handle, 157113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * dest_pol, uint32_t * typemap, 157213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t * source_rule, avtab_t * dest_avtab, 157313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** cond, 157413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** other, int enabled, 157513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int do_neverallow) 157613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 157713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 157813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t stypes, ttypes; 157913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned char alwaysexpand; 158013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 158113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW) 158213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_SUCCESS; 158313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 158413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&stypes); 158513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&ttypes); 158613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 158713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Force expansion for type rules and for self rules. */ 158813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle alwaysexpand = ((source_rule->specified & AVRULE_TYPE) || 158913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (source_rule->flags & RULE_SELF)); 159013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 159113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set 159213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (dest_pol, typemap, &source_rule->stypes, &stypes, alwaysexpand)) 159313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_ERROR; 159413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set 159513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (dest_pol, typemap, &source_rule->ttypes, &ttypes, alwaysexpand)) 159613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return EXPAND_RULE_ERROR; 159713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 159813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = expand_rule_helper(handle, dest_pol, typemap, 159913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule, dest_avtab, 160013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond, other, enabled, &stypes, &ttypes); 160113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&stypes); 160213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&ttypes); 160313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 160413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 160513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 160613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int cond_avrule_list_copy(policydb_t * dest_pol, avrule_t * source_rules, 160713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_t * dest_avtab, cond_av_list_t ** list, 160813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** other, uint32_t * typemap, 160913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int enabled, expand_state_t * state) 161013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 161113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t *cur; 161213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 161313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = source_rules; 161413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 161513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (convert_and_expand_rule(state->handle, dest_pol, 161613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typemap, cur, dest_avtab, 161713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle list, other, enabled, 161813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 0) != EXPAND_RULE_SUCCESS) { 161913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 162013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 162113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 162213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 162313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 162413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 162513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 162613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 162713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 162813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int cond_node_map_bools(expand_state_t * state, cond_node_t * cn) 162913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 163013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_expr_t *cur; 163113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 163213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 163313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cn->expr; 163413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur) { 163513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur->bool) 163613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur->bool = state->boolmap[cur->bool - 1]; 163713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur = cur->next; 163813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 163913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 164013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++) 164113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1]; 164213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 164313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_normalize_expr(state->out, cn)) { 164413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Error while normalizing conditional"); 164513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 164613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 164713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 164813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 164913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 165013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 165113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* copy the nodes in *reverse* order -- the result is that the last 165213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * given conditional appears first in the policy, so as to match the 165313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * behavior of the upstream compiler */ 165413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int cond_node_copy(expand_state_t * state, cond_node_t * cn) 165513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 165613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_node_t *new_cond, *tmp; 165713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 165813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cn == NULL) { 165913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 166013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 166113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_node_copy(state, cn->next)) { 166213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 166313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 166413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_normalize_expr(state->base, cn)) { 166513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Error while normalizing conditional"); 166613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 166713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 166813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 166913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* create a new temporary conditional node with the booleans 167013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * mapped */ 167113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmp = cond_node_create(state->base, cn); 167213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!tmp) { 167313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory"); 167413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 167513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 167613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 167713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_node_map_bools(state, tmp)) { 167813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Error mapping booleans"); 167913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 168013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 168113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 168213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_cond = cond_node_search(state->out, state->out->cond_list, tmp); 168313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_cond) { 168413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_node_destroy(tmp); 168513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(tmp); 168613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 168713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 168813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 168913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_node_destroy(tmp); 169013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(tmp); 169113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 169213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_avrule_list_copy 169313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->out, cn->avtrue_list, &state->out->te_cond_avtab, 169413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_cond->true_list, &new_cond->false_list, state->typemap, 169513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_cond->cur_state, state)) 169613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 169713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_avrule_list_copy 169813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->out, cn->avfalse_list, &state->out->te_cond_avtab, 169913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &new_cond->false_list, &new_cond->true_list, state->typemap, 170013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle !new_cond->cur_state, state)) 170113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 170213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 170313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 170413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 170513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 170613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int context_copy(context_struct_t * dst, context_struct_t * src, 170713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t * state) 170813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 170913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->user = state->usermap[src->user - 1]; 171013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->role = state->rolemap[src->role - 1]; 171113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dst->type = state->typemap[src->type - 1]; 171213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return mls_context_cpy(dst, src); 171313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 171413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 171513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int ocontext_copy(expand_state_t * state) 171613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 171713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 171813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *c, *n, *l; 171913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 172013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < OCON_NUM; i++) { 172113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l = NULL; 172213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = state->base->ocontexts[i]; c; c = c->next) { 172313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n = malloc(sizeof(ocontext_t)); 172413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!n) { 172513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 172613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 172713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 172813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(n, 0, sizeof(ocontext_t)); 172913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (l) { 173013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l->next = n; 173113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 173213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->ocontexts[i] = n; 173313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 173413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l = n; 173513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_copy(&n->context[0], &c->context[0], state)) { 173613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 173713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 173813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 173913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (i) { 174013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case OCON_ISID: 174113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->sid[0] = c->sid[0]; 174213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 174313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case OCON_FS: /* FALLTHROUGH */ 174413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case OCON_NETIF: 174513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.name = strdup(c->u.name); 174613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!n->u.name) { 174713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 174813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 174913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 175013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_copy 175113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&n->context[1], &c->context[1], state)) { 175213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 175313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 175413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 175513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 175613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case OCON_PORT: 175713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.port.protocol = c->u.port.protocol; 175813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.port.low_port = c->u.port.low_port; 175913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.port.high_port = c->u.port.high_port; 176013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 176113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case OCON_NODE: 176213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.node.addr = c->u.node.addr; 176313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.node.mask = c->u.node.mask; 176413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 176513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case OCON_FSUSE: 176613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->v.behavior = c->v.behavior; 176713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.name = strdup(c->u.name); 176813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!n->u.name) { 176913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 177013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 177113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 177213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 177313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case OCON_NODE6: 177413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (j = 0; j < 4; j++) 177513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.node6.addr[j] = c->u.node6.addr[j]; 177613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (j = 0; j < 4; j++) 177713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle n->u.node6.mask[j] = c->u.node6.mask[j]; 177813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 177913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 178013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* shouldn't get here */ 178113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(0); 178213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 178313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 178413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 178513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 178613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 178713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 178813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int genfs_copy(expand_state_t * state) 178913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 179013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ocontext_t *c, *newc, *l; 179113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle genfs_t *genfs, *newgenfs, *end; 179213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 179313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle end = NULL; 179413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (genfs = state->base->genfs; genfs; genfs = genfs->next) { 179513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newgenfs = malloc(sizeof(genfs_t)); 179613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!newgenfs) { 179713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 179813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 179913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 180013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(newgenfs, 0, sizeof(genfs_t)); 180113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newgenfs->fstype = strdup(genfs->fstype); 180213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!newgenfs->fstype) { 180313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 180413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 180513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 180613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 180713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l = NULL; 180813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (c = genfs->head; c; c = c->next) { 180913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newc = malloc(sizeof(ocontext_t)); 181013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!newc) { 181113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 181213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 181313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 181413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(newc, 0, sizeof(ocontext_t)); 181513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newc->u.name = strdup(c->u.name); 181613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!newc->u.name) { 181713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 181813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 181913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 182013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newc->v.sclass = c->v.sclass; 182113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_copy(&newc->context[0], &c->context[0], state); 182213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (l) 182313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l->next = newc; 182413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 182513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newgenfs->head = newc; 182613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle l = newc; 182713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 182813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!end) { 182913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->genfs = newgenfs; 183013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 183113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle end->next = newgenfs; 183213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 183313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle end = newgenfs; 183413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 183513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 183613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 183713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 183813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int type_attr_map(hashtab_key_t key 183913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle __attribute__ ((unused)), hashtab_datum_t datum, 184013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *ptr) 184113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 184213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *type; 184313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t *state = ptr; 184413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *p = state->out; 184513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 184613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *tnode; 184713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 184813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type = (type_datum_t *) datum; 184913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type->flavor == TYPE_ATTRIB) { 185013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&p->attr_type_map[type->s.value - 1], 185113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &type->types)) { 185213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 185313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 185413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 185513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&type->types, tnode, i) { 185613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, i)) 185713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 185813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(&p->type_attr_map[i], 185913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type->s.value - 1, 1)) { 186013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of memory!"); 186113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 186213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 186313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 186413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 186513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 186613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 186713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 186813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 186913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle __attribute__ ((unused))) 187013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 187113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(key); 187213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_destroy((type_datum_t *) datum); 187313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(datum); 187413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 187513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 187613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int type_attr_remove(hashtab_key_t key 187713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle __attribute__ ((unused)), hashtab_datum_t datum, 187813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle void *args) 187913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 188013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *typdatum; 188113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *p; 188213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 188313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle typdatum = (type_datum_t *) datum; 188413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p = (policydb_t *) args; 188513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (typdatum->flavor == TYPE_ATTRIB) { 188613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->type_val_to_struct[typdatum->s.value - 1] = NULL; 188713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->p_type_val_to_name[typdatum->s.value - 1] = NULL; 188813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 188913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 189013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 189113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 189213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 189313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy. 189413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * this should not be called until after all the blocks have been processed and the attributes in target policy 189513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * are complete. */ 189613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint expand_convert_type_set(policydb_t * p, uint32_t * typemap, 189713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_t * set, ebitmap_t * types, 189813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned char alwaysexpand) 189913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 190013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_t tmpset; 190113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 190213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_init(&tmpset); 190313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 190413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (map_ebitmap(&set->types, &tmpset.types, typemap)) 190513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 190613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 190713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (map_ebitmap(&set->negset, &tmpset.negset, typemap)) 190813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 190913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 191013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tmpset.flags = set->flags; 191113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 191213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_expand(&tmpset, types, p, alwaysexpand)) 191313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 191413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 191513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_set_destroy(&tmpset); 191613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 191713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 191813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 191913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 192013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Expand a rule into a given avtab - checking for conflicting type 192113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * rules. Return 1 on success, 0 if the rule conflicts with something 192213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * (and hence was not added), or -1 on error. */ 192313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint expand_rule(sepol_handle_t * handle, 192413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * source_pol, 192513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t * source_rule, avtab_t * dest_avtab, 192613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** cond, cond_av_list_t ** other, int enabled) 192713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 192813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 192913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t stypes, ttypes; 193013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 193113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (source_rule->specified & AVRULE_NEVERALLOW) 193213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1; 193313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 193413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&stypes); 193513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&ttypes); 193613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 193713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_expand(&source_rule->stypes, &stypes, source_pol, 1)) 193813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 193913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (type_set_expand(&source_rule->ttypes, &ttypes, source_pol, 1)) 194013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 194113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = expand_rule_helper(handle, source_pol, NULL, 194213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle source_rule, dest_avtab, 194313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond, other, enabled, &stypes, &ttypes); 194413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&stypes); 194513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&ttypes); 194613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 194713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 194813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 194913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * p, uint32_t * rolemap) 195013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 195113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 195213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *rnode; 195313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t mapped_roles; 195413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 195513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(r); 195613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&mapped_roles); 195713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 195813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (x->flags & ROLE_STAR) { 195913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < p->p_roles.nprim++; i++) 196013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(r, i, 1)) 196113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 196213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 196313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 196413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 196513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rolemap) { 196613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (map_ebitmap(&x->roles, &mapped_roles, rolemap)) 196713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 196813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 196913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&mapped_roles, &x->roles)) 197013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 197113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 197213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 197313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&mapped_roles, rnode, i) { 197413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(rnode, i)) { 197513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(r, i, 1)) 197613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 197713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 197813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 197913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 198013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&mapped_roles); 198113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 198213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* if role is to be complimented, invert the entire bitmap here */ 198313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (x->flags & ROLE_COMP) { 198413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < ebitmap_length(r); i++) { 198513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_get_bit(r, i)) { 198613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(r, i, 0)) 198713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 198813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 198913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(r, i, 1)) 199013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 199113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 199213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 199313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 199413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 199513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 199613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 199713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Expand a type set into an ebitmap containing the types. This 199813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * handles the negset, attributes, and flags. 199913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Attribute expansion depends on several factors: 200013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * - if alwaysexpand is 1, then they will be expanded, 200113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * - if the type set has a negset or flags, then they will be expanded, 200213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * - otherwise, they will not be expanded. 200313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 200413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, 200513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned char alwaysexpand) 200613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 200713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 200813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t types, neg_types; 200913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *tnode; 201013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 201113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&types); 201213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(t); 201313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 201413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (alwaysexpand || ebitmap_length(&set->negset) || set->flags) { 201513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* First go through the types and OR all the attributes to types */ 201613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&set->types, tnode, i) { 201713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(tnode, i)) { 201813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->type_val_to_struct[i]->flavor == 201913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle TYPE_ATTRIB) { 202013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union 202113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&types, 202213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &p->type_val_to_struct[i]-> 202313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle types)) { 202413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 202513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 202613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 202713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(&types, i, 1)) { 202813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 202913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 203013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 203113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 203213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 203313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 203413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* No expansion of attributes, just copy the set as is. */ 203513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&types, &set->types)) 203613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 203713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 203813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 203913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Now do the same thing for negset */ 204013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&neg_types); 204113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&set->negset, tnode, i) { 204213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(tnode, i)) { 204313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->type_val_to_struct[i] && 204413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { 204513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_union 204613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (&neg_types, 204713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &p->type_val_to_struct[i]->types)) { 204813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 204913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 205013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 205113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(&neg_types, i, 1)) { 205213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 205313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 205413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 205513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 205613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 205713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 205813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (set->flags & TYPE_STAR) { 205913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* set all types not in neg_types */ 206013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < p->p_types.nprim; i++) { 206113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_get_bit(&neg_types, i)) 206213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 206313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->type_val_to_struct[i] && 206413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) 206513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 206613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(t, i, 1)) 206713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 206813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 206913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 207013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 207113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 207213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(&types, tnode, i) { 207313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_node_get_bit(tnode, i) 207413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle && (!ebitmap_get_bit(&neg_types, i))) 207513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(t, i, 1)) 207613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 207713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 207813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 207913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (set->flags & TYPE_COMP) { 208013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < p->p_types.nprim; i++) { 208113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (p->type_val_to_struct[i] && 208213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { 208313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(!ebitmap_get_bit(t, i)); 208413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 208513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 208613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_get_bit(t, i)) { 208713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(t, i, 0)) 208813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 208913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 209013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(t, i, 1)) 209113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 209213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 209313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 209413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 209513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 209613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out: 209713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 209813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&types); 209913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&neg_types); 210013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 210113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 210213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 210313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 210413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap, 210513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t * source_rule) 210613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 210713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t stypes, ttypes; 210813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t *avrule; 210913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_perm_node_t *cur_perm, *new_perm, *tail_perm; 211013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 211113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&stypes); 211213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&ttypes); 211313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 211413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set 211513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (dest_pol, typemap, &source_rule->stypes, &stypes, 1)) 211613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 211713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_convert_type_set 211813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (dest_pol, typemap, &source_rule->ttypes, &ttypes, 1)) 211913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 212013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 212113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule = (avrule_t *) malloc(sizeof(avrule_t)); 212213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!avrule) 212313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 212413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 212513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_init(avrule); 212613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule->specified = AVRULE_NEVERALLOW; 212713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule->line = source_rule->line; 212813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule->flags = source_rule->flags; 212913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 213013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&avrule->stypes.types, &stypes)) 213113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 213213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 213313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&avrule->ttypes.types, &ttypes)) 213413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 213513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 213613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_perm = source_rule->perms; 213713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail_perm = NULL; 213813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur_perm) { 213913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm = 214013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 214113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_perm) 214213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto err; 214313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle class_perm_node_init(new_perm); 214413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm->class = cur_perm->class; 214513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(new_perm->class); 214613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 214713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* once we have modules with permissions we'll need to map the permissions (and classes) */ 214813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_perm->data = cur_perm->data; 214913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 215013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!avrule->perms) 215113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule->perms = new_perm; 215213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 215313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (tail_perm) 215413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail_perm->next = new_perm; 215513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail_perm = new_perm; 215613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_perm = cur_perm->next; 215713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 215813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 215913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* just prepend the avrule to the first branch; it'll never be 216013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle written to disk */ 216113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!dest_pol->global->branch_list->avrules) 216213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_pol->global->branch_list->avrules = avrule; 216313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else { 216413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule->next = dest_pol->global->branch_list->avrules; 216513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle dest_pol->global->branch_list->avrules = avrule; 216613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 216713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 216813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&stypes); 216913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&ttypes); 217013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 217113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 217213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 217313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle err: 217413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&stypes); 217513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&ttypes); 217613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&avrule->stypes.types); 217713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_destroy(&avrule->ttypes.types); 217813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_perm = avrule->perms; 217913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur_perm) { 218013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle tail_perm = cur_perm->next; 218113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(cur_perm); 218213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_perm = tail_perm; 218313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 218413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(avrule); 218513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 218613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 218713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 218813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* 218913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Expands the avrule blocks for a policy. RBAC rules are copied. Neverallow 219013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * rules are copied or expanded as per the settings in the state object; all 219113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * other AV rules are expanded. If neverallow rules are expanded, they are not 219213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * copied, otherwise they are copied for later use by the assertion checker. 219313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 219413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int copy_and_expand_avrule_block(expand_state_t * state) 219513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 219613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *curblock = state->base->global; 219713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *prevblock; 219813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval = -1; 219913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 220013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (avtab_alloc(&state->out->te_avtab, MAX_AVTAB_SIZE)) { 220113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of Memory!"); 220213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 220313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 220413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 220513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (avtab_alloc(&state->out->te_cond_avtab, MAX_AVTAB_SIZE)) { 220613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, "Out of Memory!"); 220713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 220813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 220913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 221013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (curblock) { 221113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = curblock->enabled; 221213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_t *cur_avrule; 221313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 221413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (decl == NULL) { 221513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* nothing was enabled within this block */ 221613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cont; 221713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 221813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 221913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy role allows and role trans */ 222013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_role_allows(state, decl->role_allow_rules) != 0 || 222113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle copy_role_trans(state, decl->role_tr_rules) != 0) { 222213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 222313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 222413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 222513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* expand the range transition rules */ 222613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (expand_range_trans(state, decl->range_tr_rules)) 222713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 222813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 222913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy rules */ 223013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_avrule = decl->avrules; 223113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (cur_avrule != NULL) { 223213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(state->expand_neverallow) 223313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle && cur_avrule->specified & AVRULE_NEVERALLOW) { 223413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy this over directly so that assertions are checked later */ 223513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_neverallow 223613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->out, state->typemap, cur_avrule)) 223713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(state->handle, 223813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Error while copying neverallow."); 223913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 224013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cur_avrule->specified & AVRULE_NEVERALLOW) { 224113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->out->unsupported_format = 1; 224213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 224313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (convert_and_expand_rule 224413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state->handle, state->out, state->typemap, 224513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_avrule, &state->out->te_avtab, NULL, 224613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle NULL, 0, 224713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->expand_neverallow) != 224813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle EXPAND_RULE_SUCCESS) { 224913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 225013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 225113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 225213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cur_avrule = cur_avrule->next; 225313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 225413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 225513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy conditional rules */ 225613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (cond_node_copy(state, decl->cond_list)) 225713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 225813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 225913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cont: 226013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle prevblock = curblock; 226113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle curblock = curblock->next; 226213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 226313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (state->handle && state->handle->expand_consume_base) { 226413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* set base top avrule block in case there 226513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * is an error condition and the policy needs 226613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to be destroyed */ 226713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state->base->global = curblock; 226813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_destroy(prevblock); 226913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 227013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 227113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 227213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 0; 227313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 227413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 227513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 227613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 227713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 227813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* 227913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This function allows external users of the library (such as setools) to 228013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * expand only the avrules and optionally perform expansion of neverallow rules 228113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * or expand into the same policy for analysis purposes. 228213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 228313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint expand_module_avrules(sepol_handle_t * handle, policydb_t * base, 228413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * out, uint32_t * typemap, 228513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t * boolmap, uint32_t * rolemap, 228613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t * usermap, int verbose, 228713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int expand_neverallow) 228813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 228913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t state; 229013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 229113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_init(&state); 229213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 229313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.base = base; 229413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.out = out; 229513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.typemap = typemap; 229613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.boolmap = boolmap; 229713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.rolemap = rolemap; 229813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.usermap = usermap; 229913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.handle = handle; 230013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.verbose = verbose; 230113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.expand_neverallow = expand_neverallow; 230213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 230313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return copy_and_expand_avrule_block(&state); 230413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 230513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 230613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Linking should always be done before calling expand, even if 230713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * there is only a base since all optionals are dealt with at link time 230813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the base passed in should be indexed and avrule blocks should be 230913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * enabled. 231013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 231113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint expand_module(sepol_handle_t * handle, 231213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t * base, policydb_t * out, int verbose, int check) 231313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 231413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval = -1; 231513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 231613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_t state; 231713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_block_t *curblock; 231813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 231913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expand_state_init(&state); 232013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 232113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.verbose = verbose; 232213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.typemap = NULL; 232313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.base = base; 232413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.out = out; 232513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.handle = handle; 232613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 232713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (base->policy_type != POLICY_BASE) { 232813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Target of expand was not a base policy."); 232913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 233013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 233113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 233213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.out->policy_type = POLICY_KERN; 233313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.out->policyvers = POLICYDB_VERSION_MAX; 233413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 233513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Copy mls state from base to out */ 233613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out->mls = base->mls; 233713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out->handle_unknown = base->handle_unknown; 233813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 233913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Copy policy capabilities */ 234013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_cpy(&out->policycaps, &base->policycaps)) { 234113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 234213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 234313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 234413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 234513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((state.typemap = 234613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (uint32_t *) calloc(state.base->p_types.nprim, 234713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(uint32_t))) == NULL) { 234813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 234913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 235013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 235113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 235213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t)); 235313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!state.boolmap) { 235413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 235513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 235613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 235713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 235813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.rolemap = (uint32_t *)calloc(state.base->p_roles.nprim, sizeof(uint32_t)); 235913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!state.rolemap) { 236013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 236113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 236213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 236313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 236413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.usermap = (uint32_t *)calloc(state.base->p_users.nprim, sizeof(uint32_t)); 236513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!state.usermap) { 236613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 236713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 236813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 236913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 237013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* order is important - types must be first */ 237113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 237213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy types */ 237313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.base->p_types.table, type_copy_callback, &state)) { 237413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 237513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 237613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 237713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* convert attribute type sets */ 237813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 237913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state.base->p_types.table, attr_convert_callback, &state)) { 238013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 238113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 238213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 238313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy commons */ 238413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 238513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state.base->p_commons.table, common_copy_callback, &state)) { 238613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 238713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 238813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 238913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy classes, note, this does not copy constraints, constraints can't be 239013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * copied until after all the blocks have been processed and attributes are complete */ 239113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 239213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state.base->p_classes.table, class_copy_callback, &state)) { 239313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 239413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 239513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 239613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy aliases */ 239713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.base->p_types.table, alias_copy_callback, &state)) 239813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 239913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 240013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* index here so that type indexes are available for role_copy_callback */ 240113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_others(handle, out, verbose)) { 240213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Error while indexing out symbols"); 240313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 240413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 240513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 240613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy roles */ 240713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.base->p_roles.table, role_copy_callback, &state)) 240813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 240913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 241013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy MLS's sensitivity level and categories - this needs to be done 241113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * before expanding users (they need to be indexed too) */ 241213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.base->p_levels.table, sens_copy_callback, &state)) 241313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 241413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.base->p_cats.table, cats_copy_callback, &state)) 241513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 241613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_others(handle, out, verbose)) { 241713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Error while indexing out symbols"); 241813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 241913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 242013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 242113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy users */ 242213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.base->p_users.table, user_copy_callback, &state)) 242313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 242413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 242513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy bools */ 242613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.base->p_bools.table, bool_copy_callback, &state)) 242713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 242813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 242913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_classes(out)) { 243013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Error while indexing out classes"); 243113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 243213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 243313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (policydb_index_others(handle, out, verbose)) { 243413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Error while indexing out symbols"); 243513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 243613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 243713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 243813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* loop through all decls and union attributes, roles, users */ 243913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (curblock = state.base->global; curblock != NULL; 244013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle curblock = curblock->next) { 244113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avrule_decl_t *decl = curblock->enabled; 244213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 244313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (decl == NULL) { 244413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* nothing was enabled within this block */ 244513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 244613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 244713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 244813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* convert attribute type sets */ 244913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 245013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (decl->p_types.table, attr_convert_callback, &state)) { 245113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 245213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 245313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 245413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy roles */ 245513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 245613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (decl->p_roles.table, role_copy_callback, &state)) 245713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 245813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 245913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy users */ 246013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 246113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (decl->p_users.table, user_copy_callback, &state)) 246213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 246313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 246413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 246513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 246613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* remap role dominates bitmaps */ 246713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.out->p_roles.table, role_remap_dominates, &state)) { 246813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 246913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 247013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 247113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (copy_and_expand_avrule_block(&state) < 0) { 247213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Error during expand"); 247313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 247413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 247513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 247613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy constraints */ 247713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map 247813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (state.base->p_classes.table, constraint_copy_callback, &state)) { 247913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 248013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 248113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 248213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_optimize_lists(state.out->cond_list); 248313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle evaluate_conds(state.out); 248413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 248513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy ocontexts */ 248613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ocontext_copy(&state)) 248713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 248813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 248913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* copy genfs */ 249013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (genfs_copy(&state)) 249113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 249213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 249313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Build the type<->attribute maps and remove attributes. */ 249413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.out->attr_type_map = malloc(state.out->p_types.nprim * 249513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(ebitmap_t)); 249613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.out->type_attr_map = malloc(state.out->p_types.nprim * 249713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sizeof(ebitmap_t)); 249813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!state.out->attr_type_map || !state.out->type_attr_map) { 249913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 250013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 250113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 250213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < state.out->p_types.nprim; i++) { 250313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&state.out->type_attr_map[i]); 250413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_init(&state.out->attr_type_map[i]); 250513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* add the type itself as the degenerate case */ 250613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ebitmap_set_bit(&state.out->type_attr_map[i], i, 1)) { 250713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(handle, "Out of memory!"); 250813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 250913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 251013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 251113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hashtab_map(state.out->p_types.table, type_attr_map, &state)) 251213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 251313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hashtab_map_remove_on_error(state.out->p_types.table, 251413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_attr_remove, type_destroy, state.out); 251513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (check) { 251613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hierarchy_check_constraints(handle, state.out)) 251713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 251813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 251913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (check_assertions 252013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (handle, state.out, 252113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle state.out->global->branch_list->avrules)) 252213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 252313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 252413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 252513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 0; 252613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 252713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 252813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(state.typemap); 252913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(state.boolmap); 253013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(state.rolemap); 253113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(state.usermap); 253213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 253313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 253413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 253513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d) 253613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 253713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_ptr_t node; 253813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_datum_t *avd; 253913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 254013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 254113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_search_node(a, k); 254213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node) { 254313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = avtab_insert(a, k, d); 254413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 254513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Out of memory!"); 254613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return rc; 254713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 254813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 254913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((k->specified & AVTAB_ENABLED) != 255013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (node->key.specified & AVTAB_ENABLED)) { 255113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_insert_nonunique(a, k, d); 255213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node) { 255313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Out of memory!"); 255413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 255513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 255613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 255713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 255813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 255913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avd = &node->datum; 256013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (k->specified & ~AVTAB_ENABLED) { 256113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case AVTAB_ALLOWED: 256213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case AVTAB_AUDITALLOW: 256313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avd->data |= d->data; 256413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 256513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case AVTAB_AUDITDENY: 256613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avd->data &= d->data; 256713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 256813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 256913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Type conflict!"); 257013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 257113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 257213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 257313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 257413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 257513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 257613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestruct expand_avtab_data { 257713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_t *expa; 257813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *p; 257913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 258013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}; 258113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 258213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args) 258313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 258413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct expand_avtab_data *ptr = args; 258513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_t *expa = ptr->expa; 258613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle policydb_t *p = ptr->p; 258713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; 258813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; 258913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; 259013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; 259113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *snode, *tnode; 259213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 259313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_key_t newkey; 259413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 259513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 259613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_class = k->target_class; 259713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.specified = k->specified; 259813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 259913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stype && ttype) { 260013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Both are individual types, no expansion required. */ 260113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return expand_avtab_insert(expa, k, d); 260213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 260313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 260413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stype) { 260513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Source is an individual type, target is an attribute. */ 260613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.source_type = k->source_type; 260713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(tattr, tnode, j) { 260813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 260913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 261013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_type = j + 1; 261113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = expand_avtab_insert(expa, &newkey, d); 261213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 261313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 261413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 261513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 261613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 261713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 261813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ttype) { 261913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Target is an individual type, source is an attribute. */ 262013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_type = k->target_type; 262113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(sattr, snode, i) { 262213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(snode, i)) 262313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 262413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.source_type = i + 1; 262513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = expand_avtab_insert(expa, &newkey, d); 262613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 262713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 262813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 262913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 263013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 263113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 263213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Both source and target type are attributes. */ 263313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(sattr, snode, i) { 263413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(snode, i)) 263513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 263613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(tattr, tnode, j) { 263713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 263813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 263913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.source_type = i + 1; 264013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_type = j + 1; 264113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = expand_avtab_insert(expa, &newkey, d); 264213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 264313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 264413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 264513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 264613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 264713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 264813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 264913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 265013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa) 265113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 265213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct expand_avtab_data data; 265313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 265413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (avtab_alloc(expa, MAX_AVTAB_SIZE)) { 265513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Out of memory!"); 265613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 265713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 265813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 265913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data.expa = expa; 266013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data.p = p; 266113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return avtab_map(a, expand_avtab_node, &data); 266213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 266313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 266413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int expand_cond_insert(cond_av_list_t ** l, 266513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_t * expa, 266613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_key_t * k, avtab_datum_t * d) 266713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 266813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_ptr_t node; 266913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_datum_t *avd; 267013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t *nl; 267113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 267213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_search_node(expa, k); 267313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node || 267413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (k->specified & AVTAB_ENABLED) != 267513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (node->key.specified & AVTAB_ENABLED)) { 267613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = avtab_insert_nonunique(expa, k, d); 267713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!node) { 267813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Out of memory!"); 267913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 268013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 268113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node->parse_context = (void *)1; 268213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nl = (cond_av_list_t *) malloc(sizeof(*nl)); 268313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!nl) { 268413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Out of memory!"); 268513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 268613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 268713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(nl, 0, sizeof(*nl)); 268813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nl->node = node; 268913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nl->next = *l; 269013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *l = nl; 269113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 269213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 269313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 269413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avd = &node->datum; 269513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle switch (k->specified & ~AVTAB_ENABLED) { 269613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case AVTAB_ALLOWED: 269713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case AVTAB_AUDITALLOW: 269813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avd->data |= d->data; 269913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 270013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle case AVTAB_AUDITDENY: 270113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avd->data &= d->data; 270213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 270313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle default: 270413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Type conflict!"); 270513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 270613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 270713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 270813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 270913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 271013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 271113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint expand_cond_av_node(policydb_t * p, 271213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_ptr_t node, 271313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** newl, avtab_t * expa) 271413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 271513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_key_t *k = &node->key; 271613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_datum_t *d = &node->datum; 271713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; 271813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; 271913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; 272013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; 272113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_node_t *snode, *tnode; 272213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i, j; 272313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_key_t newkey; 272413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 272513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 272613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_class = k->target_class; 272713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.specified = k->specified; 272813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 272913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stype && ttype) { 273013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Both are individual types, no expansion required. */ 273113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return expand_cond_insert(newl, expa, k, d); 273213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 273313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 273413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (stype) { 273513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Source is an individual type, target is an attribute. */ 273613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.source_type = k->source_type; 273713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(tattr, tnode, j) { 273813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 273913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 274013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_type = j + 1; 274113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = expand_cond_insert(newl, expa, &newkey, d); 274213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 274313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 274413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 274513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 274613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 274713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 274813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ttype) { 274913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Target is an individual type, source is an attribute. */ 275013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_type = k->target_type; 275113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(sattr, snode, i) { 275213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(snode, i)) 275313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 275413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.source_type = i + 1; 275513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = expand_cond_insert(newl, expa, &newkey, d); 275613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 275713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 275813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 275913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 276013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 276113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 276213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Both source and target type are attributes. */ 276313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(sattr, snode, i) { 276413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(snode, i)) 276513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 276613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ebitmap_for_each_bit(tattr, tnode, j) { 276713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ebitmap_node_get_bit(tnode, j)) 276813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 276913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.source_type = i + 1; 277013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newkey.target_type = j + 1; 277113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = expand_cond_insert(newl, expa, &newkey, d); 277213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 277313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 277413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 277513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 277613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 277713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 277813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 277913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 278013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint expand_cond_av_list(policydb_t * p, cond_av_list_t * l, 278113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t ** newl, avtab_t * expa) 278213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 278313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cond_av_list_t *cur; 278413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle avtab_ptr_t node; 278513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rc; 278613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 278713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (avtab_alloc(expa, MAX_AVTAB_SIZE)) { 278813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(NULL, "Out of memory!"); 278913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 279013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 279113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 279213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *newl = NULL; 279313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (cur = l; cur; cur = cur->next) { 279413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle node = cur->node; 279513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle rc = expand_cond_av_node(p, node, newl, expa); 279613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (rc) 279713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return rc; 279813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 279913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 280013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 280113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 2802