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