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