• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
2  *	    Joshua Brindle <jbrindle@tresys.com>
3  *          Jason Tang <jtang@tresys.com>
4  *
5  * Copyright (C) 2004-2005 Tresys Technology, LLC
6  * Copyright (C) 2007 Red Hat, Inc.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2.1 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22 
23 #include <sepol/policydb/policydb.h>
24 #include <sepol/policydb/conditional.h>
25 #include <sepol/policydb/hashtab.h>
26 #include <sepol/policydb/avrule_block.h>
27 #include <sepol/policydb/link.h>
28 #include <sepol/policydb/util.h>
29 
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <assert.h>
35 
36 #include "debug.h"
37 #include "private.h"
38 
39 #undef min
40 #define min(a,b) (((a) < (b)) ? (a) : (b))
41 
42 typedef struct policy_module {
43 	policydb_t *policy;
44 	uint32_t num_decls;
45 	uint32_t *map[SYM_NUM];
46 	uint32_t *avdecl_map;
47 	uint32_t **perm_map;
48 	uint32_t *perm_map_len;
49 
50 	/* a pointer to within the base module's avrule_block chain to
51 	 * where this module's global now resides */
52 	avrule_block_t *base_global;
53 } policy_module_t;
54 
55 typedef struct link_state {
56 	int verbose;
57 	policydb_t *base;
58 	avrule_block_t *last_avrule_block, *last_base_avrule_block;
59 	uint32_t next_decl_id, current_decl_id;
60 
61 	/* temporary variables, used during hashtab_map() calls */
62 	policy_module_t *cur;
63 	char *cur_mod_name;
64 	avrule_decl_t *dest_decl;
65 	class_datum_t *src_class, *dest_class;
66 	char *dest_class_name;
67 	char dest_class_req;	/* flag indicating the class was not declared */
68 	uint32_t symbol_num;
69 	/* used to report the name of the module if dependency error occurs */
70 	policydb_t **decl_to_mod;
71 
72 	/* error reporting fields */
73 	sepol_handle_t *handle;
74 } link_state_t;
75 
76 typedef struct missing_requirement {
77 	uint32_t symbol_type;
78 	uint32_t symbol_value;
79 	uint32_t perm_value;
80 } missing_requirement_t;
81 
82 static const char * const symtab_names[SYM_NUM] = {
83 	"common", "class", "role", "type/attribute", "user",
84 	"bool", "level", "category"
85 };
86 
87 /* Deallocates all elements within a module, but NOT the policydb_t
88  * structure within, as well as the pointer itself. */
policy_module_destroy(policy_module_t * mod)89 static void policy_module_destroy(policy_module_t * mod)
90 {
91 	unsigned int i;
92 	if (mod == NULL) {
93 		return;
94 	}
95 	for (i = 0; i < SYM_NUM; i++) {
96 		free(mod->map[i]);
97 	}
98 	for (i = 0; mod->perm_map != NULL && i < mod->policy->p_classes.nprim;
99 	     i++) {
100 		free(mod->perm_map[i]);
101 	}
102 	free(mod->perm_map);
103 	free(mod->perm_map_len);
104 	free(mod->avdecl_map);
105 	free(mod);
106 }
107 
108 /***** functions that copy identifiers from a module to base *****/
109 
110 /* Note: there is currently no scoping for permissions, which causes some
111  * strange side-effects. The current approach is this:
112  *
113  * a) perm is required and the class _and_ perm are declared in base: only add a mapping.
114  * b) perm is required and the class and perm are _not_ declared in base: simply add the permissions
115  *    to the object class. This means that the requirements for the decl are the union of the permissions
116  *    required for all decls, but who cares.
117  * c) perm is required, the class is declared in base, but the perm is not present. Nothing we can do
118  *    here because we can't mark a single permission as required, so we bail with a requirement error
119  *    _even_ if we are in an optional.
120  *
121  * A is correct behavior, b is wrong but not too bad, c is totall wrong for optionals. Fixing this requires
122  * a format change.
123  */
permission_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)124 static int permission_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
125 				    void *data)
126 {
127 	char *perm_id = key, *new_id = NULL;
128 	perm_datum_t *perm, *new_perm = NULL, *dest_perm;
129 	link_state_t *state = (link_state_t *) data;
130 
131 	class_datum_t *src_class = state->src_class;
132 	class_datum_t *dest_class = state->dest_class;
133 	policy_module_t *mod = state->cur;
134 	uint32_t sclassi = src_class->s.value - 1;
135 	int ret;
136 
137 	perm = (perm_datum_t *) datum;
138 	dest_perm = hashtab_search(dest_class->permissions.table, perm_id);
139 	if (dest_perm == NULL && dest_class->comdatum != NULL) {
140 		dest_perm =
141 		    hashtab_search(dest_class->comdatum->permissions.table,
142 				   perm_id);
143 	}
144 
145 	if (dest_perm == NULL) {
146 		/* If the object class was not declared in the base, add the perm
147 		 * to the object class. */
148 		if (state->dest_class_req) {
149 			/* If the class was required (not declared), insert the new permission */
150 			new_id = strdup(perm_id);
151 			if (new_id == NULL) {
152 				ERR(state->handle, "Memory error");
153 				ret = SEPOL_ERR;
154 				goto err;
155 			}
156 			new_perm =
157 			    (perm_datum_t *) calloc(1, sizeof(perm_datum_t));
158 			if (new_perm == NULL) {
159 				ERR(state->handle, "Memory error");
160 				ret = SEPOL_ERR;
161 				goto err;
162 			}
163 			ret = hashtab_insert(dest_class->permissions.table,
164 					     (hashtab_key_t) new_id,
165 					     (hashtab_datum_t) new_perm);
166 			if (ret) {
167 				ERR(state->handle,
168 				    "could not insert permission into class");
169 				goto err;
170 			}
171 			new_perm->s.value = dest_class->permissions.nprim + 1;
172 			dest_perm = new_perm;
173 		} else {
174 			/* this is case c from above */
175 			ERR(state->handle,
176 			    "Module %s depends on permission %s in class %s, not satisfied",
177 			    state->cur_mod_name, perm_id,
178 			    state->dest_class_name);
179 			return SEPOL_EREQ;
180 		}
181 	}
182 
183 	/* build the mapping for permissions encompassing this class.
184 	 * unlike symbols, the permission map translates between
185 	 * module permission bit to target permission bit.  that bit
186 	 * may have originated from the class -or- it could be from
187 	 * the class's common parent.*/
188 	if (perm->s.value > mod->perm_map_len[sclassi]) {
189 		uint32_t *newmap = calloc(perm->s.value, sizeof(*newmap));
190 		if (newmap == NULL) {
191 			ERR(state->handle, "Out of memory!");
192 			return -1;
193 		}
194 		if (mod->perm_map_len[sclassi] > 0) {
195 			memcpy(newmap, mod->perm_map[sclassi], mod->perm_map_len[sclassi] * sizeof(*newmap));
196 		}
197 		free(mod->perm_map[sclassi]);
198 		mod->perm_map[sclassi] = newmap;
199 		mod->perm_map_len[sclassi] = perm->s.value;
200 	}
201 	mod->perm_map[sclassi][perm->s.value - 1] = dest_perm->s.value;
202 
203 	return 0;
204       err:
205 	free(new_id);
206 	free(new_perm);
207 	return ret;
208 }
209 
class_copy_default_new_object(link_state_t * state,class_datum_t * olddatum,class_datum_t * newdatum)210 static int class_copy_default_new_object(link_state_t *state,
211 					 class_datum_t *olddatum,
212 					 class_datum_t *newdatum)
213 {
214 	if (olddatum->default_user) {
215 		if (newdatum->default_user && olddatum->default_user != newdatum->default_user) {
216 			ERR(state->handle, "Found conflicting default user definitions");
217 			return SEPOL_ENOTSUP;
218 		}
219 		newdatum->default_user = olddatum->default_user;
220 	}
221 	if (olddatum->default_role) {
222 		if (newdatum->default_role && olddatum->default_role != newdatum->default_role) {
223 			ERR(state->handle, "Found conflicting default role definitions");
224 			return SEPOL_ENOTSUP;
225 		}
226 		newdatum->default_role = olddatum->default_role;
227 	}
228 	if (olddatum->default_type) {
229 		if (newdatum->default_type && olddatum->default_type != newdatum->default_type) {
230 			ERR(state->handle, "Found conflicting default type definitions");
231 			return SEPOL_ENOTSUP;
232 		}
233 		newdatum->default_type = olddatum->default_type;
234 	}
235 	if (olddatum->default_range) {
236 		if (newdatum->default_range && olddatum->default_range != newdatum->default_range) {
237 			ERR(state->handle, "Found conflicting default range definitions");
238 			return SEPOL_ENOTSUP;
239 		}
240 		newdatum->default_range = olddatum->default_range;
241 	}
242 	return 0;
243 }
244 
class_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)245 static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
246 			       void *data)
247 {
248 	char *id = key, *new_id = NULL;
249 	class_datum_t *cladatum, *new_class = NULL;
250 	link_state_t *state = (link_state_t *) data;
251 	scope_datum_t *scope = NULL;
252 	int ret;
253 
254 	cladatum = (class_datum_t *) datum;
255 	state->dest_class_req = 0;
256 
257 	new_class = hashtab_search(state->base->p_classes.table, id);
258 	/* If there is not an object class already in the base symtab that means
259 	 * that either a) a module is trying to declare a new object class (which
260 	 * the compiler should prevent) or b) an object class was required that is
261 	 * not in the base.
262 	 */
263 	if (new_class == NULL) {
264 		scope =
265 		    hashtab_search(state->cur->policy->p_classes_scope.table,
266 				   id);
267 		if (scope == NULL) {
268 			ret = SEPOL_ERR;
269 			goto err;
270 		}
271 		if (scope->scope == SCOPE_DECL) {
272 			/* disallow declarations in modules */
273 			ERR(state->handle,
274 			    "%s: Modules may not yet declare new classes.",
275 			    state->cur_mod_name);
276 			ret = SEPOL_ENOTSUP;
277 			goto err;
278 		} else {
279 			/* It would be nice to error early here because the requirement is
280 			 * not met, but we cannot because the decl might be optional (in which
281 			 * case we should record the requirement so that it is just turned
282 			 * off). Note: this will break horribly if modules can declare object
283 			 * classes because the class numbers will be all wrong (i.e., they
284 			 * might be assigned in the order they were required rather than the
285 			 * current scheme which ensures correct numbering by ordering the
286 			 * declarations properly). This can't be fixed until some infrastructure
287 			 * for querying the object class numbers is in place. */
288 			state->dest_class_req = 1;
289 			new_class =
290 			    (class_datum_t *) calloc(1, sizeof(class_datum_t));
291 			if (new_class == NULL) {
292 				ERR(state->handle, "Memory error");
293 				ret = SEPOL_ERR;
294 				goto err;
295 			}
296 			if (symtab_init
297 			    (&new_class->permissions, PERM_SYMTAB_SIZE)) {
298 				ret = SEPOL_ERR;
299 				goto err;
300 			}
301 			new_id = strdup(id);
302 			if (new_id == NULL) {
303 				ERR(state->handle, "Memory error");
304 				symtab_destroy(&new_class->permissions);
305 				ret = SEPOL_ERR;
306 				goto err;
307 			}
308 			ret = hashtab_insert(state->base->p_classes.table,
309 					     (hashtab_key_t) new_id,
310 					     (hashtab_datum_t) new_class);
311 			if (ret) {
312 				ERR(state->handle,
313 				    "could not insert new class into symtab");
314 				symtab_destroy(&new_class->permissions);
315 				goto err;
316 			}
317 			new_class->s.value = ++(state->base->p_classes.nprim);
318 		}
319 	}
320 
321 	state->cur->map[SYM_CLASSES][cladatum->s.value - 1] =
322 	    new_class->s.value;
323 
324 	/* copy permissions */
325 	state->src_class = cladatum;
326 	state->dest_class = new_class;
327 	state->dest_class_name = (char *)key;
328 
329 	/* copy default new object rules */
330 	ret = class_copy_default_new_object(state, cladatum, new_class);
331 	if (ret)
332 		return ret;
333 
334 	ret =
335 	    hashtab_map(cladatum->permissions.table, permission_copy_callback,
336 			state);
337 	if (ret != 0) {
338 		return ret;
339 	}
340 
341 	return 0;
342       err:
343 	free(new_class);
344 	free(new_id);
345 	return ret;
346 }
347 
role_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)348 static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
349 			      void *data)
350 {
351 	int ret;
352 	char *id = key, *new_id = NULL;
353 	role_datum_t *role, *base_role, *new_role = NULL;
354 	link_state_t *state = (link_state_t *) data;
355 
356 	role = (role_datum_t *) datum;
357 
358 	base_role = hashtab_search(state->base->p_roles.table, id);
359 	if (base_role != NULL) {
360 		/* role already exists.  check that it is what this
361 		 * module expected.  duplicate declarations (e.g., two
362 		 * modules both declare role foo_r) is checked during
363 		 * scope_copy_callback(). */
364 		if (role->flavor == ROLE_ATTRIB
365 		    && base_role->flavor != ROLE_ATTRIB) {
366 			ERR(state->handle,
367 			    "%s: Expected %s to be a role attribute, but it was already declared as a regular role.",
368 			    state->cur_mod_name, id);
369 			return -1;
370 		} else if (role->flavor != ROLE_ATTRIB
371 			   && base_role->flavor == ROLE_ATTRIB) {
372 			ERR(state->handle,
373 			    "%s: Expected %s to be a regular role, but it was already declared as a role attribute.",
374 			    state->cur_mod_name, id);
375 			return -1;
376 		}
377 	} else {
378 		if (state->verbose)
379 			INFO(state->handle, "copying role %s", id);
380 
381 		if ((new_id = strdup(id)) == NULL) {
382 			goto cleanup;
383 		}
384 
385 		if ((new_role =
386 		     (role_datum_t *) malloc(sizeof(*new_role))) == NULL) {
387 			goto cleanup;
388 		}
389 		role_datum_init(new_role);
390 
391 		/* new_role's dominates, types and roles field will be copied
392 		 * during role_fix_callback() */
393 		new_role->flavor = role->flavor;
394 		new_role->s.value = state->base->p_roles.nprim + 1;
395 
396 		ret = hashtab_insert(state->base->p_roles.table,
397 				     (hashtab_key_t) new_id,
398 				     (hashtab_datum_t) new_role);
399 		if (ret) {
400 			goto cleanup;
401 		}
402 		state->base->p_roles.nprim++;
403 		base_role = new_role;
404 	}
405 
406 	if (state->dest_decl) {
407 		new_id = NULL;
408 		if ((new_role = malloc(sizeof(*new_role))) == NULL) {
409 			goto cleanup;
410 		}
411 		role_datum_init(new_role);
412 		new_role->flavor = base_role->flavor;
413 		new_role->s.value = base_role->s.value;
414 		if ((new_id = strdup(id)) == NULL) {
415 			goto cleanup;
416 		}
417 		if (hashtab_insert
418 		    (state->dest_decl->p_roles.table, new_id, new_role)) {
419 			goto cleanup;
420 		}
421 		state->dest_decl->p_roles.nprim++;
422 	}
423 
424 	state->cur->map[SYM_ROLES][role->s.value - 1] = base_role->s.value;
425 	return 0;
426 
427       cleanup:
428 	ERR(state->handle, "Out of memory!");
429 	role_datum_destroy(new_role);
430 	free(new_id);
431 	free(new_role);
432 	return -1;
433 }
434 
435 /* Copy types and attributes from a module into the base module. The
436  * attributes are copied, but the types that make up this attribute
437  * are delayed type_fix_callback(). */
type_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)438 static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
439 			      void *data)
440 {
441 	int ret;
442 	char *id = key, *new_id = NULL;
443 	type_datum_t *type, *base_type, *new_type = NULL;
444 	link_state_t *state = (link_state_t *) data;
445 
446 	type = (type_datum_t *) datum;
447 	if ((type->flavor == TYPE_TYPE && !type->primary)
448 	    || type->flavor == TYPE_ALIAS) {
449 		/* aliases are handled later, in alias_copy_callback() */
450 		return 0;
451 	}
452 
453 	base_type = hashtab_search(state->base->p_types.table, id);
454 	if (base_type != NULL) {
455 		/* type already exists.  check that it is what this
456 		 * module expected.  duplicate declarations (e.g., two
457 		 * modules both declare type foo_t) is checked during
458 		 * scope_copy_callback(). */
459 		if (type->flavor == TYPE_ATTRIB
460 		    && base_type->flavor != TYPE_ATTRIB) {
461 			ERR(state->handle,
462 			    "%s: Expected %s to be an attribute, but it was already declared as a type.",
463 			    state->cur_mod_name, id);
464 			return -1;
465 		} else if (type->flavor != TYPE_ATTRIB
466 			   && base_type->flavor == TYPE_ATTRIB) {
467 			ERR(state->handle,
468 			    "%s: Expected %s to be a type, but it was already declared as an attribute.",
469 			    state->cur_mod_name, id);
470 			return -1;
471 		}
472 
473 		base_type->flags |= type->flags;
474 	} else {
475 		if (state->verbose)
476 			INFO(state->handle, "copying type %s", id);
477 
478 		if ((new_id = strdup(id)) == NULL) {
479 			goto cleanup;
480 		}
481 
482 		if ((new_type =
483 		     (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) {
484 			goto cleanup;
485 		}
486 		new_type->primary = type->primary;
487 		new_type->flags = type->flags;
488 		new_type->flavor = type->flavor;
489 		/* for attributes, the writing of new_type->types is
490 		   done in type_fix_callback() */
491 
492 		new_type->s.value = state->base->p_types.nprim + 1;
493 
494 		ret = hashtab_insert(state->base->p_types.table,
495 				     (hashtab_key_t) new_id,
496 				     (hashtab_datum_t) new_type);
497 		if (ret) {
498 			goto cleanup;
499 		}
500 		state->base->p_types.nprim++;
501 		base_type = new_type;
502 	}
503 
504 	if (state->dest_decl) {
505 		new_id = NULL;
506 		if ((new_type = calloc(1, sizeof(*new_type))) == NULL) {
507 			goto cleanup;
508 		}
509 		new_type->primary = type->primary;
510 		new_type->flavor = type->flavor;
511 		new_type->flags = type->flags;
512 		new_type->s.value = base_type->s.value;
513 		if ((new_id = strdup(id)) == NULL) {
514 			goto cleanup;
515 		}
516 		if (hashtab_insert
517 		    (state->dest_decl->p_types.table, new_id, new_type)) {
518 			goto cleanup;
519 		}
520 		state->dest_decl->p_types.nprim++;
521 	}
522 
523 	state->cur->map[SYM_TYPES][type->s.value - 1] = base_type->s.value;
524 	return 0;
525 
526       cleanup:
527 	ERR(state->handle, "Out of memory!");
528 	free(new_id);
529 	free(new_type);
530 	return -1;
531 }
532 
user_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)533 static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
534 			      void *data)
535 {
536 	int ret;
537 	char *id = key, *new_id = NULL;
538 	user_datum_t *user, *base_user, *new_user = NULL;
539 	link_state_t *state = (link_state_t *) data;
540 
541 	user = (user_datum_t *) datum;
542 
543 	base_user = hashtab_search(state->base->p_users.table, id);
544 	if (base_user == NULL) {
545 		if (state->verbose)
546 			INFO(state->handle, "copying user %s", id);
547 
548 		if ((new_id = strdup(id)) == NULL) {
549 			goto cleanup;
550 		}
551 
552 		if ((new_user =
553 		     (user_datum_t *) malloc(sizeof(*new_user))) == NULL) {
554 			goto cleanup;
555 		}
556 		user_datum_init(new_user);
557 		/* new_users's roles and MLS fields will be copied during
558 		   user_fix_callback(). */
559 
560 		new_user->s.value = state->base->p_users.nprim + 1;
561 
562 		ret = hashtab_insert(state->base->p_users.table,
563 				     (hashtab_key_t) new_id,
564 				     (hashtab_datum_t) new_user);
565 		if (ret) {
566 			goto cleanup;
567 		}
568 		state->base->p_users.nprim++;
569 		base_user = new_user;
570 	}
571 
572 	if (state->dest_decl) {
573 		new_id = NULL;
574 		if ((new_user = malloc(sizeof(*new_user))) == NULL) {
575 			goto cleanup;
576 		}
577 		user_datum_init(new_user);
578 		new_user->s.value = base_user->s.value;
579 		if ((new_id = strdup(id)) == NULL) {
580 			goto cleanup;
581 		}
582 		if (hashtab_insert
583 		    (state->dest_decl->p_users.table, new_id, new_user)) {
584 			goto cleanup;
585 		}
586 		state->dest_decl->p_users.nprim++;
587 	}
588 
589 	state->cur->map[SYM_USERS][user->s.value - 1] = base_user->s.value;
590 	return 0;
591 
592       cleanup:
593 	ERR(state->handle, "Out of memory!");
594 	user_datum_destroy(new_user);
595 	free(new_id);
596 	free(new_user);
597 	return -1;
598 }
599 
bool_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)600 static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
601 			      void *data)
602 {
603 	int ret;
604 	char *id = key, *new_id = NULL;
605 	cond_bool_datum_t *booldatum, *base_bool, *new_bool = NULL;
606 	link_state_t *state = (link_state_t *) data;
607 	scope_datum_t *scope;
608 
609 	booldatum = (cond_bool_datum_t *) datum;
610 
611 	base_bool = hashtab_search(state->base->p_bools.table, id);
612 	if (base_bool == NULL) {
613 		if (state->verbose)
614 			INFO(state->handle, "copying boolean %s", id);
615 
616 		if ((new_id = strdup(id)) == NULL) {
617 			goto cleanup;
618 		}
619 
620 		if ((new_bool =
621 		     (cond_bool_datum_t *) malloc(sizeof(*new_bool))) == NULL) {
622 			goto cleanup;
623 		}
624 		new_bool->s.value = state->base->p_bools.nprim + 1;
625 
626 		ret = hashtab_insert(state->base->p_bools.table,
627 				     (hashtab_key_t) new_id,
628 				     (hashtab_datum_t) new_bool);
629 		if (ret) {
630 			goto cleanup;
631 		}
632 		state->base->p_bools.nprim++;
633 		base_bool = new_bool;
634 		base_bool->flags = booldatum->flags;
635 		base_bool->state = booldatum->state;
636 	} else if ((booldatum->flags & COND_BOOL_FLAGS_TUNABLE) !=
637 		   (base_bool->flags & COND_BOOL_FLAGS_TUNABLE)) {
638 			/* A mismatch between boolean/tunable declaration
639 			 * and usage(for example a boolean used in the
640 			 * tunable_policy() or vice versa).
641 			 *
642 			 * This is not allowed and bail out with errors */
643 			ERR(state->handle,
644 			    "%s: Mismatch between boolean/tunable definition "
645 			    "and usage for %s", state->cur_mod_name, id);
646 			return -1;
647 	}
648 
649 	/* Get the scope info for this boolean to see if this is the declaration,
650  	 * if so set the state */
651 	scope = hashtab_search(state->cur->policy->p_bools_scope.table, id);
652 	if (!scope)
653 		return SEPOL_ERR;
654 	if (scope->scope == SCOPE_DECL) {
655 		base_bool->state = booldatum->state;
656 		/* Only the declaration rather than requirement
657 		 * decides if it is a boolean or tunable. */
658 		base_bool->flags = booldatum->flags;
659 	}
660 	state->cur->map[SYM_BOOLS][booldatum->s.value - 1] = base_bool->s.value;
661 	return 0;
662 
663       cleanup:
664 	ERR(state->handle, "Out of memory!");
665 	cond_destroy_bool(new_id, new_bool, NULL);
666 	return -1;
667 }
668 
sens_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)669 static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
670 			      void *data)
671 {
672 	char *id = key;
673 	level_datum_t *level, *base_level;
674 	link_state_t *state = (link_state_t *) data;
675 	scope_datum_t *scope;
676 
677 	level = (level_datum_t *) datum;
678 
679 	base_level = hashtab_search(state->base->p_levels.table, id);
680 	if (!base_level) {
681 		scope =
682 		    hashtab_search(state->cur->policy->p_sens_scope.table, id);
683 		if (!scope)
684 			return SEPOL_ERR;
685 		if (scope->scope == SCOPE_DECL) {
686 			/* disallow declarations in modules */
687 			ERR(state->handle,
688 			    "%s: Modules may not declare new sensitivities.",
689 			    state->cur_mod_name);
690 			return SEPOL_ENOTSUP;
691 		} else if (scope->scope == SCOPE_REQ) {
692 			/* unmet requirement */
693 			ERR(state->handle,
694 			    "%s: Sensitivity %s not declared by base.",
695 			    state->cur_mod_name, id);
696 			return SEPOL_ENOTSUP;
697 		} else {
698 			ERR(state->handle,
699 			    "%s: has an unknown scope: %d",
700 			    state->cur_mod_name, scope->scope);
701 			return SEPOL_ENOTSUP;
702 		}
703 	}
704 
705 	state->cur->map[SYM_LEVELS][level->level->sens - 1] =
706 	    base_level->level->sens;
707 
708 	return 0;
709 }
710 
cat_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)711 static int cat_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
712 			     void *data)
713 {
714 	char *id = key;
715 	cat_datum_t *cat, *base_cat;
716 	link_state_t *state = (link_state_t *) data;
717 	scope_datum_t *scope;
718 
719 	cat = (cat_datum_t *) datum;
720 
721 	base_cat = hashtab_search(state->base->p_cats.table, id);
722 	if (!base_cat) {
723 		scope = hashtab_search(state->cur->policy->p_cat_scope.table, id);
724 		if (!scope)
725 			return SEPOL_ERR;
726 		if (scope->scope == SCOPE_DECL) {
727 			/* disallow declarations in modules */
728 			ERR(state->handle,
729 			    "%s: Modules may not declare new categories.",
730 			    state->cur_mod_name);
731 			return SEPOL_ENOTSUP;
732 		} else if (scope->scope == SCOPE_REQ) {
733 			/* unmet requirement */
734 			ERR(state->handle,
735 			    "%s: Category %s not declared by base.",
736 			    state->cur_mod_name, id);
737 			return SEPOL_ENOTSUP;
738 		} else {
739 			/* unknown scope?  malformed policy? */
740 			ERR(state->handle,
741 			    "%s: has an unknown scope: %d",
742 			    state->cur_mod_name, scope->scope);
743 			return SEPOL_ENOTSUP;
744 		}
745 	}
746 
747 	state->cur->map[SYM_CATS][cat->s.value - 1] = base_cat->s.value;
748 
749 	return 0;
750 }
751 
752 static int (*copy_callback_f[SYM_NUM]) (hashtab_key_t key,
753 					hashtab_datum_t datum, void *datap) = {
754 NULL, class_copy_callback, role_copy_callback, type_copy_callback,
755 	    user_copy_callback, bool_copy_callback, sens_copy_callback,
756 	    cat_copy_callback};
757 
758 /*
759  * The boundaries have to be copied after the types/roles/users are copied,
760  * because it refers hashtab to lookup destinated objects.
761  */
type_bounds_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)762 static int type_bounds_copy_callback(hashtab_key_t key,
763 				     hashtab_datum_t datum, void *data)
764 {
765 	link_state_t *state = (link_state_t *) data;
766 	type_datum_t *type = (type_datum_t *) datum;
767 	type_datum_t *dest;
768 	uint32_t bounds_val;
769 
770 	if (!type->bounds)
771 		return 0;
772 
773 	bounds_val = state->cur->map[SYM_TYPES][type->bounds - 1];
774 
775 	dest = hashtab_search(state->base->p_types.table, key);
776 	if (!dest) {
777 		ERR(state->handle,
778 		    "Type lookup failed for %s", (char *)key);
779 		return -1;
780 	}
781 	if (dest->bounds != 0 && dest->bounds != bounds_val) {
782 		ERR(state->handle,
783 		    "Inconsistent boundary for %s", (char *)key);
784 		return -1;
785 	}
786 	dest->bounds = bounds_val;
787 
788 	return 0;
789 }
790 
role_bounds_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)791 static int role_bounds_copy_callback(hashtab_key_t key,
792 				     hashtab_datum_t datum, void *data)
793 {
794 	link_state_t *state = (link_state_t *) data;
795 	role_datum_t *role = (role_datum_t *) datum;
796 	role_datum_t *dest;
797 	uint32_t bounds_val;
798 
799 	if (!role->bounds)
800 		return 0;
801 
802 	bounds_val = state->cur->map[SYM_ROLES][role->bounds - 1];
803 
804 	dest = hashtab_search(state->base->p_roles.table, key);
805 	if (!dest) {
806 		ERR(state->handle,
807 		    "Role lookup failed for %s", (char *)key);
808 		return -1;
809 	}
810 	if (dest->bounds != 0 && dest->bounds != bounds_val) {
811 		ERR(state->handle,
812 		    "Inconsistent boundary for %s", (char *)key);
813 		return -1;
814 	}
815 	dest->bounds = bounds_val;
816 
817 	return 0;
818 }
819 
user_bounds_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)820 static int user_bounds_copy_callback(hashtab_key_t key,
821 				     hashtab_datum_t datum, void *data)
822 {
823 	link_state_t *state = (link_state_t *) data;
824 	user_datum_t *user = (user_datum_t *) datum;
825 	user_datum_t *dest;
826 	uint32_t bounds_val;
827 
828 	if (!user->bounds)
829 		return 0;
830 
831 	bounds_val = state->cur->map[SYM_USERS][user->bounds - 1];
832 
833 	dest = hashtab_search(state->base->p_users.table, key);
834 	if (!dest) {
835 		ERR(state->handle,
836 		    "User lookup failed for %s", (char *)key);
837 		return -1;
838 	}
839 	if (dest->bounds != 0 && dest->bounds != bounds_val) {
840 		ERR(state->handle,
841 		    "Inconsistent boundary for %s", (char *)key);
842 		return -1;
843 	}
844 	dest->bounds = bounds_val;
845 
846 	return 0;
847 }
848 
849 /* The aliases have to be copied after the types and attributes to be
850  * certain that the base symbol table will have the type that the
851  * alias refers. Otherwise, we won't be able to find the type value
852  * for the alias. We can't depend on the declaration ordering because
853  * of the hash table.
854  */
alias_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)855 static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
856 			       void *data)
857 {
858 	char *id = key, *new_id = NULL, *target_id;
859 	type_datum_t *type, *base_type, *new_type = NULL, *target_type;
860 	link_state_t *state = (link_state_t *) data;
861 	policy_module_t *mod = state->cur;
862 	int primval;
863 
864 	type = (type_datum_t *) datum;
865 	/* there are 2 kinds of aliases. Ones with their own value (TYPE_ALIAS)
866 	 * and ones with the value of their primary (TYPE_TYPE && type->primary = 0)
867 	 */
868 	if (!
869 	    (type->flavor == TYPE_ALIAS
870 	     || (type->flavor == TYPE_TYPE && !type->primary))) {
871 		/* ignore types and attributes -- they were handled in
872 		 * type_copy_callback() */
873 		return 0;
874 	}
875 
876 	if (type->flavor == TYPE_ALIAS)
877 		primval = type->primary;
878 	else
879 		primval = type->s.value;
880 
881 	target_id = mod->policy->p_type_val_to_name[primval - 1];
882 	target_type = hashtab_search(state->base->p_types.table, target_id);
883 	if (target_type == NULL) {
884 		ERR(state->handle, "%s: Could not find type %s for alias %s.",
885 		    state->cur_mod_name, target_id, id);
886 		return -1;
887 	}
888 
889 	if (!strcmp(id, target_id)) {
890 		ERR(state->handle, "%s: Self aliasing of %s.",
891 		    state->cur_mod_name, id);
892 		return -1;
893 	}
894 
895 	target_type->flags |= type->flags;
896 
897 	base_type = hashtab_search(state->base->p_types.table, id);
898 	if (base_type == NULL) {
899 		if (state->verbose)
900 			INFO(state->handle, "copying alias %s", id);
901 
902 		if ((new_type =
903 		     (type_datum_t *) calloc(1, sizeof(*new_type))) == NULL) {
904 			goto cleanup;
905 		}
906 		/* the linked copy always has TYPE_ALIAS style aliases */
907 		new_type->primary = target_type->s.value;
908 		new_type->flags = target_type->flags;
909 		new_type->flavor = TYPE_ALIAS;
910 		new_type->s.value = state->base->p_types.nprim + 1;
911 		if ((new_id = strdup(id)) == NULL) {
912 			goto cleanup;
913 		}
914 		if (hashtab_insert
915 		    (state->base->p_types.table, new_id, new_type)) {
916 			goto cleanup;
917 		}
918 		state->base->p_types.nprim++;
919 		base_type = new_type;
920 	} else {
921 
922 		/* if this already exists and isn't an alias it was required by another module (or base)
923 		 * and inserted into the hashtable as a type, fix it up now */
924 
925 		if (base_type->flavor == TYPE_ALIAS) {
926 			/* error checking */
927 			assert(base_type->primary == target_type->s.value);
928 			assert(base_type->primary ==
929 			       mod->map[SYM_TYPES][primval - 1]);
930 			assert(mod->map[SYM_TYPES][type->s.value - 1] ==
931 			       base_type->primary);
932 			return 0;
933 		}
934 
935 		if (base_type->flavor == TYPE_ATTRIB) {
936 			ERR(state->handle,
937 			    "%s is an alias of an attribute, not allowed", id);
938 			return -1;
939 		}
940 
941 		base_type->flavor = TYPE_ALIAS;
942 		base_type->primary = target_type->s.value;
943 		base_type->flags |= target_type->flags;
944 
945 	}
946 	/* the aliases map points from its value to its primary so when this module
947 	 * references this type the value it gets back from the map is the primary */
948 	mod->map[SYM_TYPES][type->s.value - 1] = base_type->primary;
949 
950 	return 0;
951 
952       cleanup:
953 	ERR(state->handle, "Out of memory!");
954 	free(new_id);
955 	free(new_type);
956 	return -1;
957 }
958 
959 /*********** callbacks that fix bitmaps ***********/
960 
type_set_convert(type_set_t * types,type_set_t * dst,policy_module_t * mod,link_state_t * state)961 static int type_set_convert(type_set_t * types, type_set_t * dst,
962 			    policy_module_t * mod, link_state_t * state
963 			    __attribute__ ((unused)))
964 {
965 	unsigned int i;
966 	ebitmap_node_t *tnode;
967 	ebitmap_for_each_positive_bit(&types->types, tnode, i) {
968 		assert(mod->map[SYM_TYPES][i]);
969 		if (ebitmap_set_bit
970 		    (&dst->types, mod->map[SYM_TYPES][i] - 1, 1)) {
971 			goto cleanup;
972 		}
973 	}
974 	ebitmap_for_each_positive_bit(&types->negset, tnode, i) {
975 		assert(mod->map[SYM_TYPES][i]);
976 		if (ebitmap_set_bit
977 		    (&dst->negset, mod->map[SYM_TYPES][i] - 1, 1)) {
978 			goto cleanup;
979 		}
980 	}
981 	dst->flags = types->flags;
982 	return 0;
983 
984       cleanup:
985 	return -1;
986 }
987 
988 /* OR 2 typemaps together and at the same time map the src types to
989  * the correct values in the dst typeset.
990  */
type_set_or_convert(type_set_t * types,type_set_t * dst,policy_module_t * mod,link_state_t * state)991 static int type_set_or_convert(type_set_t * types, type_set_t * dst,
992 			       policy_module_t * mod, link_state_t * state)
993 {
994 	type_set_t ts_tmp;
995 
996 	type_set_init(&ts_tmp);
997 	if (type_set_convert(types, &ts_tmp, mod, state) == -1) {
998 		goto cleanup;
999 	}
1000 	if (type_set_or_eq(dst, &ts_tmp)) {
1001 		goto cleanup;
1002 	}
1003 	type_set_destroy(&ts_tmp);
1004 	return 0;
1005 
1006       cleanup:
1007 	ERR(state->handle, "Out of memory!");
1008 	type_set_destroy(&ts_tmp);
1009 	return -1;
1010 }
1011 
role_set_or_convert(role_set_t * roles,role_set_t * dst,policy_module_t * mod,link_state_t * state)1012 static int role_set_or_convert(role_set_t * roles, role_set_t * dst,
1013 			       policy_module_t * mod, link_state_t * state)
1014 {
1015 	unsigned int i;
1016 	ebitmap_t tmp;
1017 	ebitmap_node_t *rnode;
1018 
1019 	ebitmap_init(&tmp);
1020 	ebitmap_for_each_positive_bit(&roles->roles, rnode, i) {
1021 		assert(mod->map[SYM_ROLES][i]);
1022 		if (ebitmap_set_bit
1023 		    (&tmp, mod->map[SYM_ROLES][i] - 1, 1)) {
1024 			goto cleanup;
1025 		}
1026 	}
1027 	if (ebitmap_union(&dst->roles, &tmp)) {
1028 		goto cleanup;
1029 	}
1030 	dst->flags |= roles->flags;
1031 	ebitmap_destroy(&tmp);
1032 	return 0;
1033       cleanup:
1034 	ERR(state->handle, "Out of memory!");
1035 	ebitmap_destroy(&tmp);
1036 	return -1;
1037 }
1038 
mls_level_convert(mls_semantic_level_t * src,mls_semantic_level_t * dst,policy_module_t * mod,link_state_t * state)1039 static int mls_level_convert(mls_semantic_level_t * src, mls_semantic_level_t * dst,
1040 			     policy_module_t * mod, link_state_t * state)
1041 {
1042 	mls_semantic_cat_t *src_cat, *new_cat;
1043 
1044 	if (!mod->policy->mls)
1045 		return 0;
1046 
1047 	/* Required not declared. */
1048 	if (!src->sens)
1049 		return 0;
1050 
1051 	assert(mod->map[SYM_LEVELS][src->sens - 1]);
1052 	dst->sens = mod->map[SYM_LEVELS][src->sens - 1];
1053 
1054 	for (src_cat = src->cat; src_cat; src_cat = src_cat->next) {
1055 		new_cat =
1056 		    (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
1057 		if (!new_cat) {
1058 			ERR(state->handle, "Out of memory");
1059 			return -1;
1060 		}
1061 		mls_semantic_cat_init(new_cat);
1062 
1063 		new_cat->next = dst->cat;
1064 		dst->cat = new_cat;
1065 
1066 		assert(mod->map[SYM_CATS][src_cat->low - 1]);
1067 		dst->cat->low = mod->map[SYM_CATS][src_cat->low - 1];
1068 		assert(mod->map[SYM_CATS][src_cat->high - 1]);
1069 		dst->cat->high = mod->map[SYM_CATS][src_cat->high - 1];
1070 	}
1071 
1072 	return 0;
1073 }
1074 
mls_range_convert(mls_semantic_range_t * src,mls_semantic_range_t * dst,policy_module_t * mod,link_state_t * state)1075 static int mls_range_convert(mls_semantic_range_t * src, mls_semantic_range_t * dst,
1076 			     policy_module_t * mod, link_state_t * state)
1077 {
1078 	int ret;
1079 	ret = mls_level_convert(&src->level[0], &dst->level[0], mod, state);
1080 	if (ret)
1081 		return ret;
1082 	ret = mls_level_convert(&src->level[1], &dst->level[1], mod, state);
1083 	if (ret)
1084 		return ret;
1085 	return 0;
1086 }
1087 
role_fix_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)1088 static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
1089 			     void *data)
1090 {
1091 	unsigned int i;
1092 	char *id = key;
1093 	role_datum_t *role, *dest_role = NULL;
1094 	link_state_t *state = (link_state_t *) data;
1095 	ebitmap_t e_tmp;
1096 	policy_module_t *mod = state->cur;
1097 	ebitmap_node_t *rnode;
1098 	hashtab_t role_tab;
1099 
1100 	role = (role_datum_t *) datum;
1101 	if (state->dest_decl == NULL)
1102 		role_tab = state->base->p_roles.table;
1103 	else
1104 		role_tab = state->dest_decl->p_roles.table;
1105 
1106 	dest_role = hashtab_search(role_tab, id);
1107 	assert(dest_role != NULL);
1108 
1109 	if (state->verbose) {
1110 		INFO(state->handle, "fixing role %s", id);
1111 	}
1112 
1113 	ebitmap_init(&e_tmp);
1114 	ebitmap_for_each_positive_bit(&role->dominates, rnode, i) {
1115 		assert(mod->map[SYM_ROLES][i]);
1116 		if (ebitmap_set_bit
1117 		    (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) {
1118 			goto cleanup;
1119 		}
1120 	}
1121 	if (ebitmap_union(&dest_role->dominates, &e_tmp)) {
1122 		goto cleanup;
1123 	}
1124 	if (type_set_or_convert(&role->types, &dest_role->types, mod, state)) {
1125 		goto cleanup;
1126 	}
1127 	ebitmap_destroy(&e_tmp);
1128 
1129 	if (role->flavor == ROLE_ATTRIB) {
1130 		ebitmap_init(&e_tmp);
1131 		ebitmap_for_each_positive_bit(&role->roles, rnode, i) {
1132 			assert(mod->map[SYM_ROLES][i]);
1133 			if (ebitmap_set_bit
1134 			    (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) {
1135 				goto cleanup;
1136 			}
1137 		}
1138 		if (ebitmap_union(&dest_role->roles, &e_tmp)) {
1139 			goto cleanup;
1140 		}
1141 		ebitmap_destroy(&e_tmp);
1142 	}
1143 
1144 	return 0;
1145 
1146       cleanup:
1147 	ERR(state->handle, "Out of memory!");
1148 	ebitmap_destroy(&e_tmp);
1149 	return -1;
1150 }
1151 
type_fix_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)1152 static int type_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
1153 			     void *data)
1154 {
1155 	unsigned int i;
1156 	char *id = key;
1157 	type_datum_t *type, *new_type = NULL;
1158 	link_state_t *state = (link_state_t *) data;
1159 	ebitmap_t e_tmp;
1160 	policy_module_t *mod = state->cur;
1161 	ebitmap_node_t *tnode;
1162 	symtab_t *typetab;
1163 
1164 	type = (type_datum_t *) datum;
1165 
1166 	if (state->dest_decl == NULL)
1167 		typetab = &state->base->p_types;
1168 	else
1169 		typetab = &state->dest_decl->p_types;
1170 
1171 	/* only fix attributes */
1172 	if (type->flavor != TYPE_ATTRIB) {
1173 		return 0;
1174 	}
1175 
1176 	new_type = hashtab_search(typetab->table, id);
1177 	assert(new_type != NULL && new_type->flavor == TYPE_ATTRIB);
1178 
1179 	if (state->verbose) {
1180 		INFO(state->handle, "fixing attribute %s", id);
1181 	}
1182 
1183 	ebitmap_init(&e_tmp);
1184 	ebitmap_for_each_positive_bit(&type->types, tnode, i) {
1185 		assert(mod->map[SYM_TYPES][i]);
1186 		if (ebitmap_set_bit
1187 		    (&e_tmp, mod->map[SYM_TYPES][i] - 1, 1)) {
1188 			goto cleanup;
1189 		}
1190 	}
1191 	if (ebitmap_union(&new_type->types, &e_tmp)) {
1192 		goto cleanup;
1193 	}
1194 	ebitmap_destroy(&e_tmp);
1195 	return 0;
1196 
1197       cleanup:
1198 	ERR(state->handle, "Out of memory!");
1199 	ebitmap_destroy(&e_tmp);
1200 	return -1;
1201 }
1202 
user_fix_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)1203 static int user_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
1204 			     void *data)
1205 {
1206 	char *id = key;
1207 	user_datum_t *user, *new_user = NULL;
1208 	link_state_t *state = (link_state_t *) data;
1209 	policy_module_t *mod = state->cur;
1210 	symtab_t *usertab;
1211 
1212 	user = (user_datum_t *) datum;
1213 
1214 	if (state->dest_decl == NULL)
1215 		usertab = &state->base->p_users;
1216 	else
1217 		usertab = &state->dest_decl->p_users;
1218 
1219 	new_user = hashtab_search(usertab->table, id);
1220 	assert(new_user != NULL);
1221 
1222 	if (state->verbose) {
1223 		INFO(state->handle, "fixing user %s", id);
1224 	}
1225 
1226 	if (role_set_or_convert(&user->roles, &new_user->roles, mod, state)) {
1227 		goto cleanup;
1228 	}
1229 
1230 	if (mls_range_convert(&user->range, &new_user->range, mod, state))
1231 		goto cleanup;
1232 
1233 	if (mls_level_convert(&user->dfltlevel, &new_user->dfltlevel, mod, state))
1234 		goto cleanup;
1235 
1236 	return 0;
1237 
1238       cleanup:
1239 	ERR(state->handle, "Out of memory!");
1240 	return -1;
1241 }
1242 
1243 static int (*fix_callback_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
1244 				       void *datap) = {
1245 NULL, NULL, role_fix_callback, type_fix_callback, user_fix_callback,
1246 	    NULL, NULL, NULL};
1247 
1248 /*********** functions that copy AV rules ***********/
1249 
copy_avrule_list(avrule_t * list,avrule_t ** dst,policy_module_t * module,link_state_t * state)1250 static int copy_avrule_list(avrule_t * list, avrule_t ** dst,
1251 			    policy_module_t * module, link_state_t * state)
1252 {
1253 	unsigned int i;
1254 	avrule_t *cur, *new_rule = NULL, *tail;
1255 	class_perm_node_t *cur_perm, *new_perm, *tail_perm = NULL;
1256 
1257 	tail = *dst;
1258 	while (tail && tail->next) {
1259 		tail = tail->next;
1260 	}
1261 
1262 	cur = list;
1263 	while (cur) {
1264 		if ((new_rule = (avrule_t *) malloc(sizeof(avrule_t))) == NULL) {
1265 			goto cleanup;
1266 		}
1267 		avrule_init(new_rule);
1268 
1269 		new_rule->specified = cur->specified;
1270 		new_rule->flags = cur->flags;
1271 		if (type_set_convert
1272 		    (&cur->stypes, &new_rule->stypes, module, state) == -1
1273 		    || type_set_convert(&cur->ttypes, &new_rule->ttypes, module,
1274 					state) == -1) {
1275 			goto cleanup;
1276 		}
1277 
1278 		cur_perm = cur->perms;
1279 		tail_perm = NULL;
1280 		while (cur_perm) {
1281 			if ((new_perm = (class_perm_node_t *)
1282 			     malloc(sizeof(class_perm_node_t))) == NULL) {
1283 				goto cleanup;
1284 			}
1285 			class_perm_node_init(new_perm);
1286 
1287 			new_perm->tclass =
1288 			    module->map[SYM_CLASSES][cur_perm->tclass - 1];
1289 			assert(new_perm->tclass);
1290 
1291 			if (new_rule->specified & AVRULE_AV) {
1292 				for (i = 0;
1293 				     i <
1294 				     module->perm_map_len[cur_perm->tclass - 1];
1295 				     i++) {
1296 					if (!(cur_perm->data & (UINT32_C(1) << i)))
1297 						continue;
1298 					new_perm->data |=
1299 					    (UINT32_C(1) <<
1300 					     (module->
1301 					      perm_map[cur_perm->tclass - 1][i] -
1302 					      1));
1303 				}
1304 			} else {
1305 				new_perm->data =
1306 				    module->map[SYM_TYPES][cur_perm->data - 1];
1307 			}
1308 
1309 			if (new_rule->perms == NULL) {
1310 				new_rule->perms = new_perm;
1311 			} else {
1312 				assert(tail_perm);
1313 				tail_perm->next = new_perm;
1314 			}
1315 			tail_perm = new_perm;
1316 			cur_perm = cur_perm->next;
1317 		}
1318 
1319 		if (cur->xperms) {
1320 			new_rule->xperms = calloc(1, sizeof(*new_rule->xperms));
1321 			if (!new_rule->xperms)
1322 				goto cleanup;
1323 			memcpy(new_rule->xperms, cur->xperms,
1324 			       sizeof(*new_rule->xperms));
1325 		}
1326 
1327 		new_rule->line = cur->line;
1328 		new_rule->source_line = cur->source_line;
1329 		if (cur->source_filename) {
1330 			new_rule->source_filename = strdup(cur->source_filename);
1331 			if (!new_rule->source_filename)
1332 				goto cleanup;
1333 		}
1334 
1335 		cur = cur->next;
1336 
1337 		if (*dst == NULL) {
1338 			*dst = new_rule;
1339 		} else {
1340 			tail->next = new_rule;
1341 		}
1342 		tail = new_rule;
1343 	}
1344 
1345 	return 0;
1346       cleanup:
1347 	ERR(state->handle, "Out of memory!");
1348 	avrule_destroy(new_rule);
1349 	free(new_rule);
1350 	return -1;
1351 }
1352 
copy_role_trans_list(role_trans_rule_t * list,role_trans_rule_t ** dst,policy_module_t * module,link_state_t * state)1353 static int copy_role_trans_list(role_trans_rule_t * list,
1354 				role_trans_rule_t ** dst,
1355 				policy_module_t * module, link_state_t * state)
1356 {
1357 	role_trans_rule_t *cur, *new_rule = NULL, *tail;
1358 	unsigned int i;
1359 	ebitmap_node_t *cnode;
1360 
1361 	cur = list;
1362 	tail = *dst;
1363 	while (tail && tail->next) {
1364 		tail = tail->next;
1365 	}
1366 	while (cur) {
1367 		if ((new_rule =
1368 		     (role_trans_rule_t *) malloc(sizeof(role_trans_rule_t))) ==
1369 		    NULL) {
1370 			goto cleanup;
1371 		}
1372 		role_trans_rule_init(new_rule);
1373 
1374 		if (role_set_or_convert
1375 		    (&cur->roles, &new_rule->roles, module, state)
1376 		    || type_set_or_convert(&cur->types, &new_rule->types,
1377 					   module, state)) {
1378 			goto cleanup;
1379 		}
1380 
1381 		ebitmap_for_each_positive_bit(&cur->classes, cnode, i) {
1382 			assert(module->map[SYM_CLASSES][i]);
1383 			if (ebitmap_set_bit(&new_rule->classes,
1384 					    module->
1385 					    map[SYM_CLASSES][i] - 1,
1386 					    1)) {
1387 				goto cleanup;
1388 			}
1389 		}
1390 
1391 		new_rule->new_role = module->map[SYM_ROLES][cur->new_role - 1];
1392 
1393 		if (*dst == NULL) {
1394 			*dst = new_rule;
1395 		} else {
1396 			tail->next = new_rule;
1397 		}
1398 		tail = new_rule;
1399 		cur = cur->next;
1400 	}
1401 	return 0;
1402       cleanup:
1403 	ERR(state->handle, "Out of memory!");
1404 	role_trans_rule_list_destroy(new_rule);
1405 	return -1;
1406 }
1407 
copy_role_allow_list(role_allow_rule_t * list,role_allow_rule_t ** dst,policy_module_t * module,link_state_t * state)1408 static int copy_role_allow_list(role_allow_rule_t * list,
1409 				role_allow_rule_t ** dst,
1410 				policy_module_t * module, link_state_t * state)
1411 {
1412 	role_allow_rule_t *cur, *new_rule = NULL, *tail;
1413 
1414 	cur = list;
1415 	tail = *dst;
1416 	while (tail && tail->next) {
1417 		tail = tail->next;
1418 	}
1419 
1420 	while (cur) {
1421 		if ((new_rule =
1422 		     (role_allow_rule_t *) malloc(sizeof(role_allow_rule_t))) ==
1423 		    NULL) {
1424 			goto cleanup;
1425 		}
1426 		role_allow_rule_init(new_rule);
1427 
1428 		if (role_set_or_convert
1429 		    (&cur->roles, &new_rule->roles, module, state)
1430 		    || role_set_or_convert(&cur->new_roles,
1431 					   &new_rule->new_roles, module,
1432 					   state)) {
1433 			goto cleanup;
1434 		}
1435 		if (*dst == NULL) {
1436 			*dst = new_rule;
1437 		} else {
1438 			tail->next = new_rule;
1439 		}
1440 		tail = new_rule;
1441 		cur = cur->next;
1442 	}
1443 	return 0;
1444       cleanup:
1445 	ERR(state->handle, "Out of memory!");
1446 	role_allow_rule_list_destroy(new_rule);
1447 	return -1;
1448 }
1449 
copy_filename_trans_list(filename_trans_rule_t * list,filename_trans_rule_t ** dst,policy_module_t * module,link_state_t * state)1450 static int copy_filename_trans_list(filename_trans_rule_t * list,
1451 				    filename_trans_rule_t ** dst,
1452 				    policy_module_t * module,
1453 				    link_state_t * state)
1454 {
1455 	filename_trans_rule_t *cur, *new_rule, *tail;
1456 
1457 	cur = list;
1458 	tail = *dst;
1459 	while (tail && tail->next)
1460 		tail = tail->next;
1461 
1462 	while (cur) {
1463 		new_rule = malloc(sizeof(*new_rule));
1464 		if (!new_rule)
1465 			goto err;
1466 
1467 		filename_trans_rule_init(new_rule);
1468 
1469 		if (*dst == NULL)
1470 			*dst = new_rule;
1471 		else
1472 			tail->next = new_rule;
1473 		tail = new_rule;
1474 
1475 		new_rule->name = strdup(cur->name);
1476 		if (!new_rule->name)
1477 			goto err;
1478 
1479 		if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module, state) ||
1480 		    type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module, state))
1481 			goto err;
1482 
1483 		new_rule->tclass = module->map[SYM_CLASSES][cur->tclass - 1];
1484 		new_rule->otype = module->map[SYM_TYPES][cur->otype - 1];
1485 		new_rule->flags = cur->flags;
1486 
1487 		cur = cur->next;
1488 	}
1489 	return 0;
1490 err:
1491 	ERR(state->handle, "Out of memory!");
1492 	return -1;
1493 }
1494 
copy_range_trans_list(range_trans_rule_t * rules,range_trans_rule_t ** dst,policy_module_t * mod,link_state_t * state)1495 static int copy_range_trans_list(range_trans_rule_t * rules,
1496 				 range_trans_rule_t ** dst,
1497 				 policy_module_t * mod, link_state_t * state)
1498 {
1499 	range_trans_rule_t *rule, *new_rule = NULL;
1500 	unsigned int i;
1501 	ebitmap_node_t *cnode;
1502 
1503 	for (rule = rules; rule; rule = rule->next) {
1504 		new_rule =
1505 		    (range_trans_rule_t *) malloc(sizeof(range_trans_rule_t));
1506 		if (!new_rule)
1507 			goto cleanup;
1508 
1509 		range_trans_rule_init(new_rule);
1510 
1511 		new_rule->next = *dst;
1512 		*dst = new_rule;
1513 
1514 		if (type_set_convert(&rule->stypes, &new_rule->stypes,
1515 				     mod, state))
1516 			goto cleanup;
1517 
1518 		if (type_set_convert(&rule->ttypes, &new_rule->ttypes,
1519 				     mod, state))
1520 			goto cleanup;
1521 
1522 		ebitmap_for_each_positive_bit(&rule->tclasses, cnode, i) {
1523 			assert(mod->map[SYM_CLASSES][i]);
1524 			if (ebitmap_set_bit
1525 			    (&new_rule->tclasses,
1526 			     mod->map[SYM_CLASSES][i] - 1, 1)) {
1527 				goto cleanup;
1528 			}
1529 		}
1530 
1531 		if (mls_range_convert(&rule->trange, &new_rule->trange, mod, state))
1532 			goto cleanup;
1533 	}
1534 	return 0;
1535 
1536       cleanup:
1537 	ERR(state->handle, "Out of memory!");
1538 	range_trans_rule_list_destroy(new_rule);
1539 	return -1;
1540 }
1541 
copy_cond_list(cond_node_t * list,cond_node_t ** dst,policy_module_t * module,link_state_t * state)1542 static int copy_cond_list(cond_node_t * list, cond_node_t ** dst,
1543 			  policy_module_t * module, link_state_t * state)
1544 {
1545 	unsigned i;
1546 	cond_node_t *cur, *new_node = NULL, *tail;
1547 	cond_expr_t *cur_expr;
1548 	tail = *dst;
1549 	while (tail && tail->next)
1550 		tail = tail->next;
1551 
1552 	cur = list;
1553 	while (cur) {
1554 		new_node = (cond_node_t *) malloc(sizeof(cond_node_t));
1555 		if (!new_node) {
1556 			goto cleanup;
1557 		}
1558 		memset(new_node, 0, sizeof(cond_node_t));
1559 
1560 		new_node->cur_state = cur->cur_state;
1561 		new_node->expr = cond_copy_expr(cur->expr);
1562 		if (!new_node->expr)
1563 			goto cleanup;
1564 		/* go back through and remap the expression */
1565 		for (cur_expr = new_node->expr; cur_expr != NULL;
1566 		     cur_expr = cur_expr->next) {
1567 			/* expression nodes don't have a bool value of 0 - don't map them */
1568 			if (cur_expr->expr_type != COND_BOOL)
1569 				continue;
1570 			assert(module->map[SYM_BOOLS][cur_expr->bool - 1] != 0);
1571 			cur_expr->bool =
1572 			    module->map[SYM_BOOLS][cur_expr->bool - 1];
1573 		}
1574 		new_node->nbools = cur->nbools;
1575 		/* FIXME should COND_MAX_BOOLS be used here? */
1576 		for (i = 0; i < min(cur->nbools, COND_MAX_BOOLS); i++) {
1577 			uint32_t remapped_id =
1578 			    module->map[SYM_BOOLS][cur->bool_ids[i] - 1];
1579 			assert(remapped_id != 0);
1580 			new_node->bool_ids[i] = remapped_id;
1581 		}
1582 		new_node->expr_pre_comp = cur->expr_pre_comp;
1583 
1584 		if (copy_avrule_list
1585 		    (cur->avtrue_list, &new_node->avtrue_list, module, state)
1586 		    || copy_avrule_list(cur->avfalse_list,
1587 					&new_node->avfalse_list, module,
1588 					state)) {
1589 			goto cleanup;
1590 		}
1591 
1592 		if (*dst == NULL) {
1593 			*dst = new_node;
1594 		} else {
1595 			tail->next = new_node;
1596 		}
1597 		tail = new_node;
1598 		cur = cur->next;
1599 	}
1600 	return 0;
1601       cleanup:
1602 	ERR(state->handle, "Out of memory!");
1603 	cond_node_destroy(new_node);
1604 	free(new_node);
1605 	return -1;
1606 
1607 }
1608 
1609 /*********** functions that copy avrule_decls from module to base ***********/
1610 
copy_identifiers(link_state_t * state,symtab_t * src_symtab,avrule_decl_t * dest_decl)1611 static int copy_identifiers(link_state_t * state, symtab_t * src_symtab,
1612 			    avrule_decl_t * dest_decl)
1613 {
1614 	int i, ret;
1615 
1616 	state->dest_decl = dest_decl;
1617 	for (i = 0; i < SYM_NUM; i++) {
1618 		if (copy_callback_f[i] != NULL) {
1619 			ret =
1620 			    hashtab_map(src_symtab[i].table, copy_callback_f[i],
1621 					state);
1622 			if (ret) {
1623 				return ret;
1624 			}
1625 		}
1626 	}
1627 
1628 	if (hashtab_map(src_symtab[SYM_TYPES].table,
1629 			type_bounds_copy_callback, state))
1630 		return -1;
1631 
1632 	if (hashtab_map(src_symtab[SYM_TYPES].table,
1633 			alias_copy_callback, state))
1634 		return -1;
1635 
1636 	if (hashtab_map(src_symtab[SYM_ROLES].table,
1637 			role_bounds_copy_callback, state))
1638 		return -1;
1639 
1640 	if (hashtab_map(src_symtab[SYM_USERS].table,
1641 			user_bounds_copy_callback, state))
1642 		return -1;
1643 
1644 	/* then fix bitmaps associated with those newly copied identifiers */
1645 	for (i = 0; i < SYM_NUM; i++) {
1646 		if (fix_callback_f[i] != NULL &&
1647 		    hashtab_map(src_symtab[i].table, fix_callback_f[i],
1648 				state)) {
1649 			return -1;
1650 		}
1651 	}
1652 	return 0;
1653 }
1654 
copy_scope_index(scope_index_t * src,scope_index_t * dest,policy_module_t * module,link_state_t * state)1655 static int copy_scope_index(scope_index_t * src, scope_index_t * dest,
1656 			    policy_module_t * module, link_state_t * state)
1657 {
1658 	unsigned int i, j;
1659 	uint32_t largest_mapped_class_value = 0;
1660 	ebitmap_node_t *node;
1661 	/* copy the scoping information for this avrule decl block */
1662 	for (i = 0; i < SYM_NUM; i++) {
1663 		ebitmap_t *srcmap = src->scope + i;
1664 		ebitmap_t *destmap = dest->scope + i;
1665 		if (copy_callback_f[i] == NULL) {
1666 			continue;
1667 		}
1668 		ebitmap_for_each_positive_bit(srcmap, node, j) {
1669 			assert(module->map[i][j] != 0);
1670 			if (ebitmap_set_bit
1671 			    (destmap, module->map[i][j] - 1, 1) != 0) {
1672 
1673 				goto cleanup;
1674 			}
1675 			if (i == SYM_CLASSES &&
1676 			    largest_mapped_class_value <
1677 			    module->map[SYM_CLASSES][j]) {
1678 				largest_mapped_class_value =
1679 				    module->map[SYM_CLASSES][j];
1680 			}
1681 		}
1682 	}
1683 
1684 	/* next copy the enabled permissions data  */
1685 	if ((dest->class_perms_map = calloc(largest_mapped_class_value,
1686 					    sizeof(*dest->class_perms_map))) == NULL) {
1687 		goto cleanup;
1688 	}
1689 	dest->class_perms_len = largest_mapped_class_value;
1690 	for (i = 0; i < src->class_perms_len; i++) {
1691 		ebitmap_t *srcmap = src->class_perms_map + i;
1692 		ebitmap_t *destmap =
1693 		    dest->class_perms_map + module->map[SYM_CLASSES][i] - 1;
1694 		ebitmap_for_each_positive_bit(srcmap, node, j) {
1695 			if (ebitmap_set_bit(destmap, module->perm_map[i][j] - 1,
1696 					    1)) {
1697 				goto cleanup;
1698 			}
1699 		}
1700 	}
1701 
1702 	return 0;
1703 
1704       cleanup:
1705 	ERR(state->handle, "Out of memory!");
1706 	return -1;
1707 }
1708 
copy_avrule_decl(link_state_t * state,policy_module_t * module,avrule_decl_t * src_decl,avrule_decl_t * dest_decl)1709 static int copy_avrule_decl(link_state_t * state, policy_module_t * module,
1710 			    avrule_decl_t * src_decl, avrule_decl_t * dest_decl)
1711 {
1712 	int ret;
1713 
1714 	/* copy all of the RBAC and TE rules */
1715 	if (copy_avrule_list
1716 	    (src_decl->avrules, &dest_decl->avrules, module, state) == -1
1717 	    || copy_role_trans_list(src_decl->role_tr_rules,
1718 				    &dest_decl->role_tr_rules, module,
1719 				    state) == -1
1720 	    || copy_role_allow_list(src_decl->role_allow_rules,
1721 				    &dest_decl->role_allow_rules, module,
1722 				    state) == -1
1723 	    || copy_cond_list(src_decl->cond_list, &dest_decl->cond_list,
1724 			      module, state) == -1) {
1725 		return -1;
1726 	}
1727 
1728 	if (copy_filename_trans_list(src_decl->filename_trans_rules,
1729 				     &dest_decl->filename_trans_rules,
1730 				     module, state))
1731 		return -1;
1732 
1733 	if (copy_range_trans_list(src_decl->range_tr_rules,
1734 				  &dest_decl->range_tr_rules, module, state))
1735 		return -1;
1736 
1737 	/* finally copy any identifiers local to this declaration */
1738 	ret = copy_identifiers(state, src_decl->symtab, dest_decl);
1739 	if (ret < 0) {
1740 		return ret;
1741 	}
1742 
1743 	/* then copy required and declared scope indices here */
1744 	if (copy_scope_index(&src_decl->required, &dest_decl->required,
1745 			     module, state) == -1 ||
1746 	    copy_scope_index(&src_decl->declared, &dest_decl->declared,
1747 			     module, state) == -1) {
1748 		return -1;
1749 	}
1750 
1751 	return 0;
1752 }
1753 
copy_avrule_block(link_state_t * state,policy_module_t * module,avrule_block_t * block)1754 static int copy_avrule_block(link_state_t * state, policy_module_t * module,
1755 			     avrule_block_t * block)
1756 {
1757 	avrule_block_t *new_block = avrule_block_create();
1758 	avrule_decl_t *decl, *last_decl = NULL;
1759 	int ret;
1760 
1761 	if (new_block == NULL) {
1762 		ERR(state->handle, "Out of memory!");
1763 		ret = -1;
1764 		goto cleanup;
1765 	}
1766 
1767 	new_block->flags = block->flags;
1768 
1769 	for (decl = block->branch_list; decl != NULL; decl = decl->next) {
1770 		avrule_decl_t *new_decl =
1771 		    avrule_decl_create(state->next_decl_id);
1772 		if (new_decl == NULL) {
1773 			ERR(state->handle, "Out of memory!");
1774 			ret = -1;
1775 			goto cleanup;
1776 		}
1777 
1778 		if (module->policy->name != NULL) {
1779 			new_decl->module_name = strdup(module->policy->name);
1780 			if (new_decl->module_name == NULL) {
1781 				ERR(state->handle, "Out of memory");
1782 				avrule_decl_destroy(new_decl);
1783 				ret = -1;
1784 				goto cleanup;
1785 			}
1786 		}
1787 
1788 		if (last_decl == NULL) {
1789 			new_block->branch_list = new_decl;
1790 		} else {
1791 			last_decl->next = new_decl;
1792 		}
1793 		last_decl = new_decl;
1794 		state->base->decl_val_to_struct[state->next_decl_id - 1] =
1795 		    new_decl;
1796 		state->decl_to_mod[state->next_decl_id] = module->policy;
1797 
1798 		module->avdecl_map[decl->decl_id] = new_decl->decl_id;
1799 
1800 		ret = copy_avrule_decl(state, module, decl, new_decl);
1801 		if (ret) {
1802 			avrule_decl_destroy(new_decl);
1803 			goto cleanup;
1804 		}
1805 
1806 		state->next_decl_id++;
1807 	}
1808 	state->last_avrule_block->next = new_block;
1809 	state->last_avrule_block = new_block;
1810 	return 0;
1811 
1812       cleanup:
1813 	avrule_block_list_destroy(new_block);
1814 	return ret;
1815 }
1816 
scope_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)1817 static int scope_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
1818 			       void *data)
1819 {
1820 	unsigned int i;
1821 	int ret;
1822 	char *id = key, *new_id = NULL;
1823 	scope_datum_t *scope, *base_scope;
1824 	link_state_t *state = (link_state_t *) data;
1825 	uint32_t symbol_num = state->symbol_num;
1826 	uint32_t *avdecl_map = state->cur->avdecl_map;
1827 
1828 	scope = (scope_datum_t *) datum;
1829 
1830 	/* check if the base already has a scope entry */
1831 	base_scope = hashtab_search(state->base->scope[symbol_num].table, id);
1832 	if (base_scope == NULL) {
1833 		scope_datum_t *new_scope;
1834 		if ((new_id = strdup(id)) == NULL) {
1835 			goto cleanup;
1836 		}
1837 
1838 		if ((new_scope =
1839 		     (scope_datum_t *) calloc(1, sizeof(*new_scope))) == NULL) {
1840 			free(new_id);
1841 			goto cleanup;
1842 		}
1843 		ret = hashtab_insert(state->base->scope[symbol_num].table,
1844 				     (hashtab_key_t) new_id,
1845 				     (hashtab_datum_t) new_scope);
1846 		if (ret) {
1847 			free(new_id);
1848 			free(new_scope);
1849 			goto cleanup;
1850 		}
1851 		new_scope->scope = SCOPE_REQ;	/* this is reset further down */
1852 		base_scope = new_scope;
1853 	}
1854 	if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_DECL) {
1855 		/* this module declared symbol, so overwrite the old
1856 		 * list with the new decl ids */
1857 		base_scope->scope = SCOPE_DECL;
1858 		free(base_scope->decl_ids);
1859 		base_scope->decl_ids = NULL;
1860 		base_scope->decl_ids_len = 0;
1861 		for (i = 0; i < scope->decl_ids_len; i++) {
1862 			if (add_i_to_a(avdecl_map[scope->decl_ids[i]],
1863 				       &base_scope->decl_ids_len,
1864 				       &base_scope->decl_ids) == -1) {
1865 				goto cleanup;
1866 			}
1867 		}
1868 	} else if (base_scope->scope == SCOPE_DECL && scope->scope == SCOPE_REQ) {
1869 		/* this module depended on a symbol that now exists,
1870 		 * so don't do anything */
1871 	} else if (base_scope->scope == SCOPE_REQ && scope->scope == SCOPE_REQ) {
1872 		/* symbol is still required, so add to the list */
1873 		for (i = 0; i < scope->decl_ids_len; i++) {
1874 			if (add_i_to_a(avdecl_map[scope->decl_ids[i]],
1875 				       &base_scope->decl_ids_len,
1876 				       &base_scope->decl_ids) == -1) {
1877 				goto cleanup;
1878 			}
1879 		}
1880 	} else {
1881 		/* this module declared a symbol, and it was already
1882 		 * declared.  only roles and users may be multiply
1883 		 * declared; for all others this is an error. */
1884 		if (symbol_num != SYM_ROLES && symbol_num != SYM_USERS) {
1885 			ERR(state->handle,
1886 			    "%s: Duplicate declaration in module: %s %s",
1887 			    state->cur_mod_name,
1888 			    symtab_names[state->symbol_num], id);
1889 			return -1;
1890 		}
1891 		for (i = 0; i < scope->decl_ids_len; i++) {
1892 			if (add_i_to_a(avdecl_map[scope->decl_ids[i]],
1893 				       &base_scope->decl_ids_len,
1894 				       &base_scope->decl_ids) == -1) {
1895 				goto cleanup;
1896 			}
1897 		}
1898 	}
1899 	return 0;
1900 
1901       cleanup:
1902 	ERR(state->handle, "Out of memory!");
1903 	return -1;
1904 }
1905 
1906 /* Copy a module over to a base, remapping all values within.  After
1907  * all identifiers and rules are done, copy the scoping information.
1908  * This is when it checks for duplicate declarations. */
copy_module(link_state_t * state,policy_module_t * module)1909 static int copy_module(link_state_t * state, policy_module_t * module)
1910 {
1911 	int i, ret;
1912 	avrule_block_t *cur;
1913 	state->cur = module;
1914 	state->cur_mod_name = module->policy->name;
1915 
1916 	/* first copy all of the identifiers */
1917 	ret = copy_identifiers(state, module->policy->symtab, NULL);
1918 	if (ret) {
1919 		return ret;
1920 	}
1921 
1922 	/* next copy all of the avrule blocks */
1923 	for (cur = module->policy->global; cur != NULL; cur = cur->next) {
1924 		ret = copy_avrule_block(state, module, cur);
1925 		if (ret) {
1926 			return ret;
1927 		}
1928 	}
1929 
1930 	/* then copy the scoping tables */
1931 	for (i = 0; i < SYM_NUM; i++) {
1932 		state->symbol_num = i;
1933 		if (hashtab_map
1934 		    (module->policy->scope[i].table, scope_copy_callback,
1935 		     state)) {
1936 			return -1;
1937 		}
1938 	}
1939 
1940 	return 0;
1941 }
1942 
1943 /***** functions that check requirements and enable blocks in a module ******/
1944 
1945 /* borrowed from checkpolicy.c */
1946 
1947 struct find_perm_arg {
1948 	unsigned int valuep;
1949 	hashtab_key_t key;
1950 };
1951 
find_perm(hashtab_key_t key,hashtab_datum_t datum,void * varg)1952 static int find_perm(hashtab_key_t key, hashtab_datum_t datum, void *varg)
1953 {
1954 
1955 	struct find_perm_arg *arg = varg;
1956 
1957 	perm_datum_t *perdatum = (perm_datum_t *) datum;
1958 	if (arg->valuep == perdatum->s.value) {
1959 		arg->key = key;
1960 		return 1;
1961 	}
1962 
1963 	return 0;
1964 }
1965 
1966 /* Check if the requirements are met for a single declaration.  If all
1967  * are met return 1.  For the first requirement found to be missing,
1968  * if 'missing_sym_num' and 'missing_value' are both not NULL then
1969  * write to them the symbol number and value for the missing
1970  * declaration.  Then return 0 to indicate a missing declaration.
1971  * Note that if a declaration had no requirement at all (e.g., an ELSE
1972  * block) this returns 1. */
is_decl_requires_met(link_state_t * state,avrule_decl_t * decl,struct missing_requirement * req)1973 static int is_decl_requires_met(link_state_t * state,
1974 				avrule_decl_t * decl,
1975 				struct missing_requirement *req)
1976 {
1977 	/* (This algorithm is very unoptimized.  It performs many
1978 	 * redundant checks.  A very obvious improvement is to cache
1979 	 * which symbols have been verified, so that they do not need
1980 	 * to be re-checked.) */
1981 	unsigned int i, j;
1982 	ebitmap_t *bitmap;
1983 	char *id, *perm_id;
1984 	policydb_t *pol = state->base;
1985 	ebitmap_node_t *node;
1986 
1987 	/* check that all symbols have been satisfied */
1988 	for (i = 0; i < SYM_NUM; i++) {
1989 		if (i == SYM_CLASSES) {
1990 			/* classes will be checked during permissions
1991 			 * checking phase below */
1992 			continue;
1993 		}
1994 		bitmap = &decl->required.scope[i];
1995 		ebitmap_for_each_positive_bit(bitmap, node, j) {
1996 			/* check base's scope table */
1997 			id = pol->sym_val_to_name[i][j];
1998 			if (!is_id_enabled(id, state->base, i)) {
1999 				/* this symbol was not found */
2000 				if (req != NULL) {
2001 					req->symbol_type = i;
2002 					req->symbol_value = j + 1;
2003 				}
2004 				return 0;
2005 			}
2006 		}
2007 	}
2008 	/* check that all classes and permissions have been satisfied */
2009 	for (i = 0; i < decl->required.class_perms_len; i++) {
2010 
2011 		bitmap = decl->required.class_perms_map + i;
2012 		ebitmap_for_each_positive_bit(bitmap, node, j) {
2013 			struct find_perm_arg fparg;
2014 			class_datum_t *cladatum;
2015 			uint32_t perm_value = j + 1;
2016 			int rc;
2017 			scope_datum_t *scope;
2018 
2019 			id = pol->p_class_val_to_name[i];
2020 			cladatum = pol->class_val_to_struct[i];
2021 
2022 			scope =
2023 			    hashtab_search(state->base->p_classes_scope.table,
2024 					   id);
2025 			if (scope == NULL) {
2026 				ERR(state->handle,
2027 				    "Could not find scope information for class %s",
2028 				    id);
2029 				return -1;
2030 			}
2031 
2032 			fparg.valuep = perm_value;
2033 			fparg.key = NULL;
2034 
2035 			(void)hashtab_map(cladatum->permissions.table, find_perm,
2036 				    &fparg);
2037 			if (fparg.key == NULL && cladatum->comdatum != NULL) {
2038 				rc = hashtab_map(cladatum->comdatum->permissions.table,
2039 						 find_perm, &fparg);
2040 				assert(rc == 1);
2041 			}
2042 			perm_id = fparg.key;
2043 
2044 			assert(perm_id != NULL);
2045 			if (!is_perm_enabled(id, perm_id, state->base)) {
2046 				if (req != NULL) {
2047 					req->symbol_type = SYM_CLASSES;
2048 					req->symbol_value = i + 1;
2049 					req->perm_value = perm_value;
2050 				}
2051 				return 0;
2052 			}
2053 		}
2054 	}
2055 
2056 	/* all requirements have been met */
2057 	return 1;
2058 }
2059 
debug_requirements(link_state_t * state,policydb_t * p)2060 static int debug_requirements(link_state_t * state, policydb_t * p)
2061 {
2062 	int ret;
2063 	avrule_block_t *cur;
2064 	missing_requirement_t req;
2065 	memset(&req, 0, sizeof(req));
2066 
2067 	for (cur = p->global; cur != NULL; cur = cur->next) {
2068 		if (cur->enabled != NULL)
2069 			continue;
2070 
2071 		ret = is_decl_requires_met(state, cur->branch_list, &req);
2072 		if (ret < 0) {
2073 			return ret;
2074 		} else if (ret == 0) {
2075 			const char *mod_name = cur->branch_list->module_name ?
2076 			    cur->branch_list->module_name : "BASE";
2077 			if (req.symbol_type == SYM_CLASSES) {
2078 				struct find_perm_arg fparg;
2079 
2080 				class_datum_t *cladatum;
2081 				cladatum = p->class_val_to_struct[req.symbol_value - 1];
2082 
2083 				fparg.valuep = req.perm_value;
2084 				fparg.key = NULL;
2085 				(void)hashtab_map(cladatum->permissions.table,
2086 						  find_perm, &fparg);
2087 
2088 				if (cur->flags & AVRULE_OPTIONAL) {
2089 					ERR(state->handle,
2090 					    "%s[%d]'s optional requirements were not met: class %s, permission %s",
2091 					    mod_name, cur->branch_list->decl_id,
2092 					    p->p_class_val_to_name[req.symbol_value - 1],
2093 					    fparg.key);
2094 				} else {
2095 					ERR(state->handle,
2096 					    "%s[%d]'s global requirements were not met: class %s, permission %s",
2097 					    mod_name, cur->branch_list->decl_id,
2098 					    p->p_class_val_to_name[req.symbol_value - 1],
2099 					    fparg.key);
2100 				}
2101 			} else {
2102 				if (cur->flags & AVRULE_OPTIONAL) {
2103 					ERR(state->handle,
2104 					    "%s[%d]'s optional requirements were not met: %s %s",
2105 					    mod_name, cur->branch_list->decl_id,
2106 					    symtab_names[req.symbol_type],
2107 					    p->sym_val_to_name[req.
2108 							       symbol_type][req.
2109 									    symbol_value
2110 									    -
2111 									    1]);
2112 				} else {
2113 					ERR(state->handle,
2114 					    "%s[%d]'s global requirements were not met: %s %s",
2115 					    mod_name, cur->branch_list->decl_id,
2116 					    symtab_names[req.symbol_type],
2117 					    p->sym_val_to_name[req.
2118 							       symbol_type][req.
2119 									    symbol_value
2120 									    -
2121 									    1]);
2122 				}
2123 			}
2124 		}
2125 	}
2126 	return 0;
2127 }
2128 
print_missing_requirements(link_state_t * state,avrule_block_t * cur,missing_requirement_t * req)2129 static void print_missing_requirements(link_state_t * state,
2130 				       avrule_block_t * cur,
2131 				       missing_requirement_t * req)
2132 {
2133 	policydb_t *p = state->base;
2134 	const char *mod_name = cur->branch_list->module_name ?
2135 	    cur->branch_list->module_name : "BASE";
2136 
2137 	if (req->symbol_type == SYM_CLASSES) {
2138 
2139 		struct find_perm_arg fparg;
2140 
2141 		class_datum_t *cladatum;
2142 		cladatum = p->class_val_to_struct[req->symbol_value - 1];
2143 
2144 		fparg.valuep = req->perm_value;
2145 		fparg.key = NULL;
2146 		(void)hashtab_map(cladatum->permissions.table, find_perm, &fparg);
2147 
2148 		ERR(state->handle,
2149 		    "%s's global requirements were not met: class %s, permission %s",
2150 		    mod_name,
2151 		    p->p_class_val_to_name[req->symbol_value - 1], fparg.key);
2152 	} else {
2153 		ERR(state->handle,
2154 		    "%s's global requirements were not met: %s %s",
2155 		    mod_name,
2156 		    symtab_names[req->symbol_type],
2157 		    p->sym_val_to_name[req->symbol_type][req->symbol_value - 1]);
2158 	}
2159 }
2160 
2161 /* Enable all of the avrule_decl blocks for the policy. This simple
2162  * algorithm is the following:
2163  *
2164  * 1) Enable all of the non-else avrule_decls for all blocks.
2165  * 2) Iterate through the non-else decls looking for decls whose requirements
2166  *    are not met.
2167  *    2a) If the decl is non-optional, return immediately with an error.
2168  *    2b) If the decl is optional, disable the block and mark changed = 1
2169  * 3) If changed == 1 goto 2.
2170  * 4) Iterate through all blocks looking for those that have no enabled
2171  *    decl. If the block has an else decl, enable.
2172  *
2173  * This will correctly handle all dependencies, including mutual and
2174  * circular. The only downside is that it is slow.
2175  */
enable_avrules(link_state_t * state,policydb_t * pol)2176 static int enable_avrules(link_state_t * state, policydb_t * pol)
2177 {
2178 	int changed = 1;
2179 	avrule_block_t *block;
2180 	avrule_decl_t *decl;
2181 	missing_requirement_t req;
2182 	int ret = 0, rc;
2183 
2184 	if (state->verbose) {
2185 		INFO(state->handle, "Determining which avrules to enable.");
2186 	}
2187 
2188 	/* 1) enable all of the non-else blocks */
2189 	for (block = pol->global; block != NULL; block = block->next) {
2190 		block->enabled = block->branch_list;
2191 		block->enabled->enabled = 1;
2192 		for (decl = block->branch_list->next; decl != NULL;
2193 		     decl = decl->next)
2194 			decl->enabled = 0;
2195 	}
2196 
2197 	/* 2) Iterate */
2198 	while (changed) {
2199 		changed = 0;
2200 		for (block = pol->global; block != NULL; block = block->next) {
2201 			if (block->enabled == NULL) {
2202 				continue;
2203 			}
2204 			decl = block->branch_list;
2205 			if (state->verbose) {
2206 				const char *mod_name = decl->module_name ?
2207 				    decl->module_name : "BASE";
2208 				INFO(state->handle, "check module %s decl %d",
2209 				     mod_name, decl->decl_id);
2210 			}
2211 			rc = is_decl_requires_met(state, decl, &req);
2212 			if (rc < 0) {
2213 				ret = SEPOL_ERR;
2214 				goto out;
2215 			} else if (rc == 0) {
2216 				decl->enabled = 0;
2217 				block->enabled = NULL;
2218 				changed = 1;
2219 				if (!(block->flags & AVRULE_OPTIONAL)) {
2220 					print_missing_requirements(state, block,
2221 								   &req);
2222 					ret = SEPOL_EREQ;
2223 					goto out;
2224 				}
2225 			}
2226 		}
2227 	}
2228 
2229 	/* 4) else handling
2230 	 *
2231 	 * Iterate through all of the blocks skipping the first (which is the
2232 	 * global block, is required to be present, and cannot have an else).
2233 	 * If the block is disabled and has an else decl, enable that.
2234 	 *
2235 	 * This code assumes that the second block in the branch list is the else
2236 	 * block. This is currently supported by the compiler.
2237 	 */
2238 	for (block = pol->global->next; block != NULL; block = block->next) {
2239 		if (block->enabled == NULL) {
2240 			if (block->branch_list->next != NULL) {
2241 				block->enabled = block->branch_list->next;
2242 				block->branch_list->next->enabled = 1;
2243 			}
2244 		}
2245 	}
2246 
2247       out:
2248 	if (state->verbose)
2249 		debug_requirements(state, pol);
2250 
2251 	return ret;
2252 }
2253 
2254 /*********** the main linking functions ***********/
2255 
2256 /* Given a module's policy, normalize all conditional expressions
2257  * within.  Return 0 on success, -1 on error. */
cond_normalize(policydb_t * p)2258 static int cond_normalize(policydb_t * p)
2259 {
2260 	avrule_block_t *block;
2261 	for (block = p->global; block != NULL; block = block->next) {
2262 		avrule_decl_t *decl;
2263 		for (decl = block->branch_list; decl != NULL; decl = decl->next) {
2264 			cond_list_t *cond = decl->cond_list;
2265 			while (cond) {
2266 				if (cond_normalize_expr(p, cond) < 0)
2267 					return -1;
2268 				cond = cond->next;
2269 			}
2270 		}
2271 	}
2272 	return 0;
2273 }
2274 
2275 /* Allocate space for the various remapping arrays. */
prepare_module(link_state_t * state,policy_module_t * module)2276 static int prepare_module(link_state_t * state, policy_module_t * module)
2277 {
2278 	int i;
2279 	uint32_t items, num_decls = 0;
2280 	avrule_block_t *cur;
2281 
2282 	/* allocate the maps */
2283 	for (i = 0; i < SYM_NUM; i++) {
2284 		items = module->policy->symtab[i].nprim;
2285 		if ((module->map[i] =
2286 		     (uint32_t *) calloc(items,
2287 					 sizeof(*module->map[i]))) == NULL) {
2288 			ERR(state->handle, "Out of memory!");
2289 			return -1;
2290 		}
2291 	}
2292 
2293 	/* allocate the permissions remap here */
2294 	items = module->policy->p_classes.nprim;
2295 	if ((module->perm_map_len =
2296 	     calloc(items, sizeof(*module->perm_map_len))) == NULL) {
2297 		ERR(state->handle, "Out of memory!");
2298 		return -1;
2299 	}
2300 	if ((module->perm_map =
2301 	     calloc(items, sizeof(*module->perm_map))) == NULL) {
2302 		ERR(state->handle, "Out of memory!");
2303 		return -1;
2304 	}
2305 
2306 	/* allocate a map for avrule_decls */
2307 	for (cur = module->policy->global; cur != NULL; cur = cur->next) {
2308 		avrule_decl_t *decl;
2309 		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
2310 			if (decl->decl_id > num_decls) {
2311 				num_decls = decl->decl_id;
2312 			}
2313 		}
2314 	}
2315 	num_decls++;
2316 	if ((module->avdecl_map = calloc(num_decls, sizeof(uint32_t))) == NULL) {
2317 		ERR(state->handle, "Out of memory!");
2318 		return -1;
2319 	}
2320 	module->num_decls = num_decls;
2321 
2322 	/* normalize conditionals within */
2323 	if (cond_normalize(module->policy) < 0) {
2324 		ERR(state->handle,
2325 		    "Error while normalizing conditionals within the module %s.",
2326 		    module->policy->name);
2327 		return -1;
2328 	}
2329 	return 0;
2330 }
2331 
prepare_base(link_state_t * state,uint32_t num_mod_decls)2332 static int prepare_base(link_state_t * state, uint32_t num_mod_decls)
2333 {
2334 	avrule_block_t *cur = state->base->global;
2335 	assert(cur != NULL);
2336 	state->next_decl_id = 0;
2337 
2338 	/* iterate through all of the declarations in the base, to
2339 	   determine what the next decl_id should be */
2340 	while (cur != NULL) {
2341 		avrule_decl_t *decl;
2342 		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
2343 			if (decl->decl_id > state->next_decl_id) {
2344 				state->next_decl_id = decl->decl_id;
2345 			}
2346 		}
2347 		state->last_avrule_block = cur;
2348 		cur = cur->next;
2349 	}
2350 	state->last_base_avrule_block = state->last_avrule_block;
2351 	state->next_decl_id++;
2352 
2353 	/* allocate the table mapping from base's decl_id to its
2354 	 * avrule_decls and set the initial mappings */
2355 	free(state->base->decl_val_to_struct);
2356 	if ((state->base->decl_val_to_struct =
2357 	     calloc(state->next_decl_id + num_mod_decls,
2358 		    sizeof(*(state->base->decl_val_to_struct)))) == NULL) {
2359 		ERR(state->handle, "Out of memory!");
2360 		return -1;
2361 	}
2362 	/* This allocates the decl block to module mapping used for error reporting */
2363 	if ((state->decl_to_mod = calloc(state->next_decl_id + num_mod_decls,
2364 					 sizeof(*(state->decl_to_mod)))) ==
2365 	    NULL) {
2366 		ERR(state->handle, "Out of memory!");
2367 		return -1;
2368 	}
2369 	cur = state->base->global;
2370 	while (cur != NULL) {
2371 		avrule_decl_t *decl = cur->branch_list;
2372 		while (decl != NULL) {
2373 			state->base->decl_val_to_struct[decl->decl_id - 1] =
2374 			    decl;
2375 			state->decl_to_mod[decl->decl_id] = state->base;
2376 			decl = decl->next;
2377 		}
2378 		cur = cur->next;
2379 	}
2380 
2381 	/* normalize conditionals within */
2382 	if (cond_normalize(state->base) < 0) {
2383 		ERR(state->handle,
2384 		    "Error while normalizing conditionals within the base module.");
2385 		return -1;
2386 	}
2387 	return 0;
2388 }
2389 
expand_role_attributes(hashtab_key_t key,hashtab_datum_t datum,void * data)2390 static int expand_role_attributes(hashtab_key_t key, hashtab_datum_t datum,
2391 				  void * data)
2392 {
2393 	char *id;
2394 	role_datum_t *role, *sub_attr;
2395 	link_state_t *state;
2396 	unsigned int i;
2397 	ebitmap_node_t *rnode;
2398 
2399 	id = key;
2400 	role = (role_datum_t *)datum;
2401 	state = (link_state_t *)data;
2402 
2403 	if (strcmp(id, OBJECT_R) == 0){
2404 		/* object_r is never a role attribute by far */
2405 		return 0;
2406 	}
2407 
2408 	if (role->flavor != ROLE_ATTRIB)
2409 		return 0;
2410 
2411 	if (state->verbose)
2412 		INFO(state->handle, "expanding role attribute %s", id);
2413 
2414 restart:
2415 	ebitmap_for_each_positive_bit(&role->roles, rnode, i) {
2416 		sub_attr = state->base->role_val_to_struct[i];
2417 		if (sub_attr->flavor != ROLE_ATTRIB)
2418 			continue;
2419 
2420 		/* remove the sub role attribute from the parent
2421 		 * role attribute's roles ebitmap */
2422 		if (ebitmap_set_bit(&role->roles, i, 0))
2423 			return -1;
2424 
2425 		/* loop dependency of role attributes */
2426 		if (sub_attr->s.value == role->s.value)
2427 			continue;
2428 
2429 		/* now go on to expand a sub role attribute
2430 		 * by escalating its roles ebitmap */
2431 		if (ebitmap_union(&role->roles, &sub_attr->roles)) {
2432 			ERR(state->handle, "Out of memory!");
2433 			return -1;
2434 		}
2435 
2436 		/* sub_attr->roles may contain other role attributes,
2437 		 * re-scan the parent role attribute's roles ebitmap */
2438 		goto restart;
2439 	}
2440 
2441 	return 0;
2442 }
2443 
2444 /* For any role attribute in a declaration's local symtab[SYM_ROLES] table,
2445  * copy its roles ebitmap into its duplicate's in the base->p_roles.table.
2446  */
populate_decl_roleattributes(hashtab_key_t key,hashtab_datum_t datum,void * data)2447 static int populate_decl_roleattributes(hashtab_key_t key,
2448 					hashtab_datum_t datum,
2449 					void *data)
2450 {
2451 	char *id = key;
2452 	role_datum_t *decl_role, *base_role;
2453 	link_state_t *state = (link_state_t *)data;
2454 
2455 	decl_role = (role_datum_t *)datum;
2456 
2457 	if (strcmp(id, OBJECT_R) == 0) {
2458 		/* object_r is never a role attribute by far */
2459 		return 0;
2460 	}
2461 
2462 	if (decl_role->flavor != ROLE_ATTRIB)
2463 		return 0;
2464 
2465 	base_role = (role_datum_t *)hashtab_search(state->base->p_roles.table,
2466 						   id);
2467 	assert(base_role != NULL && base_role->flavor == ROLE_ATTRIB);
2468 
2469 	if (ebitmap_union(&base_role->roles, &decl_role->roles)) {
2470 		ERR(state->handle, "Out of memory!");
2471 		return -1;
2472 	}
2473 
2474 	return 0;
2475 }
2476 
populate_roleattributes(link_state_t * state,policydb_t * pol)2477 static int populate_roleattributes(link_state_t *state, policydb_t *pol)
2478 {
2479 	avrule_block_t *block;
2480 	avrule_decl_t *decl;
2481 
2482 	if (state->verbose)
2483 		INFO(state->handle, "Populating role-attribute relationship "
2484 			    "from enabled declarations' local symtab.");
2485 
2486 	/* Iterate through all of the blocks skipping the first(which is the
2487 	 * global block, is required to be present and can't have an else).
2488 	 * If the block is disabled or not having an enabled decl, skip it.
2489 	 */
2490 	for (block = pol->global->next; block != NULL; block = block->next)
2491 	{
2492 		decl = block->enabled;
2493 		if (decl == NULL || decl->enabled == 0)
2494 			continue;
2495 
2496 		if (hashtab_map(decl->symtab[SYM_ROLES].table,
2497 				populate_decl_roleattributes, state))
2498 			return -1;
2499 	}
2500 
2501 	return 0;
2502 }
2503 
2504 /* Link a set of modules into a base module. This process is somewhat
2505  * similar to an actual compiler: it requires a set of order dependent
2506  * steps.  The base and every module must have been indexed prior to
2507  * calling this function.
2508  */
link_modules(sepol_handle_t * handle,policydb_t * b,policydb_t ** mods,int len,int verbose)2509 int link_modules(sepol_handle_t * handle,
2510 		 policydb_t * b, policydb_t ** mods, int len, int verbose)
2511 {
2512 	int i, ret, retval = -1;
2513 	policy_module_t **modules = NULL;
2514 	link_state_t state;
2515 	uint32_t num_mod_decls = 0;
2516 
2517 	memset(&state, 0, sizeof(state));
2518 	state.base = b;
2519 	state.verbose = verbose;
2520 	state.handle = handle;
2521 
2522 	if (b->policy_type != POLICY_BASE) {
2523 		ERR(state.handle, "Target of link was not a base policy.");
2524 		return -1;
2525 	}
2526 
2527 	/* first allocate some space to hold the maps from module
2528 	 * symbol's value to the destination symbol value; then do
2529 	 * other preparation work */
2530 	if ((modules =
2531 	     (policy_module_t **) calloc(len, sizeof(*modules))) == NULL) {
2532 		ERR(state.handle, "Out of memory!");
2533 		return -1;
2534 	}
2535 	for (i = 0; i < len; i++) {
2536 		if (mods[i]->policy_type != POLICY_MOD) {
2537 			ERR(state.handle,
2538 			    "Tried to link in a policy that was not a module.");
2539 			goto cleanup;
2540 		}
2541 
2542 		if (mods[i]->mls != b->mls) {
2543 			if (b->mls)
2544 				ERR(state.handle,
2545 				    "Tried to link in a non-MLS module with an MLS base.");
2546 			else
2547 				ERR(state.handle,
2548 				    "Tried to link in an MLS module with a non-MLS base.");
2549 			goto cleanup;
2550 		}
2551 
2552 		if (mods[i]->policyvers > b->policyvers) {
2553 			WARN(state.handle,
2554 			     "Upgrading policy version from %u to %u", b->policyvers, mods[i]->policyvers);
2555 			b->policyvers = mods[i]->policyvers;
2556 		}
2557 
2558 		if ((modules[i] =
2559 		     (policy_module_t *) calloc(1,
2560 						sizeof(policy_module_t))) ==
2561 		    NULL) {
2562 			ERR(state.handle, "Out of memory!");
2563 			goto cleanup;
2564 		}
2565 		modules[i]->policy = mods[i];
2566 		if (prepare_module(&state, modules[i]) == -1) {
2567 			goto cleanup;
2568 		}
2569 		num_mod_decls += modules[i]->num_decls;
2570 	}
2571 	if (prepare_base(&state, num_mod_decls) == -1) {
2572 		goto cleanup;
2573 	}
2574 
2575 	/* copy and remap the module's data over to base */
2576 	for (i = 0; i < len; i++) {
2577 		state.cur = modules[i];
2578 		ret = copy_module(&state, modules[i]);
2579 		if (ret) {
2580 			retval = ret;
2581 			goto cleanup;
2582 		}
2583 	}
2584 
2585 	/* re-index base, for symbols were added to symbol tables  */
2586 	if (policydb_index_classes(state.base)) {
2587 		ERR(state.handle, "Error while indexing classes");
2588 		goto cleanup;
2589 	}
2590 	if (policydb_index_others(state.handle, state.base, 0)) {
2591 		ERR(state.handle, "Error while indexing others");
2592 		goto cleanup;
2593 	}
2594 
2595 	if (enable_avrules(&state, state.base)) {
2596 		retval = SEPOL_EREQ;
2597 		goto cleanup;
2598 	}
2599 
2600 	/* Now that all role attribute's roles ebitmap have been settled,
2601 	 * escalate sub role attribute's roles ebitmap into that of parent.
2602 	 *
2603 	 * First, since some role-attribute relationships could be recorded
2604 	 * in some decl's local symtab(see get_local_role()), we need to
2605 	 * populate them up to the base.p_roles table. */
2606 	if (populate_roleattributes(&state, state.base)) {
2607 		retval = SEPOL_EREQ;
2608 		goto cleanup;
2609 	}
2610 
2611 	/* Now do the escalation. */
2612 	if (hashtab_map(state.base->p_roles.table, expand_role_attributes,
2613 			&state))
2614 		goto cleanup;
2615 
2616 	retval = 0;
2617       cleanup:
2618 	for (i = 0; modules != NULL && i < len; i++) {
2619 		policy_module_destroy(modules[i]);
2620 	}
2621 	free(modules);
2622 	free(state.decl_to_mod);
2623 	return retval;
2624 }
2625