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