• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
2  *          Jason Tang <jtang@tresys.com>
3  *	    Joshua Brindle <jbrindle@tresys.com>
4  *
5  * Copyright (C) 2004-2005 Tresys Technology, LLC
6  * Copyright (C) 2007 Red Hat, Inc.
7  * Copyright (C) 2017 Mellanox Technologies, Inc.
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2.1 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23 
24 #include "context.h"
25 #include <sepol/policydb/policydb.h>
26 #include <sepol/policydb/conditional.h>
27 #include <sepol/policydb/hashtab.h>
28 #include <sepol/policydb/expand.h>
29 #include <sepol/policydb/hierarchy.h>
30 #include <sepol/policydb/avrule_block.h>
31 
32 #include <stdlib.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <inttypes.h>
38 
39 #include "debug.h"
40 #include "private.h"
41 
42 typedef struct expand_state {
43 	int verbose;
44 	uint32_t *typemap;
45 	uint32_t *boolmap;
46 	uint32_t *rolemap;
47 	uint32_t *usermap;
48 	policydb_t *base;
49 	policydb_t *out;
50 	sepol_handle_t *handle;
51 	int expand_neverallow;
52 } expand_state_t;
53 
expand_state_init(expand_state_t * state)54 static void expand_state_init(expand_state_t * state)
55 {
56 	memset(state, 0, sizeof(expand_state_t));
57 }
58 
map_ebitmap(ebitmap_t * src,ebitmap_t * dst,uint32_t * map)59 static int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map)
60 {
61 	unsigned int i;
62 	ebitmap_node_t *tnode;
63 	ebitmap_init(dst);
64 
65 	ebitmap_for_each_positive_bit(src, tnode, i) {
66 		if (!map[i])
67 			continue;
68 		if (ebitmap_set_bit(dst, map[i] - 1, 1))
69 			return -1;
70 	}
71 	return 0;
72 }
73 
type_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)74 static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
75 			      void *data)
76 {
77 	int ret;
78 	char *id, *new_id;
79 	type_datum_t *type, *new_type;
80 	expand_state_t *state;
81 
82 	id = (char *)key;
83 	type = (type_datum_t *) datum;
84 	state = (expand_state_t *) data;
85 
86 	if ((type->flavor == TYPE_TYPE && !type->primary)
87 	    || type->flavor == TYPE_ALIAS) {
88 		/* aliases are handled later */
89 		return 0;
90 	}
91 	if (!is_id_enabled(id, state->base, SYM_TYPES)) {
92 		/* identifier's scope is not enabled */
93 		return 0;
94 	}
95 
96 	if (state->verbose)
97 		INFO(state->handle, "copying type or attribute %s", id);
98 
99 	new_id = strdup(id);
100 	if (new_id == NULL) {
101 		ERR(state->handle, "Out of memory!");
102 		return -1;
103 	}
104 
105 	new_type = (type_datum_t *) malloc(sizeof(type_datum_t));
106 	if (!new_type) {
107 		ERR(state->handle, "Out of memory!");
108 		free(new_id);
109 		return SEPOL_ENOMEM;
110 	}
111 	memset(new_type, 0, sizeof(type_datum_t));
112 
113 	new_type->flavor = type->flavor;
114 	new_type->flags = type->flags;
115 	new_type->s.value = ++state->out->p_types.nprim;
116 	if (new_type->s.value > UINT16_MAX) {
117 		free(new_id);
118 		free(new_type);
119 		ERR(state->handle, "type space overflow");
120 		return -1;
121 	}
122 	new_type->primary = 1;
123 	state->typemap[type->s.value - 1] = new_type->s.value;
124 
125 	ret = hashtab_insert(state->out->p_types.table,
126 			     (hashtab_key_t) new_id,
127 			     (hashtab_datum_t) new_type);
128 	if (ret) {
129 		free(new_id);
130 		free(new_type);
131 		ERR(state->handle, "hashtab overflow");
132 		return -1;
133 	}
134 
135 	if (new_type->flags & TYPE_FLAGS_PERMISSIVE)
136 		if (ebitmap_set_bit(&state->out->permissive_map, new_type->s.value, 1)) {
137 			ERR(state->handle, "Out of memory!\n");
138 			return -1;
139 		}
140 
141 	return 0;
142 }
143 
attr_convert_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)144 static int attr_convert_callback(hashtab_key_t key, hashtab_datum_t datum,
145 				 void *data)
146 {
147 	char *id;
148 	type_datum_t *type, *new_type;
149 	expand_state_t *state;
150 	ebitmap_t tmp_union;
151 
152 	id = (char *)key;
153 	type = (type_datum_t *) datum;
154 	state = (expand_state_t *) data;
155 
156 	if (type->flavor != TYPE_ATTRIB)
157 		return 0;
158 
159 	if (!is_id_enabled(id, state->base, SYM_TYPES)) {
160 		/* identifier's scope is not enabled */
161 		return 0;
162 	}
163 
164 	if (state->verbose)
165 		INFO(state->handle, "converting attribute %s", id);
166 
167 	new_type = hashtab_search(state->out->p_types.table, id);
168 	if (!new_type) {
169 		ERR(state->handle, "attribute %s vanished!", id);
170 		return -1;
171 	}
172 	if (map_ebitmap(&type->types, &tmp_union, state->typemap)) {
173 		ERR(state->handle, "out of memory");
174 		return -1;
175 	}
176 
177 	/* then union tmp_union onto &new_type->types */
178 	if (ebitmap_union(&new_type->types, &tmp_union)) {
179 		ERR(state->handle, "Out of memory!");
180 		return -1;
181 	}
182 	ebitmap_destroy(&tmp_union);
183 
184 	return 0;
185 }
186 
perm_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)187 static int perm_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
188 			      void *data)
189 {
190 	int ret;
191 	char *id, *new_id;
192 	symtab_t *s;
193 	perm_datum_t *perm, *new_perm;
194 
195 	id = key;
196 	perm = (perm_datum_t *) datum;
197 	s = (symtab_t *) data;
198 
199 	new_perm = (perm_datum_t *) malloc(sizeof(perm_datum_t));
200 	if (!new_perm) {
201 		return -1;
202 	}
203 	memset(new_perm, 0, sizeof(perm_datum_t));
204 
205 	new_id = strdup(id);
206 	if (!new_id) {
207 		free(new_perm);
208 		return -1;
209 	}
210 
211 	new_perm->s.value = perm->s.value;
212 	s->nprim++;
213 
214 	ret = hashtab_insert(s->table, new_id, (hashtab_datum_t *) new_perm);
215 	if (ret) {
216 		free(new_id);
217 		free(new_perm);
218 		return -1;
219 	}
220 
221 	return 0;
222 }
223 
common_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)224 static int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
225 				void *data)
226 {
227 	int ret;
228 	char *id, *new_id;
229 	common_datum_t *common, *new_common;
230 	expand_state_t *state;
231 
232 	id = (char *)key;
233 	common = (common_datum_t *) datum;
234 	state = (expand_state_t *) data;
235 
236 	if (state->verbose)
237 		INFO(state->handle, "copying common %s", id);
238 
239 	new_common = (common_datum_t *) malloc(sizeof(common_datum_t));
240 	if (!new_common) {
241 		ERR(state->handle, "Out of memory!");
242 		return -1;
243 	}
244 	memset(new_common, 0, sizeof(common_datum_t));
245 	if (symtab_init(&new_common->permissions, PERM_SYMTAB_SIZE)) {
246 		ERR(state->handle, "Out of memory!");
247 		free(new_common);
248 		return -1;
249 	}
250 
251 	new_id = strdup(id);
252 	if (!new_id) {
253 		ERR(state->handle, "Out of memory!");
254 		/* free memory created by symtab_init first, then free new_common */
255 		symtab_destroy(&new_common->permissions);
256 		free(new_common);
257 		return -1;
258 	}
259 
260 	new_common->s.value = common->s.value;
261 	state->out->p_commons.nprim++;
262 
263 	ret =
264 	    hashtab_insert(state->out->p_commons.table, new_id,
265 			   (hashtab_datum_t *) new_common);
266 	if (ret) {
267 		ERR(state->handle, "hashtab overflow");
268 		free(new_common);
269 		free(new_id);
270 		return -1;
271 	}
272 
273 	if (hashtab_map
274 	    (common->permissions.table, perm_copy_callback,
275 	     &new_common->permissions)) {
276 		ERR(state->handle, "Out of memory!");
277 		return -1;
278 	}
279 
280 	return 0;
281 }
282 
constraint_node_clone(constraint_node_t ** dst,constraint_node_t * src,expand_state_t * state)283 static int constraint_node_clone(constraint_node_t ** dst,
284 				 constraint_node_t * src,
285 				 expand_state_t * state)
286 {
287 	constraint_node_t *new_con = NULL, *last_new_con = NULL;
288 	constraint_expr_t *new_expr = NULL;
289 	*dst = NULL;
290 	while (src != NULL) {
291 		constraint_expr_t *expr, *expr_l = NULL;
292 		new_con =
293 		    (constraint_node_t *) malloc(sizeof(constraint_node_t));
294 		if (!new_con) {
295 			goto out_of_mem;
296 		}
297 		memset(new_con, 0, sizeof(constraint_node_t));
298 		new_con->permissions = src->permissions;
299 		for (expr = src->expr; expr; expr = expr->next) {
300 			if ((new_expr = calloc(1, sizeof(*new_expr))) == NULL) {
301 				goto out_of_mem;
302 			}
303 			if (constraint_expr_init(new_expr) == -1) {
304 				goto out_of_mem;
305 			}
306 			new_expr->expr_type = expr->expr_type;
307 			new_expr->attr = expr->attr;
308 			new_expr->op = expr->op;
309 			if (new_expr->expr_type == CEXPR_NAMES) {
310 				if (new_expr->attr & CEXPR_TYPE) {
311 					/*
312 					 * Copy over constraint policy source types and/or
313 					 * attributes for sepol_compute_av_reason_buffer(3)
314 					 * so that utilities can analyse constraint errors.
315 					 */
316 					if (map_ebitmap(&expr->type_names->types,
317 							&new_expr->type_names->types,
318 							state->typemap)) {
319 						ERR(NULL, "Failed to map type_names->types");
320 						goto out_of_mem;
321 					}
322 					/* Type sets require expansion and conversion. */
323 					if (expand_convert_type_set(state->out,
324 								    state->
325 								    typemap,
326 								    expr->
327 								    type_names,
328 								    &new_expr->
329 								    names, 1)) {
330 						goto out_of_mem;
331 					}
332 				} else if (new_expr->attr & CEXPR_ROLE) {
333 					if (map_ebitmap(&expr->names, &new_expr->names, state->rolemap)) {
334 						goto out_of_mem;
335 					}
336 				} else if (new_expr->attr & CEXPR_USER) {
337 					if (map_ebitmap(&expr->names, &new_expr->names, state->usermap)) {
338 						goto out_of_mem;
339 					}
340 				} else {
341 					/* Other kinds of sets do not. */
342 					if (ebitmap_cpy(&new_expr->names,
343 							&expr->names)) {
344 						goto out_of_mem;
345 					}
346 				}
347 			}
348 			if (expr_l) {
349 				expr_l->next = new_expr;
350 			} else {
351 				new_con->expr = new_expr;
352 			}
353 			expr_l = new_expr;
354 			new_expr = NULL;
355 		}
356 		if (last_new_con == NULL) {
357 			*dst = new_con;
358 		} else {
359 			last_new_con->next = new_con;
360 		}
361 		last_new_con = new_con;
362 		src = src->next;
363 	}
364 
365 	return 0;
366       out_of_mem:
367 	ERR(state->handle, "Out of memory!");
368 	if (new_con)
369 		free(new_con);
370 	constraint_expr_destroy(new_expr);
371 	return -1;
372 }
373 
class_copy_default_new_object(expand_state_t * state,class_datum_t * olddatum,class_datum_t * newdatum)374 static int class_copy_default_new_object(expand_state_t *state,
375 					 class_datum_t *olddatum,
376 					 class_datum_t *newdatum)
377 {
378 	if (olddatum->default_user) {
379 		if (newdatum->default_user && olddatum->default_user != newdatum->default_user) {
380 			ERR(state->handle, "Found conflicting default user definitions");
381 			return SEPOL_ENOTSUP;
382 		}
383 		newdatum->default_user = olddatum->default_user;
384 
385 	}
386 	if (olddatum->default_role) {
387 		if (newdatum->default_role && olddatum->default_role != newdatum->default_role) {
388 			ERR(state->handle, "Found conflicting default role definitions");
389 			return SEPOL_ENOTSUP;
390 		}
391 		newdatum->default_role = olddatum->default_role;
392 	}
393 	if (olddatum->default_type) {
394 		if (newdatum->default_type && olddatum->default_type != newdatum->default_type) {
395 			ERR(state->handle, "Found conflicting default type definitions");
396 			return SEPOL_ENOTSUP;
397 		}
398 		newdatum->default_type = olddatum->default_type;
399 	}
400 	if (olddatum->default_range) {
401 		if (newdatum->default_range && olddatum->default_range != newdatum->default_range) {
402 			ERR(state->handle, "Found conflicting default range definitions");
403 			return SEPOL_ENOTSUP;
404 		}
405 		newdatum->default_range = olddatum->default_range;
406 	}
407 	return 0;
408 }
409 
class_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)410 static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
411 			       void *data)
412 {
413 	int ret;
414 	char *id, *new_id;
415 	class_datum_t *class, *new_class;
416 	expand_state_t *state;
417 
418 	id = (char *)key;
419 	class = (class_datum_t *) datum;
420 	state = (expand_state_t *) data;
421 
422 	if (!is_id_enabled(id, state->base, SYM_CLASSES)) {
423 		/* identifier's scope is not enabled */
424 		return 0;
425 	}
426 
427 	if (state->verbose)
428 		INFO(state->handle, "copying class %s", id);
429 
430 	new_class = (class_datum_t *) malloc(sizeof(class_datum_t));
431 	if (!new_class) {
432 		ERR(state->handle, "Out of memory!");
433 		return -1;
434 	}
435 	memset(new_class, 0, sizeof(class_datum_t));
436 	if (symtab_init(&new_class->permissions, PERM_SYMTAB_SIZE)) {
437 		ERR(state->handle, "Out of memory!");
438 		free(new_class);
439 		return -1;
440 	}
441 
442 	new_class->s.value = class->s.value;
443 	state->out->p_classes.nprim++;
444 
445 	ret = class_copy_default_new_object(state, class, new_class);
446 	if (ret) {
447 		free(new_class);
448 		return ret;
449 	}
450 
451 	new_id = strdup(id);
452 	if (!new_id) {
453 		ERR(state->handle, "Out of memory!");
454 		free(new_class);
455 		return -1;
456 	}
457 
458 	ret =
459 	    hashtab_insert(state->out->p_classes.table, new_id,
460 			   (hashtab_datum_t *) new_class);
461 	if (ret) {
462 		ERR(state->handle, "hashtab overflow");
463 		free(new_class);
464 		free(new_id);
465 		return -1;
466 	}
467 
468 	if (hashtab_map
469 	    (class->permissions.table, perm_copy_callback,
470 	     &new_class->permissions)) {
471 		ERR(state->handle, "hashtab overflow");
472 		return -1;
473 	}
474 
475 	if (class->comkey) {
476 		new_class->comkey = strdup(class->comkey);
477 		if (!new_class->comkey) {
478 			ERR(state->handle, "Out of memory!");
479 			return -1;
480 		}
481 
482 		new_class->comdatum =
483 		    hashtab_search(state->out->p_commons.table,
484 				   new_class->comkey);
485 		if (!new_class->comdatum) {
486 			ERR(state->handle, "could not find common datum %s",
487 			    new_class->comkey);
488 			return -1;
489 		}
490 		new_class->permissions.nprim +=
491 		    new_class->comdatum->permissions.nprim;
492 	}
493 
494 	return 0;
495 }
496 
constraint_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)497 static int constraint_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
498 				    void *data)
499 {
500 	char *id;
501 	class_datum_t *class, *new_class;
502 	expand_state_t *state;
503 
504 	id = (char *)key;
505 	class = (class_datum_t *) datum;
506 	state = (expand_state_t *) data;
507 
508 	new_class = hashtab_search(state->out->p_classes.table, id);
509 	if (!new_class) {
510 		ERR(state->handle, "class %s vanished", id);
511 		return -1;
512 	}
513 
514 	/* constraints */
515 	if (constraint_node_clone
516 	    (&new_class->constraints, class->constraints, state) == -1
517 	    || constraint_node_clone(&new_class->validatetrans,
518 				     class->validatetrans, state) == -1) {
519 		return -1;
520 	}
521 	return 0;
522 }
523 
524 /*
525  * The boundaries have to be copied after the types/roles/users are copied,
526  * because it refers hashtab to lookup destinated objects.
527  */
type_bounds_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)528 static int type_bounds_copy_callback(hashtab_key_t key,
529 				     hashtab_datum_t datum, void *data)
530 {
531 	expand_state_t *state = (expand_state_t *) data;
532 	type_datum_t *type = (type_datum_t *) datum;
533 	type_datum_t *dest;
534 	uint32_t bounds_val;
535 
536 	if (!type->bounds)
537 		return 0;
538 
539 	if (!is_id_enabled((char *)key, state->base, SYM_TYPES))
540 		return 0;
541 
542 	bounds_val = state->typemap[type->bounds - 1];
543 
544 	dest = hashtab_search(state->out->p_types.table, (char *)key);
545 	if (!dest) {
546 		ERR(state->handle, "Type lookup failed for %s", (char *)key);
547 		return -1;
548 	}
549 	if (dest->bounds != 0 && dest->bounds != bounds_val) {
550 		ERR(state->handle, "Inconsistent boundary for %s", (char *)key);
551 		return -1;
552 	}
553 	dest->bounds = bounds_val;
554 
555 	return 0;
556 }
557 
role_bounds_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)558 static int role_bounds_copy_callback(hashtab_key_t key,
559 				     hashtab_datum_t datum, void *data)
560 {
561 	expand_state_t *state = (expand_state_t *) data;
562 	role_datum_t *role = (role_datum_t *) datum;
563 	role_datum_t *dest;
564 	uint32_t bounds_val;
565 
566 	if (!role->bounds)
567 		return 0;
568 
569 	if (!is_id_enabled((char *)key, state->base, SYM_ROLES))
570 		return 0;
571 
572 	bounds_val = state->rolemap[role->bounds - 1];
573 
574 	dest = hashtab_search(state->out->p_roles.table, (char *)key);
575 	if (!dest) {
576 		ERR(state->handle, "Role lookup failed for %s", (char *)key);
577 		return -1;
578 	}
579 	if (dest->bounds != 0 && dest->bounds != bounds_val) {
580 		ERR(state->handle, "Inconsistent boundary for %s", (char *)key);
581 		return -1;
582 	}
583 	dest->bounds = bounds_val;
584 
585 	return 0;
586 }
587 
user_bounds_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)588 static int user_bounds_copy_callback(hashtab_key_t key,
589 				     hashtab_datum_t datum, void *data)
590 {
591 	expand_state_t *state = (expand_state_t *) data;
592 	user_datum_t *user = (user_datum_t *) datum;
593 	user_datum_t *dest;
594 	uint32_t bounds_val;
595 
596 	if (!user->bounds)
597 		return 0;
598 
599 	if (!is_id_enabled((char *)key, state->base, SYM_USERS))
600 		return 0;
601 
602 	bounds_val = state->usermap[user->bounds - 1];
603 
604 	dest = hashtab_search(state->out->p_users.table, (char *)key);
605 	if (!dest) {
606 		ERR(state->handle, "User lookup failed for %s", (char *)key);
607 		return -1;
608 	}
609 	if (dest->bounds != 0 && dest->bounds != bounds_val) {
610 		ERR(state->handle, "Inconsistent boundary for %s", (char *)key);
611 		return -1;
612 	}
613 	dest->bounds = bounds_val;
614 
615 	return 0;
616 }
617 
618 /* The aliases have to be copied after the types and attributes to be certain that
619  * the out symbol table will have the type that the alias refers. Otherwise, we
620  * won't be able to find the type value for the alias. We can't depend on the
621  * declaration ordering because of the hash table.
622  */
alias_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)623 static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
624 			       void *data)
625 {
626 	int ret;
627 	char *id, *new_id;
628 	type_datum_t *alias, *new_alias;
629 	expand_state_t *state;
630 	uint32_t prival;
631 
632 	id = (char *)key;
633 	alias = (type_datum_t *) datum;
634 	state = (expand_state_t *) data;
635 
636 	/* ignore regular types */
637 	if (alias->flavor == TYPE_TYPE && alias->primary)
638 		return 0;
639 
640 	/* ignore attributes */
641 	if (alias->flavor == TYPE_ATTRIB)
642 		return 0;
643 
644 	if (alias->flavor == TYPE_ALIAS)
645 		prival = alias->primary;
646 	else
647 		prival = alias->s.value;
648 
649 	if (!is_id_enabled(state->base->p_type_val_to_name[prival - 1],
650 			state->base, SYM_TYPES)) {
651 		/* The primary type for this alias is not enabled, the alias
652  		 * shouldn't be either */
653 		return 0;
654 	}
655 
656 	if (state->verbose)
657 		INFO(state->handle, "copying alias %s", id);
658 
659 	new_id = strdup(id);
660 	if (!new_id) {
661 		ERR(state->handle, "Out of memory!");
662 		return -1;
663 	}
664 
665 	new_alias = (type_datum_t *) malloc(sizeof(type_datum_t));
666 	if (!new_alias) {
667 		ERR(state->handle, "Out of memory!");
668 		free(new_id);
669 		return SEPOL_ENOMEM;
670 	}
671 	memset(new_alias, 0, sizeof(type_datum_t));
672 	if (alias->flavor == TYPE_TYPE)
673 		new_alias->s.value = state->typemap[alias->s.value - 1];
674 	else if (alias->flavor == TYPE_ALIAS)
675 		new_alias->s.value = state->typemap[alias->primary - 1];
676 	else
677 		assert(0);	/* unreachable */
678 
679 	new_alias->flags = alias->flags;
680 
681 	ret = hashtab_insert(state->out->p_types.table,
682 			     (hashtab_key_t) new_id,
683 			     (hashtab_datum_t) new_alias);
684 
685 	if (ret) {
686 		ERR(state->handle, "hashtab overflow");
687 		free(new_alias);
688 		free(new_id);
689 		return -1;
690 	}
691 
692 	state->typemap[alias->s.value - 1] = new_alias->s.value;
693 
694 	if (new_alias->flags & TYPE_FLAGS_PERMISSIVE)
695 		if (ebitmap_set_bit(&state->out->permissive_map, new_alias->s.value, 1)) {
696 			ERR(state->handle, "Out of memory!");
697 			return -1;
698 		}
699 
700 	return 0;
701 }
702 
role_remap_dominates(hashtab_key_t key,hashtab_datum_t datum,void * data)703 static int role_remap_dominates(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *data)
704 {
705 	ebitmap_t mapped_roles;
706 	role_datum_t *role = (role_datum_t *) datum;
707 	expand_state_t *state = (expand_state_t *) data;
708 
709 	if (map_ebitmap(&role->dominates, &mapped_roles, state->rolemap))
710 		return -1;
711 
712 	ebitmap_destroy(&role->dominates);
713 
714 	if (ebitmap_cpy(&role->dominates, &mapped_roles))
715 		return -1;
716 
717 	ebitmap_destroy(&mapped_roles);
718 
719 	return 0;
720 }
721 
722 /* For the role attribute in the base module, escalate its counterpart's
723  * types.types ebitmap in the out module to the counterparts of all the
724  * regular role that belongs to the current role attribute. Note, must be
725  * invoked after role_copy_callback so that state->rolemap is available.
726  */
role_fix_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)727 static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
728 			     void *data)
729 {
730 	char *id, *base_reg_role_id;
731 	role_datum_t *role, *new_role, *regular_role;
732 	expand_state_t *state;
733 	ebitmap_node_t *rnode;
734 	unsigned int i;
735 	ebitmap_t mapped_roles;
736 
737 	id = key;
738 	role = (role_datum_t *)datum;
739 	state = (expand_state_t *)data;
740 
741 	if (strcmp(id, OBJECT_R) == 0) {
742 		/* object_r is never a role attribute by far */
743 		return 0;
744 	}
745 
746 	if (!is_id_enabled(id, state->base, SYM_ROLES)) {
747 		/* identifier's scope is not enabled */
748 		return 0;
749 	}
750 
751 	if (role->flavor != ROLE_ATTRIB)
752 		return 0;
753 
754 	if (state->verbose)
755 		INFO(state->handle, "fixing role attribute %s", id);
756 
757 	new_role =
758 		(role_datum_t *)hashtab_search(state->out->p_roles.table, id);
759 
760 	assert(new_role != NULL && new_role->flavor == ROLE_ATTRIB);
761 
762 	ebitmap_init(&mapped_roles);
763 	if (map_ebitmap(&role->roles, &mapped_roles, state->rolemap))
764 		return -1;
765 	if (ebitmap_union(&new_role->roles, &mapped_roles)) {
766 		ERR(state->handle, "Out of memory!");
767 		ebitmap_destroy(&mapped_roles);
768 		return -1;
769 	}
770 	ebitmap_destroy(&mapped_roles);
771 
772 	ebitmap_for_each_positive_bit(&role->roles, rnode, i) {
773 		/* take advantage of sym_val_to_name[]
774 		 * of the base module */
775 		base_reg_role_id = state->base->p_role_val_to_name[i];
776 		regular_role = (role_datum_t *)hashtab_search(
777 					state->out->p_roles.table,
778 					base_reg_role_id);
779 		assert(regular_role != NULL &&
780 		       regular_role->flavor == ROLE_ROLE);
781 
782 		if (ebitmap_union(&regular_role->types.types,
783 				  &new_role->types.types)) {
784 			ERR(state->handle, "Out of memory!");
785 			return -1;
786 		}
787 	}
788 
789 	return 0;
790 }
791 
role_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)792 static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
793 			      void *data)
794 {
795 	int ret;
796 	char *id, *new_id;
797 	role_datum_t *role;
798 	role_datum_t *new_role;
799 	expand_state_t *state;
800 	ebitmap_t tmp_union_types;
801 
802 	id = key;
803 	role = (role_datum_t *) datum;
804 	state = (expand_state_t *) data;
805 
806 	if (strcmp(id, OBJECT_R) == 0) {
807 		/* object_r is always value 1 */
808 		state->rolemap[role->s.value - 1] = 1;
809 		return 0;
810 	}
811 
812 	if (!is_id_enabled(id, state->base, SYM_ROLES)) {
813 		/* identifier's scope is not enabled */
814 		return 0;
815 	}
816 
817 	if (state->verbose)
818 		INFO(state->handle, "copying role %s", id);
819 
820 	new_role =
821 	    (role_datum_t *) hashtab_search(state->out->p_roles.table, id);
822 	if (!new_role) {
823 		new_role = (role_datum_t *) malloc(sizeof(role_datum_t));
824 		if (!new_role) {
825 			ERR(state->handle, "Out of memory!");
826 			return -1;
827 		}
828 		memset(new_role, 0, sizeof(role_datum_t));
829 
830 		new_id = strdup(id);
831 		if (!new_id) {
832 			ERR(state->handle, "Out of memory!");
833 			free(new_role);
834 			return -1;
835 		}
836 
837 		state->out->p_roles.nprim++;
838 		new_role->flavor = role->flavor;
839 		new_role->s.value = state->out->p_roles.nprim;
840 		state->rolemap[role->s.value - 1] = new_role->s.value;
841 		ret = hashtab_insert(state->out->p_roles.table,
842 				     (hashtab_key_t) new_id,
843 				     (hashtab_datum_t) new_role);
844 
845 		if (ret) {
846 			ERR(state->handle, "hashtab overflow");
847 			free(new_role);
848 			free(new_id);
849 			return -1;
850 		}
851 	}
852 
853 	/* The dominates bitmap is going to be wrong for the moment,
854  	 * we'll come back later and remap them, after we are sure all
855  	 * the roles have been added */
856 	if (ebitmap_union(&new_role->dominates, &role->dominates)) {
857 		ERR(state->handle, "Out of memory!");
858 		return -1;
859 	}
860 
861 	ebitmap_init(&tmp_union_types);
862 
863 	/* convert types in the role datum in the global symtab */
864 	if (expand_convert_type_set
865 	    (state->out, state->typemap, &role->types, &tmp_union_types, 1)) {
866 		ebitmap_destroy(&tmp_union_types);
867 		ERR(state->handle, "Out of memory!");
868 		return -1;
869 	}
870 
871 	if (ebitmap_union(&new_role->types.types, &tmp_union_types)) {
872 		ERR(state->handle, "Out of memory!");
873 		ebitmap_destroy(&tmp_union_types);
874 		return -1;
875 	}
876 	ebitmap_destroy(&tmp_union_types);
877 
878 	return 0;
879 }
880 
mls_semantic_level_expand(mls_semantic_level_t * sl,mls_level_t * l,policydb_t * p,sepol_handle_t * h)881 int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l,
882 			      policydb_t * p, sepol_handle_t * h)
883 {
884 	mls_semantic_cat_t *cat;
885 	level_datum_t *levdatum;
886 	unsigned int i;
887 
888 	mls_level_init(l);
889 
890 	if (!p->mls)
891 		return 0;
892 
893 	/* Required not declared. */
894 	if (!sl->sens)
895 		return 0;
896 
897 	l->sens = sl->sens;
898 	levdatum = (level_datum_t *) hashtab_search(p->p_levels.table,
899 						    p->p_sens_val_to_name[l->sens - 1]);
900 	if (!levdatum) {
901 		ERR(h, "%s: Impossible situation found, nothing in p_levels.table.\n",
902 		    __func__);
903 		errno = ENOENT;
904 		return -1;
905 	}
906 	for (cat = sl->cat; cat; cat = cat->next) {
907 		if (cat->low > cat->high) {
908 			ERR(h, "Category range is not valid %s.%s",
909 			    p->p_cat_val_to_name[cat->low - 1],
910 			    p->p_cat_val_to_name[cat->high - 1]);
911 			return -1;
912 		}
913 		for (i = cat->low - 1; i < cat->high; i++) {
914 			if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
915 				ERR(h, "Category %s can not be associated with "
916 				    "level %s",
917 				    p->p_cat_val_to_name[i],
918 				    p->p_sens_val_to_name[l->sens - 1]);
919 				return -1;
920 			}
921 			if (ebitmap_set_bit(&l->cat, i, 1)) {
922 				ERR(h, "Out of memory!");
923 				return -1;
924 			}
925 		}
926 	}
927 
928 	return 0;
929 }
930 
mls_semantic_range_expand(mls_semantic_range_t * sr,mls_range_t * r,policydb_t * p,sepol_handle_t * h)931 int mls_semantic_range_expand(mls_semantic_range_t * sr, mls_range_t * r,
932 			      policydb_t * p, sepol_handle_t * h)
933 {
934 	if (mls_semantic_level_expand(&sr->level[0], &r->level[0], p, h) < 0)
935 		return -1;
936 
937 	if (mls_semantic_level_expand(&sr->level[1], &r->level[1], p, h) < 0) {
938 		mls_level_destroy(&r->level[0]);
939 		return -1;
940 	}
941 
942 	if (!mls_level_dom(&r->level[1], &r->level[0])) {
943 		mls_range_destroy(r);
944 		ERR(h, "MLS range high level does not dominate low level");
945 		return -1;
946 	}
947 
948 	return 0;
949 }
950 
user_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)951 static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
952 			      void *data)
953 {
954 	int ret;
955 	expand_state_t *state;
956 	user_datum_t *user;
957 	user_datum_t *new_user;
958 	char *id, *new_id;
959 	ebitmap_t tmp_union;
960 
961 	id = key;
962 	user = (user_datum_t *) datum;
963 	state = (expand_state_t *) data;
964 
965 	if (!is_id_enabled(id, state->base, SYM_USERS)) {
966 		/* identifier's scope is not enabled */
967 		return 0;
968 	}
969 
970 	if (state->verbose)
971 		INFO(state->handle, "copying user %s", id);
972 
973 	new_user =
974 	    (user_datum_t *) hashtab_search(state->out->p_users.table, id);
975 	if (!new_user) {
976 		new_user = (user_datum_t *) malloc(sizeof(user_datum_t));
977 		if (!new_user) {
978 			ERR(state->handle, "Out of memory!");
979 			return -1;
980 		}
981 		memset(new_user, 0, sizeof(user_datum_t));
982 
983 		state->out->p_users.nprim++;
984 		new_user->s.value = state->out->p_users.nprim;
985 		state->usermap[user->s.value - 1] = new_user->s.value;
986 
987 		new_id = strdup(id);
988 		if (!new_id) {
989 			ERR(state->handle, "Out of memory!");
990 			free(new_user);
991 			return -1;
992 		}
993 		ret = hashtab_insert(state->out->p_users.table,
994 				     (hashtab_key_t) new_id,
995 				     (hashtab_datum_t) new_user);
996 		if (ret) {
997 			ERR(state->handle, "hashtab overflow");
998 			user_datum_destroy(new_user);
999 			free(new_user);
1000 			free(new_id);
1001 			return -1;
1002 		}
1003 
1004 		/* expand the semantic MLS info */
1005 		if (mls_semantic_range_expand(&user->range,
1006 					      &new_user->exp_range,
1007 					      state->out, state->handle)) {
1008 			return -1;
1009 		}
1010 		if (mls_semantic_level_expand(&user->dfltlevel,
1011 					      &new_user->exp_dfltlevel,
1012 					      state->out, state->handle)) {
1013 			return -1;
1014 		}
1015 		if (!mls_level_between(&new_user->exp_dfltlevel,
1016 				       &new_user->exp_range.level[0],
1017 				       &new_user->exp_range.level[1])) {
1018 			ERR(state->handle, "default level not within user "
1019 			    "range");
1020 			return -1;
1021 		}
1022 	} else {
1023 		/* require that the MLS info match */
1024 		mls_range_t tmp_range;
1025 		mls_level_t tmp_level;
1026 
1027 		if (mls_semantic_range_expand(&user->range, &tmp_range,
1028 					      state->out, state->handle)) {
1029 			return -1;
1030 		}
1031 		if (mls_semantic_level_expand(&user->dfltlevel, &tmp_level,
1032 					      state->out, state->handle)) {
1033 			mls_range_destroy(&tmp_range);
1034 			return -1;
1035 		}
1036 		if (!mls_range_eq(&new_user->exp_range, &tmp_range) ||
1037 		    !mls_level_eq(&new_user->exp_dfltlevel, &tmp_level)) {
1038 			mls_range_destroy(&tmp_range);
1039 			mls_level_destroy(&tmp_level);
1040 			return -1;
1041 		}
1042 		mls_range_destroy(&tmp_range);
1043 		mls_level_destroy(&tmp_level);
1044 	}
1045 
1046 	ebitmap_init(&tmp_union);
1047 
1048 	/* get global roles for this user */
1049 	if (role_set_expand(&user->roles, &tmp_union, state->out, state->base, state->rolemap)) {
1050 		ERR(state->handle, "Out of memory!");
1051 		ebitmap_destroy(&tmp_union);
1052 		return -1;
1053 	}
1054 
1055 	if (ebitmap_union(&new_user->roles.roles, &tmp_union)) {
1056 		ERR(state->handle, "Out of memory!");
1057 		ebitmap_destroy(&tmp_union);
1058 		return -1;
1059 	}
1060 	ebitmap_destroy(&tmp_union);
1061 
1062 	return 0;
1063 }
1064 
bool_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)1065 static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
1066 			      void *data)
1067 {
1068 	int ret;
1069 	expand_state_t *state;
1070 	cond_bool_datum_t *bool, *new_bool;
1071 	char *id, *new_id;
1072 
1073 	id = key;
1074 	bool = (cond_bool_datum_t *) datum;
1075 	state = (expand_state_t *) data;
1076 
1077 	if (!is_id_enabled(id, state->base, SYM_BOOLS)) {
1078 		/* identifier's scope is not enabled */
1079 		return 0;
1080 	}
1081 
1082 	if (bool->flags & COND_BOOL_FLAGS_TUNABLE) {
1083 		/* Skip tunables */
1084 		return 0;
1085 	}
1086 
1087 	if (state->verbose)
1088 		INFO(state->handle, "copying boolean %s", id);
1089 
1090 	new_bool = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1091 	if (!new_bool) {
1092 		ERR(state->handle, "Out of memory!");
1093 		return -1;
1094 	}
1095 
1096 	new_id = strdup(id);
1097 	if (!new_id) {
1098 		ERR(state->handle, "Out of memory!");
1099 		free(new_bool);
1100 		return -1;
1101 	}
1102 
1103 	state->out->p_bools.nprim++;
1104 	new_bool->s.value = state->out->p_bools.nprim;
1105 
1106 	ret = hashtab_insert(state->out->p_bools.table,
1107 			     (hashtab_key_t) new_id,
1108 			     (hashtab_datum_t) new_bool);
1109 	if (ret) {
1110 		ERR(state->handle, "hashtab overflow");
1111 		free(new_bool);
1112 		free(new_id);
1113 		return -1;
1114 	}
1115 
1116 	state->boolmap[bool->s.value - 1] = new_bool->s.value;
1117 
1118 	new_bool->state = bool->state;
1119 	new_bool->flags = bool->flags;
1120 
1121 	return 0;
1122 }
1123 
sens_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)1124 static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
1125 			      void *data)
1126 {
1127 	expand_state_t *state = (expand_state_t *) data;
1128 	level_datum_t *level = (level_datum_t *) datum, *new_level = NULL;
1129 	char *id = (char *)key, *new_id = NULL;
1130 
1131 	if (!is_id_enabled(id, state->base, SYM_LEVELS)) {
1132 		/* identifier's scope is not enabled */
1133 		return 0;
1134 	}
1135 
1136 	if (state->verbose)
1137 		INFO(state->handle, "copying sensitivity level %s", id);
1138 
1139 	new_level = (level_datum_t *) malloc(sizeof(level_datum_t));
1140 	if (!new_level)
1141 		goto out_of_mem;
1142 	level_datum_init(new_level);
1143 	new_level->level = (mls_level_t *) malloc(sizeof(mls_level_t));
1144 	if (!new_level->level)
1145 		goto out_of_mem;
1146 	mls_level_init(new_level->level);
1147 	new_id = strdup(id);
1148 	if (!new_id)
1149 		goto out_of_mem;
1150 
1151 	if (mls_level_cpy(new_level->level, level->level)) {
1152 		goto out_of_mem;
1153 	}
1154 	new_level->isalias = level->isalias;
1155 	state->out->p_levels.nprim++;
1156 
1157 	if (hashtab_insert(state->out->p_levels.table,
1158 			   (hashtab_key_t) new_id,
1159 			   (hashtab_datum_t) new_level)) {
1160 		goto out_of_mem;
1161 	}
1162 	return 0;
1163 
1164       out_of_mem:
1165 	ERR(state->handle, "Out of memory!");
1166 	if (new_level != NULL && new_level->level != NULL) {
1167 		mls_level_destroy(new_level->level);
1168 		free(new_level->level);
1169 	}
1170 	level_datum_destroy(new_level);
1171 	free(new_level);
1172 	free(new_id);
1173 	return -1;
1174 }
1175 
cats_copy_callback(hashtab_key_t key,hashtab_datum_t datum,void * data)1176 static int cats_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
1177 			      void *data)
1178 {
1179 	expand_state_t *state = (expand_state_t *) data;
1180 	cat_datum_t *cat = (cat_datum_t *) datum, *new_cat = NULL;
1181 	char *id = (char *)key, *new_id = NULL;
1182 
1183 	if (!is_id_enabled(id, state->base, SYM_CATS)) {
1184 		/* identifier's scope is not enabled */
1185 		return 0;
1186 	}
1187 
1188 	if (state->verbose)
1189 		INFO(state->handle, "copying category attribute %s", id);
1190 
1191 	new_cat = (cat_datum_t *) malloc(sizeof(cat_datum_t));
1192 	if (!new_cat)
1193 		goto out_of_mem;
1194 	cat_datum_init(new_cat);
1195 	new_id = strdup(id);
1196 	if (!new_id)
1197 		goto out_of_mem;
1198 
1199 	new_cat->s.value = cat->s.value;
1200 	new_cat->isalias = cat->isalias;
1201 	state->out->p_cats.nprim++;
1202 	if (hashtab_insert(state->out->p_cats.table,
1203 			   (hashtab_key_t) new_id, (hashtab_datum_t) new_cat)) {
1204 		goto out_of_mem;
1205 	}
1206 
1207 	return 0;
1208 
1209       out_of_mem:
1210 	ERR(state->handle, "Out of memory!");
1211 	cat_datum_destroy(new_cat);
1212 	free(new_cat);
1213 	free(new_id);
1214 	return -1;
1215 }
1216 
copy_role_allows(expand_state_t * state,role_allow_rule_t * rules)1217 static int copy_role_allows(expand_state_t * state, role_allow_rule_t * rules)
1218 {
1219 	unsigned int i, j;
1220 	role_allow_t *cur_allow, *n, *l;
1221 	role_allow_rule_t *cur;
1222 	ebitmap_t roles, new_roles;
1223 	ebitmap_node_t *snode, *tnode;
1224 
1225 	/* start at the end of the list */
1226 	for (l = state->out->role_allow; l && l->next; l = l->next) ;
1227 
1228 	cur = rules;
1229 	while (cur) {
1230 		ebitmap_init(&roles);
1231 		ebitmap_init(&new_roles);
1232 
1233 		if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) {
1234 			ERR(state->handle, "Out of memory!");
1235 			return -1;
1236 		}
1237 
1238 		if (role_set_expand(&cur->new_roles, &new_roles, state->out, state->base, state->rolemap)) {
1239 			ERR(state->handle, "Out of memory!");
1240 			return -1;
1241 		}
1242 
1243 		ebitmap_for_each_positive_bit(&roles, snode, i) {
1244 			ebitmap_for_each_positive_bit(&new_roles, tnode, j) {
1245 				/* check for duplicates */
1246 				cur_allow = state->out->role_allow;
1247 				while (cur_allow) {
1248 					if ((cur_allow->role == i + 1) &&
1249 					    (cur_allow->new_role == j + 1))
1250 						break;
1251 					cur_allow = cur_allow->next;
1252 				}
1253 				if (cur_allow)
1254 					continue;
1255 				n = (role_allow_t *)
1256 				    malloc(sizeof(role_allow_t));
1257 				if (!n) {
1258 					ERR(state->handle, "Out of memory!");
1259 					return -1;
1260 				}
1261 				memset(n, 0, sizeof(role_allow_t));
1262 				n->role = i + 1;
1263 				n->new_role = j + 1;
1264 				if (l) {
1265 					l->next = n;
1266 				} else {
1267 					state->out->role_allow = n;
1268 				}
1269 				l = n;
1270 			}
1271 		}
1272 
1273 		ebitmap_destroy(&roles);
1274 		ebitmap_destroy(&new_roles);
1275 
1276 		cur = cur->next;
1277 	}
1278 
1279 	return 0;
1280 }
1281 
copy_role_trans(expand_state_t * state,role_trans_rule_t * rules)1282 static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules)
1283 {
1284 	unsigned int i, j, k;
1285 	role_trans_t *n, *l, *cur_trans;
1286 	role_trans_rule_t *cur;
1287 	ebitmap_t roles, types;
1288 	ebitmap_node_t *rnode, *tnode, *cnode;
1289 
1290 	/* start at the end of the list */
1291 	for (l = state->out->role_tr; l && l->next; l = l->next) ;
1292 
1293 	cur = rules;
1294 	while (cur) {
1295 		ebitmap_init(&roles);
1296 		ebitmap_init(&types);
1297 
1298 		if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) {
1299 			ERR(state->handle, "Out of memory!");
1300 			return -1;
1301 		}
1302 		if (expand_convert_type_set
1303 		    (state->out, state->typemap, &cur->types, &types, 1)) {
1304 			ERR(state->handle, "Out of memory!");
1305 			return -1;
1306 		}
1307 		ebitmap_for_each_positive_bit(&roles, rnode, i) {
1308 			ebitmap_for_each_positive_bit(&types, tnode, j) {
1309 				ebitmap_for_each_positive_bit(&cur->classes, cnode, k) {
1310 					cur_trans = state->out->role_tr;
1311 					while (cur_trans) {
1312 						unsigned int mapped_role;
1313 
1314 						mapped_role = state->rolemap[cur->new_role - 1];
1315 
1316 						if ((cur_trans->role ==
1317 								i + 1) &&
1318 						    (cur_trans->type ==
1319 								j + 1) &&
1320 						    (cur_trans->tclass ==
1321 								k + 1)) {
1322 							if (cur_trans->new_role == mapped_role) {
1323 								break;
1324 							} else {
1325 								ERR(state->handle,
1326 									"Conflicting role trans rule %s %s : %s { %s vs %s }",
1327 									state->out->p_role_val_to_name[i],
1328 									state->out->p_type_val_to_name[j],
1329 									state->out->p_class_val_to_name[k],
1330 									state->out->p_role_val_to_name[mapped_role - 1],
1331 									state->out->p_role_val_to_name[cur_trans->new_role - 1]);
1332 								return -1;
1333 							}
1334 						}
1335 						cur_trans = cur_trans->next;
1336 					}
1337 					if (cur_trans)
1338 						continue;
1339 
1340 					n = (role_trans_t *)
1341 						malloc(sizeof(role_trans_t));
1342 					if (!n) {
1343 						ERR(state->handle,
1344 							"Out of memory!");
1345 						return -1;
1346 					}
1347 					memset(n, 0, sizeof(role_trans_t));
1348 					n->role = i + 1;
1349 					n->type = j + 1;
1350 					n->tclass = k + 1;
1351 					n->new_role = state->rolemap
1352 							[cur->new_role - 1];
1353 					if (l)
1354 						l->next = n;
1355 					else
1356 						state->out->role_tr = n;
1357 
1358 					l = n;
1359 				}
1360 			}
1361 		}
1362 
1363 		ebitmap_destroy(&roles);
1364 		ebitmap_destroy(&types);
1365 
1366 		cur = cur->next;
1367 	}
1368 	return 0;
1369 }
1370 
expand_filename_trans(expand_state_t * state,filename_trans_rule_t * rules)1371 static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules)
1372 {
1373 	unsigned int i, j;
1374 	filename_trans_t key, *new_trans;
1375 	filename_trans_datum_t *otype;
1376 	filename_trans_rule_t *cur_rule;
1377 	ebitmap_t stypes, ttypes;
1378 	ebitmap_node_t *snode, *tnode;
1379 	int rc;
1380 
1381 	cur_rule = rules;
1382 	while (cur_rule) {
1383 		uint32_t mapped_otype;
1384 
1385 		ebitmap_init(&stypes);
1386 		ebitmap_init(&ttypes);
1387 
1388 		if (expand_convert_type_set(state->out, state->typemap,
1389 					    &cur_rule->stypes, &stypes, 1)) {
1390 			ERR(state->handle, "Out of memory!");
1391 			return -1;
1392 		}
1393 
1394 		if (expand_convert_type_set(state->out, state->typemap,
1395 					    &cur_rule->ttypes, &ttypes, 1)) {
1396 			ERR(state->handle, "Out of memory!");
1397 			return -1;
1398 		}
1399 
1400 		mapped_otype = state->typemap[cur_rule->otype - 1];
1401 
1402 		ebitmap_for_each_positive_bit(&stypes, snode, i) {
1403 			ebitmap_for_each_positive_bit(&ttypes, tnode, j) {
1404 				key.stype = i + 1;
1405 				key.ttype = j + 1;
1406 				key.tclass = cur_rule->tclass;
1407 				key.name = cur_rule->name;
1408 				otype = hashtab_search(state->out->filename_trans,
1409 						       (hashtab_key_t) &key);
1410 				if (otype) {
1411 					/* duplicate rule, ignore */
1412 					if (otype->otype == mapped_otype)
1413 						continue;
1414 
1415 					ERR(state->handle, "Conflicting name-based type_transition %s %s:%s \"%s\":  %s vs %s",
1416 					    state->out->p_type_val_to_name[i],
1417 					    state->out->p_type_val_to_name[j],
1418 					    state->out->p_class_val_to_name[cur_rule->tclass - 1],
1419 					    cur_rule->name,
1420 					    state->out->p_type_val_to_name[otype->otype - 1],
1421 					    state->out->p_type_val_to_name[mapped_otype - 1]);
1422 					return -1;
1423 				}
1424 
1425 				new_trans = calloc(1, sizeof(*new_trans));
1426 				if (!new_trans) {
1427 					ERR(state->handle, "Out of memory!");
1428 					return -1;
1429 				}
1430 
1431 				new_trans->name = strdup(cur_rule->name);
1432 				if (!new_trans->name) {
1433 					ERR(state->handle, "Out of memory!");
1434 					free(new_trans);
1435 					return -1;
1436 				}
1437 				new_trans->stype = i + 1;
1438 				new_trans->ttype = j + 1;
1439 				new_trans->tclass = cur_rule->tclass;
1440 
1441 				otype = calloc(1, sizeof(*otype));
1442 				if (!otype) {
1443 					ERR(state->handle, "Out of memory!");
1444 					free(new_trans->name);
1445 					free(new_trans);
1446 					return -1;
1447 				}
1448 				otype->otype = mapped_otype;
1449 
1450 				rc = hashtab_insert(state->out->filename_trans,
1451 						    (hashtab_key_t)new_trans,
1452 						    otype);
1453 				if (rc) {
1454 					ERR(state->handle, "Out of memory!");
1455 					free(otype);
1456 					free(new_trans->name);
1457 					free(new_trans);
1458 					return -1;
1459 				}
1460 			}
1461 		}
1462 
1463 		ebitmap_destroy(&stypes);
1464 		ebitmap_destroy(&ttypes);
1465 
1466 		cur_rule = cur_rule->next;
1467 	}
1468 	return 0;
1469 }
1470 
exp_rangetr_helper(uint32_t stype,uint32_t ttype,uint32_t tclass,mls_semantic_range_t * trange,expand_state_t * state)1471 static int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t tclass,
1472 			      mls_semantic_range_t * trange,
1473 			      expand_state_t * state)
1474 {
1475 	range_trans_t *rt = NULL, key;
1476 	mls_range_t *r, *exp_range = NULL;
1477 	int rc = -1;
1478 
1479 	exp_range = calloc(1, sizeof(*exp_range));
1480 	if (!exp_range) {
1481 		ERR(state->handle, "Out of memory!");
1482 		return -1;
1483 	}
1484 
1485 	if (mls_semantic_range_expand(trange, exp_range, state->out,
1486 				      state->handle))
1487 		goto err;
1488 
1489 	/* check for duplicates/conflicts */
1490 	key.source_type = stype;
1491 	key.target_type = ttype;
1492 	key.target_class = tclass;
1493 	r = hashtab_search(state->out->range_tr, (hashtab_key_t) &key);
1494 	if (r) {
1495 		if (mls_range_eq(r, exp_range)) {
1496 			/* duplicate, ignore */
1497 			mls_range_destroy(exp_range);
1498 			free(exp_range);
1499 			return 0;
1500 		}
1501 
1502 		/* conflict */
1503 		ERR(state->handle,
1504 		    "Conflicting range trans rule %s %s : %s",
1505 		    state->out->p_type_val_to_name[stype - 1],
1506 		    state->out->p_type_val_to_name[ttype - 1],
1507 		    state->out->p_class_val_to_name[tclass - 1]);
1508 		goto err;
1509 	}
1510 
1511 	rt = calloc(1, sizeof(*rt));
1512 	if (!rt) {
1513 		ERR(state->handle, "Out of memory!");
1514 		goto err;
1515 	}
1516 	rt->source_type = stype;
1517 	rt->target_type = ttype;
1518 	rt->target_class = tclass;
1519 
1520 	rc = hashtab_insert(state->out->range_tr, (hashtab_key_t) rt,
1521 			    exp_range);
1522 	if (rc) {
1523 		ERR(state->handle, "Out of memory!");
1524 		goto err;
1525 
1526 	}
1527 
1528 	return 0;
1529 err:
1530 	free(rt);
1531 	if (exp_range) {
1532 		mls_range_destroy(exp_range);
1533 		free(exp_range);
1534 	}
1535 	return -1;
1536 }
1537 
expand_range_trans(expand_state_t * state,range_trans_rule_t * rules)1538 static int expand_range_trans(expand_state_t * state,
1539 			      range_trans_rule_t * rules)
1540 {
1541 	unsigned int i, j, k;
1542 	range_trans_rule_t *rule;
1543 
1544 	ebitmap_t stypes, ttypes;
1545 	ebitmap_node_t *snode, *tnode, *cnode;
1546 
1547 	if (state->verbose)
1548 		INFO(state->handle, "expanding range transitions");
1549 
1550 	for (rule = rules; rule; rule = rule->next) {
1551 		ebitmap_init(&stypes);
1552 		ebitmap_init(&ttypes);
1553 
1554 		/* expand the type sets */
1555 		if (expand_convert_type_set(state->out, state->typemap,
1556 					    &rule->stypes, &stypes, 1)) {
1557 			ERR(state->handle, "Out of memory!");
1558 			return -1;
1559 		}
1560 		if (expand_convert_type_set(state->out, state->typemap,
1561 					    &rule->ttypes, &ttypes, 1)) {
1562 			ebitmap_destroy(&stypes);
1563 			ERR(state->handle, "Out of memory!");
1564 			return -1;
1565 		}
1566 
1567 		/* loop on source type */
1568 		ebitmap_for_each_positive_bit(&stypes, snode, i) {
1569 			/* loop on target type */
1570 			ebitmap_for_each_positive_bit(&ttypes, tnode, j) {
1571 				/* loop on target class */
1572 				ebitmap_for_each_positive_bit(&rule->tclasses, cnode, k) {
1573 					if (exp_rangetr_helper(i + 1,
1574 							       j + 1,
1575 							       k + 1,
1576 							       &rule->trange,
1577 							       state)) {
1578 						ebitmap_destroy(&stypes);
1579 						ebitmap_destroy(&ttypes);
1580 						return -1;
1581 					}
1582 				}
1583 			}
1584 		}
1585 
1586 		ebitmap_destroy(&stypes);
1587 		ebitmap_destroy(&ttypes);
1588 	}
1589 
1590 	return 0;
1591 }
1592 
1593 /* Search for an AV tab node within a hash table with the given key.
1594  * If the node does not exist, create it and return it; otherwise
1595  * return the pre-existing one.
1596 */
find_avtab_node(sepol_handle_t * handle,avtab_t * avtab,avtab_key_t * key,cond_av_list_t ** cond,av_extended_perms_t * xperms)1597 static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,
1598 				   avtab_t * avtab, avtab_key_t * key,
1599 				   cond_av_list_t ** cond,
1600 				   av_extended_perms_t *xperms)
1601 {
1602 	avtab_ptr_t node;
1603 	avtab_datum_t avdatum;
1604 	cond_av_list_t *nl;
1605 	int match = 0;
1606 
1607 	/* AVTAB_XPERMS entries are not necessarily unique */
1608 	if (key->specified & AVTAB_XPERMS) {
1609 		node = avtab_search_node(avtab, key);
1610 		while (node) {
1611 			if ((node->datum.xperms->specified == xperms->specified) &&
1612 				(node->datum.xperms->driver == xperms->driver)) {
1613 				match = 1;
1614 				break;
1615 			}
1616 			node = avtab_search_node_next(node, key->specified);
1617 		}
1618 		if (!match)
1619 			node = NULL;
1620 	} else {
1621 		node = avtab_search_node(avtab, key);
1622 	}
1623 
1624 	/* If this is for conditional policies, keep searching in case
1625 	   the node is part of my conditional avtab. */
1626 	if (cond) {
1627 		while (node) {
1628 			if (node->parse_context == cond)
1629 				break;
1630 			node = avtab_search_node_next(node, key->specified);
1631 		}
1632 	}
1633 
1634 	if (!node) {
1635 		memset(&avdatum, 0, sizeof avdatum);
1636 		/*
1637 		 * AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for
1638 		 * others. Initialize the data accordingly.
1639 		 */
1640 		avdatum.data = key->specified == AVTAB_AUDITDENY ? ~0 : 0;
1641 		/* this is used to get the node - insertion is actually unique */
1642 		node = avtab_insert_nonunique(avtab, key, &avdatum);
1643 		if (!node) {
1644 			ERR(handle, "hash table overflow");
1645 			return NULL;
1646 		}
1647 		if (cond) {
1648 			node->parse_context = cond;
1649 			nl = (cond_av_list_t *) malloc(sizeof(cond_av_list_t));
1650 			if (!nl) {
1651 				ERR(handle, "Memory error");
1652 				return NULL;
1653 			}
1654 			memset(nl, 0, sizeof(cond_av_list_t));
1655 			nl->node = node;
1656 			nl->next = *cond;
1657 			*cond = nl;
1658 		}
1659 	}
1660 
1661 	return node;
1662 }
1663 
avrule_to_avtab_spec(uint32_t specification)1664 static uint32_t avrule_to_avtab_spec(uint32_t specification)
1665 {
1666 	return (specification == AVRULE_DONTAUDIT) ?
1667 		AVTAB_AUDITDENY : specification;
1668 }
1669 
1670 #define EXPAND_RULE_SUCCESS   1
1671 #define EXPAND_RULE_CONFLICT  0
1672 #define EXPAND_RULE_ERROR    -1
1673 
expand_terule_helper(sepol_handle_t * handle,policydb_t * p,uint32_t * typemap,uint32_t specified,cond_av_list_t ** cond,cond_av_list_t ** other,uint32_t stype,uint32_t ttype,class_perm_node_t * perms,avtab_t * avtab,int enabled)1674 static int expand_terule_helper(sepol_handle_t * handle,
1675 				policydb_t * p, uint32_t * typemap,
1676 				uint32_t specified, cond_av_list_t ** cond,
1677 				cond_av_list_t ** other, uint32_t stype,
1678 				uint32_t ttype, class_perm_node_t * perms,
1679 				avtab_t * avtab, int enabled)
1680 {
1681 	avtab_key_t avkey;
1682 	avtab_datum_t *avdatump;
1683 	avtab_ptr_t node;
1684 	class_perm_node_t *cur;
1685 	int conflict;
1686 	uint32_t oldtype = 0;
1687 
1688 	if (!(specified & (AVRULE_TRANSITION|AVRULE_MEMBER|AVRULE_CHANGE))) {
1689 		ERR(handle, "Invalid specification: %"PRIu32"\n", specified);
1690 		return EXPAND_RULE_ERROR;
1691 	}
1692 
1693 	avkey.specified = avrule_to_avtab_spec(specified);
1694 	avkey.source_type = stype + 1;
1695 	avkey.target_type = ttype + 1;
1696 
1697 	cur = perms;
1698 	while (cur) {
1699 		uint32_t remapped_data =
1700 		    typemap ? typemap[cur->data - 1] : cur->data;
1701 		avkey.target_class = cur->tclass;
1702 
1703 		conflict = 0;
1704 		/* check to see if the expanded TE already exists --
1705 		 * either in the global scope or in another
1706 		 * conditional AV tab */
1707 		node = avtab_search_node(&p->te_avtab, &avkey);
1708 		if (node) {
1709 			conflict = 1;
1710 		} else {
1711 			node = avtab_search_node(&p->te_cond_avtab, &avkey);
1712 			if (node && node->parse_context != other) {
1713 				conflict = 2;
1714 			}
1715 		}
1716 
1717 		if (conflict) {
1718 			avdatump = &node->datum;
1719 			if (specified & AVRULE_TRANSITION) {
1720 				oldtype = avdatump->data;
1721 			} else if (specified & AVRULE_MEMBER) {
1722 				oldtype = avdatump->data;
1723 			} else if (specified & AVRULE_CHANGE) {
1724 				oldtype = avdatump->data;
1725 			}
1726 
1727 			if (oldtype == remapped_data) {
1728 				/* if the duplicate is inside the same scope (eg., unconditional
1729 				 * or in same conditional then ignore it */
1730 				if ((conflict == 1 && cond == NULL)
1731 				    || node->parse_context == cond)
1732 					return EXPAND_RULE_SUCCESS;
1733 				ERR(handle, "duplicate TE rule for %s %s:%s %s",
1734 				    p->p_type_val_to_name[avkey.source_type -
1735 							  1],
1736 				    p->p_type_val_to_name[avkey.target_type -
1737 							  1],
1738 				    p->p_class_val_to_name[avkey.target_class -
1739 							   1],
1740 				    p->p_type_val_to_name[oldtype - 1]);
1741 				return EXPAND_RULE_CONFLICT;
1742 			}
1743 			ERR(handle,
1744 			    "conflicting TE rule for (%s, %s:%s):  old was %s, new is %s",
1745 			    p->p_type_val_to_name[avkey.source_type - 1],
1746 			    p->p_type_val_to_name[avkey.target_type - 1],
1747 			    p->p_class_val_to_name[avkey.target_class - 1],
1748 			    p->p_type_val_to_name[oldtype - 1],
1749 			    p->p_type_val_to_name[remapped_data - 1]);
1750 			return EXPAND_RULE_CONFLICT;
1751 		}
1752 
1753 		node = find_avtab_node(handle, avtab, &avkey, cond, NULL);
1754 		if (!node)
1755 			return -1;
1756 		if (enabled) {
1757 			node->key.specified |= AVTAB_ENABLED;
1758 		} else {
1759 			node->key.specified &= ~AVTAB_ENABLED;
1760 		}
1761 
1762 		avdatump = &node->datum;
1763 		avdatump->data = remapped_data;
1764 
1765 		cur = cur->next;
1766 	}
1767 
1768 	return EXPAND_RULE_SUCCESS;
1769 }
1770 
1771 /* 0 for success -1 indicates failure */
allocate_xperms(sepol_handle_t * handle,avtab_datum_t * avdatump,av_extended_perms_t * extended_perms)1772 static int allocate_xperms(sepol_handle_t * handle, avtab_datum_t * avdatump,
1773 			   av_extended_perms_t * extended_perms)
1774 {
1775 	unsigned int i;
1776 
1777 	avtab_extended_perms_t *xperms = avdatump->xperms;
1778 	if (!xperms) {
1779 		xperms = (avtab_extended_perms_t *)
1780 			calloc(1, sizeof(avtab_extended_perms_t));
1781 		if (!xperms) {
1782 			ERR(handle, "Out of memory!");
1783 			return -1;
1784 		}
1785 		avdatump->xperms = xperms;
1786 	}
1787 
1788 	switch (extended_perms->specified) {
1789 	case AVRULE_XPERMS_IOCTLFUNCTION:
1790 		xperms->specified = AVTAB_XPERMS_IOCTLFUNCTION;
1791 		break;
1792 	case AVRULE_XPERMS_IOCTLDRIVER:
1793 		xperms->specified = AVTAB_XPERMS_IOCTLDRIVER;
1794 		break;
1795 	default:
1796 		return -1;
1797 	}
1798 
1799 	xperms->driver = extended_perms->driver;
1800 	for (i = 0; i < ARRAY_SIZE(xperms->perms); i++)
1801 		xperms->perms[i] |= extended_perms->perms[i];
1802 
1803 	return 0;
1804 }
1805 
expand_avrule_helper(sepol_handle_t * handle,uint32_t specified,cond_av_list_t ** cond,uint32_t stype,uint32_t ttype,class_perm_node_t * perms,avtab_t * avtab,int enabled,av_extended_perms_t * extended_perms)1806 static int expand_avrule_helper(sepol_handle_t * handle,
1807 				uint32_t specified,
1808 				cond_av_list_t ** cond,
1809 				uint32_t stype, uint32_t ttype,
1810 				class_perm_node_t * perms, avtab_t * avtab,
1811 				int enabled, av_extended_perms_t *extended_perms)
1812 {
1813 	avtab_key_t avkey;
1814 	avtab_datum_t *avdatump;
1815 	avtab_ptr_t node;
1816 	class_perm_node_t *cur;
1817 
1818 	/* bail early if dontaudit's are disabled and it's a dontaudit rule */
1819 	if ((specified & (AVRULE_DONTAUDIT|AVRULE_XPERMS_DONTAUDIT))
1820 	     && handle && handle->disable_dontaudit)
1821 			return EXPAND_RULE_SUCCESS;
1822 
1823 	avkey.source_type = stype + 1;
1824 	avkey.target_type = ttype + 1;
1825 	avkey.specified = avrule_to_avtab_spec(specified);
1826 
1827 	cur = perms;
1828 	while (cur) {
1829 		avkey.target_class = cur->tclass;
1830 
1831 		node = find_avtab_node(handle, avtab, &avkey, cond, extended_perms);
1832 		if (!node)
1833 			return EXPAND_RULE_ERROR;
1834 		if (enabled) {
1835 			node->key.specified |= AVTAB_ENABLED;
1836 		} else {
1837 			node->key.specified &= ~AVTAB_ENABLED;
1838 		}
1839 
1840 		avdatump = &node->datum;
1841 		switch (specified) {
1842 		case AVRULE_ALLOWED:
1843 		case AVRULE_AUDITALLOW:
1844 		case AVRULE_NEVERALLOW:
1845 			avdatump->data |= cur->data;
1846 			break;
1847 		case AVRULE_DONTAUDIT:
1848 			avdatump->data &= ~cur->data;
1849 			break;
1850 		case AVRULE_AUDITDENY:
1851 			/* Since a '0' in an auditdeny mask represents
1852 			 * a permission we do NOT want to audit
1853 			 * (dontaudit), we use the '&' operand to
1854 			 * ensure that all '0's in the mask are
1855 			 * retained (much unlike the allow and
1856 			 * auditallow cases).
1857 			 */
1858 			avdatump->data &= cur->data;
1859 			break;
1860 		case AVRULE_XPERMS_ALLOWED:
1861 		case AVRULE_XPERMS_AUDITALLOW:
1862 		case AVRULE_XPERMS_DONTAUDIT:
1863 		case AVRULE_XPERMS_NEVERALLOW:
1864 			if (allocate_xperms(handle, avdatump, extended_perms))
1865 				return EXPAND_RULE_ERROR;
1866 			break;
1867 		default:
1868 			ERR(handle, "Unknown specification: %"PRIu32"\n", specified);
1869 			return EXPAND_RULE_ERROR;
1870 		}
1871 
1872 		cur = cur->next;
1873 	}
1874 	return EXPAND_RULE_SUCCESS;
1875 }
1876 
expand_rule_helper(sepol_handle_t * handle,policydb_t * p,uint32_t * typemap,avrule_t * source_rule,avtab_t * dest_avtab,cond_av_list_t ** cond,cond_av_list_t ** other,int enabled,ebitmap_t * stypes,ebitmap_t * ttypes)1877 static int expand_rule_helper(sepol_handle_t * handle,
1878 			      policydb_t * p, uint32_t * typemap,
1879 			      avrule_t * source_rule, avtab_t * dest_avtab,
1880 			      cond_av_list_t ** cond, cond_av_list_t ** other,
1881 			      int enabled,
1882 			      ebitmap_t * stypes, ebitmap_t * ttypes)
1883 {
1884 	unsigned int i, j;
1885 	int retval;
1886 	ebitmap_node_t *snode, *tnode;
1887 
1888 	ebitmap_for_each_positive_bit(stypes, snode, i) {
1889 		if (source_rule->flags & RULE_SELF) {
1890 			if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) {
1891 				retval = expand_avrule_helper(handle, source_rule->specified,
1892 							      cond, i, i, source_rule->perms,
1893 							      dest_avtab, enabled, source_rule->xperms);
1894 				if (retval != EXPAND_RULE_SUCCESS)
1895 					return retval;
1896 			} else {
1897 				retval = expand_terule_helper(handle, p, typemap,
1898 							      source_rule->specified, cond,
1899 							      other, i, i, source_rule->perms,
1900 							      dest_avtab, enabled);
1901 				if (retval != EXPAND_RULE_SUCCESS)
1902 					return retval;
1903 			}
1904 		}
1905 		ebitmap_for_each_positive_bit(ttypes, tnode, j) {
1906 			if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) {
1907 				retval = expand_avrule_helper(handle, source_rule->specified,
1908 							      cond, i, j, source_rule->perms,
1909 							      dest_avtab, enabled, source_rule->xperms);
1910 				if (retval != EXPAND_RULE_SUCCESS)
1911 					return retval;
1912 			} else {
1913 				retval = expand_terule_helper(handle, p, typemap,
1914 							      source_rule->specified, cond,
1915 							      other, i, j, source_rule->perms,
1916 							      dest_avtab, enabled);
1917 				if (retval != EXPAND_RULE_SUCCESS)
1918 					return retval;
1919 			}
1920 		}
1921 	}
1922 
1923 	return EXPAND_RULE_SUCCESS;
1924 }
1925 
1926 /*
1927  * Expand a rule into a given avtab - checking for conflicting type
1928  * rules in the destination policy.  Return EXPAND_RULE_SUCCESS on
1929  * success, EXPAND_RULE_CONFLICT if the rule conflicts with something
1930  * (and hence was not added), or EXPAND_RULE_ERROR on error.
1931  */
convert_and_expand_rule(sepol_handle_t * handle,policydb_t * dest_pol,uint32_t * typemap,avrule_t * source_rule,avtab_t * dest_avtab,cond_av_list_t ** cond,cond_av_list_t ** other,int enabled,int do_neverallow)1932 static int convert_and_expand_rule(sepol_handle_t * handle,
1933 				   policydb_t * dest_pol, uint32_t * typemap,
1934 				   avrule_t * source_rule, avtab_t * dest_avtab,
1935 				   cond_av_list_t ** cond,
1936 				   cond_av_list_t ** other, int enabled,
1937 				   int do_neverallow)
1938 {
1939 	int retval;
1940 	ebitmap_t stypes, ttypes;
1941 	unsigned char alwaysexpand;
1942 
1943 	if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW)
1944 		return EXPAND_RULE_SUCCESS;
1945 	if (!do_neverallow && source_rule->specified & AVRULE_XPERMS_NEVERALLOW)
1946 		return EXPAND_RULE_SUCCESS;
1947 
1948 	ebitmap_init(&stypes);
1949 	ebitmap_init(&ttypes);
1950 
1951 	/* Force expansion for type rules and for self rules. */
1952 	alwaysexpand = ((source_rule->specified & AVRULE_TYPE) ||
1953 			(source_rule->flags & RULE_SELF));
1954 
1955 	if (expand_convert_type_set
1956 	    (dest_pol, typemap, &source_rule->stypes, &stypes, alwaysexpand))
1957 		return EXPAND_RULE_ERROR;
1958 	if (expand_convert_type_set
1959 	    (dest_pol, typemap, &source_rule->ttypes, &ttypes, alwaysexpand))
1960 		return EXPAND_RULE_ERROR;
1961 
1962 	retval = expand_rule_helper(handle, dest_pol, typemap,
1963 				    source_rule, dest_avtab,
1964 				    cond, other, enabled, &stypes, &ttypes);
1965 	ebitmap_destroy(&stypes);
1966 	ebitmap_destroy(&ttypes);
1967 	return retval;
1968 }
1969 
cond_avrule_list_copy(policydb_t * dest_pol,avrule_t * source_rules,avtab_t * dest_avtab,cond_av_list_t ** list,cond_av_list_t ** other,uint32_t * typemap,int enabled,expand_state_t * state)1970 static int cond_avrule_list_copy(policydb_t * dest_pol, avrule_t * source_rules,
1971 				 avtab_t * dest_avtab, cond_av_list_t ** list,
1972 				 cond_av_list_t ** other, uint32_t * typemap,
1973 				 int enabled, expand_state_t * state)
1974 {
1975 	avrule_t *cur;
1976 
1977 	cur = source_rules;
1978 	while (cur) {
1979 		if (convert_and_expand_rule(state->handle, dest_pol,
1980 					    typemap, cur, dest_avtab,
1981 					    list, other, enabled,
1982 					    0) != EXPAND_RULE_SUCCESS) {
1983 			return -1;
1984 		}
1985 
1986 		cur = cur->next;
1987 	}
1988 
1989 	return 0;
1990 }
1991 
cond_node_map_bools(expand_state_t * state,cond_node_t * cn)1992 static int cond_node_map_bools(expand_state_t * state, cond_node_t * cn)
1993 {
1994 	cond_expr_t *cur;
1995 	unsigned int i;
1996 
1997 	cur = cn->expr;
1998 	while (cur) {
1999 		if (cur->bool)
2000 			cur->bool = state->boolmap[cur->bool - 1];
2001 		cur = cur->next;
2002 	}
2003 
2004 	for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++)
2005 		cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1];
2006 
2007 	if (cond_normalize_expr(state->out, cn)) {
2008 		ERR(state->handle, "Error while normalizing conditional");
2009 		return -1;
2010 	}
2011 
2012 	return 0;
2013 }
2014 
2015 /* copy the nodes in *reverse* order -- the result is that the last
2016  * given conditional appears first in the policy, so as to match the
2017  * behavior of the upstream compiler */
cond_node_copy(expand_state_t * state,cond_node_t * cn)2018 static int cond_node_copy(expand_state_t * state, cond_node_t * cn)
2019 {
2020 	cond_node_t *new_cond, *tmp;
2021 
2022 	if (cn == NULL) {
2023 		return 0;
2024 	}
2025 	if (cond_node_copy(state, cn->next)) {
2026 		return -1;
2027 	}
2028 
2029 	/* If current cond_node_t is of tunable, its effective branch
2030 	 * has been appended to its home decl->avrules list during link
2031 	 * and now we should just skip it. */
2032 	if (cn->flags & COND_NODE_FLAGS_TUNABLE)
2033 		return 0;
2034 
2035 	if (cond_normalize_expr(state->base, cn)) {
2036 		ERR(state->handle, "Error while normalizing conditional");
2037 		return -1;
2038 	}
2039 
2040 	/* create a new temporary conditional node with the booleans
2041 	 * mapped */
2042 	tmp = cond_node_create(state->base, cn);
2043 	if (!tmp) {
2044 		ERR(state->handle, "Out of memory");
2045 		return -1;
2046 	}
2047 
2048 	if (cond_node_map_bools(state, tmp)) {
2049 		cond_node_destroy(tmp);
2050 		free(tmp);
2051 		ERR(state->handle, "Error mapping booleans");
2052 		return -1;
2053 	}
2054 
2055 	new_cond = cond_node_search(state->out, state->out->cond_list, tmp);
2056 	if (!new_cond) {
2057 		cond_node_destroy(tmp);
2058 		free(tmp);
2059 		ERR(state->handle, "Out of memory!");
2060 		return -1;
2061 	}
2062 	cond_node_destroy(tmp);
2063 	free(tmp);
2064 
2065 	if (cond_avrule_list_copy
2066 	    (state->out, cn->avtrue_list, &state->out->te_cond_avtab,
2067 	     &new_cond->true_list, &new_cond->false_list, state->typemap,
2068 	     new_cond->cur_state, state))
2069 		return -1;
2070 	if (cond_avrule_list_copy
2071 	    (state->out, cn->avfalse_list, &state->out->te_cond_avtab,
2072 	     &new_cond->false_list, &new_cond->true_list, state->typemap,
2073 	     !new_cond->cur_state, state))
2074 		return -1;
2075 
2076 	return 0;
2077 }
2078 
context_copy(context_struct_t * dst,context_struct_t * src,expand_state_t * state)2079 static int context_copy(context_struct_t * dst, context_struct_t * src,
2080 			expand_state_t * state)
2081 {
2082 	dst->user = state->usermap[src->user - 1];
2083 	dst->role = state->rolemap[src->role - 1];
2084 	dst->type = state->typemap[src->type - 1];
2085 	return mls_context_cpy(dst, src);
2086 }
2087 
ocontext_copy_xen(expand_state_t * state)2088 static int ocontext_copy_xen(expand_state_t *state)
2089 {
2090 	unsigned int i;
2091 	ocontext_t *c, *n, *l;
2092 
2093 	for (i = 0; i < OCON_NUM; i++) {
2094 		l = NULL;
2095 		for (c = state->base->ocontexts[i]; c; c = c->next) {
2096 			if (i == OCON_XEN_ISID && !c->context[0].user) {
2097 				INFO(state->handle,
2098 				     "No context assigned to SID %s, omitting from policy",
2099 				     c->u.name);
2100 				continue;
2101 			}
2102 			n = malloc(sizeof(ocontext_t));
2103 			if (!n) {
2104 				ERR(state->handle, "Out of memory!");
2105 				return -1;
2106 			}
2107 			memset(n, 0, sizeof(ocontext_t));
2108 			if (l)
2109 				l->next = n;
2110 			else
2111 				state->out->ocontexts[i] = n;
2112 			l = n;
2113 			switch (i) {
2114 			case OCON_XEN_ISID:
2115 				n->sid[0] = c->sid[0];
2116 				break;
2117 			case OCON_XEN_PIRQ:
2118 				n->u.pirq = c->u.pirq;
2119 				break;
2120 			case OCON_XEN_IOPORT:
2121 				n->u.ioport.low_ioport = c->u.ioport.low_ioport;
2122 				n->u.ioport.high_ioport =
2123 					c->u.ioport.high_ioport;
2124 				break;
2125 			case OCON_XEN_IOMEM:
2126 				n->u.iomem.low_iomem  = c->u.iomem.low_iomem;
2127 				n->u.iomem.high_iomem = c->u.iomem.high_iomem;
2128 				break;
2129 			case OCON_XEN_PCIDEVICE:
2130 				n->u.device = c->u.device;
2131 				break;
2132 			case OCON_XEN_DEVICETREE:
2133 				n->u.name = strdup(c->u.name);
2134 				if (!n->u.name) {
2135 					ERR(state->handle, "Out of memory!");
2136 					return -1;
2137 				}
2138 				break;
2139 			default:
2140 				/* shouldn't get here */
2141 				ERR(state->handle, "Unknown ocontext");
2142 				return -1;
2143 			}
2144 			if (context_copy(&n->context[0], &c->context[0],
2145 				state)) {
2146 				ERR(state->handle, "Out of memory!");
2147 				return -1;
2148 			}
2149 		}
2150 	}
2151 	return 0;
2152 }
2153 
ocontext_copy_selinux(expand_state_t * state)2154 static int ocontext_copy_selinux(expand_state_t *state)
2155 {
2156 	unsigned int i, j;
2157 	ocontext_t *c, *n, *l;
2158 
2159 	for (i = 0; i < OCON_NUM; i++) {
2160 		l = NULL;
2161 		for (c = state->base->ocontexts[i]; c; c = c->next) {
2162 			if (i == OCON_ISID && !c->context[0].user) {
2163 				INFO(state->handle,
2164 				     "No context assigned to SID %s, omitting from policy",
2165 				     c->u.name);
2166 				continue;
2167 			}
2168 			n = malloc(sizeof(ocontext_t));
2169 			if (!n) {
2170 				ERR(state->handle, "Out of memory!");
2171 				return -1;
2172 			}
2173 			memset(n, 0, sizeof(ocontext_t));
2174 			if (l)
2175 				l->next = n;
2176 			else
2177 				state->out->ocontexts[i] = n;
2178 			l = n;
2179 			switch (i) {
2180 			case OCON_ISID:
2181 				n->sid[0] = c->sid[0];
2182 				break;
2183 			case OCON_FS:	/* FALLTHROUGH */
2184 			case OCON_NETIF:
2185 				n->u.name = strdup(c->u.name);
2186 				if (!n->u.name) {
2187 					ERR(state->handle, "Out of memory!");
2188 					return -1;
2189 				}
2190 				if (context_copy
2191 				    (&n->context[1], &c->context[1], state)) {
2192 					ERR(state->handle, "Out of memory!");
2193 					return -1;
2194 				}
2195 				break;
2196 			case OCON_IBPKEY:
2197 				n->u.ibpkey.subnet_prefix = c->u.ibpkey.subnet_prefix;
2198 
2199 				n->u.ibpkey.low_pkey = c->u.ibpkey.low_pkey;
2200 				n->u.ibpkey.high_pkey = c->u.ibpkey.high_pkey;
2201 			break;
2202 			case OCON_IBENDPORT:
2203 				n->u.ibendport.dev_name = strdup(c->u.ibendport.dev_name);
2204 				if (!n->u.ibendport.dev_name) {
2205 					ERR(state->handle, "Out of memory!");
2206 					return -1;
2207 				}
2208 				n->u.ibendport.port = c->u.ibendport.port;
2209 				break;
2210 			case OCON_PORT:
2211 				n->u.port.protocol = c->u.port.protocol;
2212 				n->u.port.low_port = c->u.port.low_port;
2213 				n->u.port.high_port = c->u.port.high_port;
2214 				break;
2215 			case OCON_NODE:
2216 				n->u.node.addr = c->u.node.addr;
2217 				n->u.node.mask = c->u.node.mask;
2218 				break;
2219 			case OCON_FSUSE:
2220 				n->v.behavior = c->v.behavior;
2221 				n->u.name = strdup(c->u.name);
2222 				if (!n->u.name) {
2223 					ERR(state->handle, "Out of memory!");
2224 					return -1;
2225 				}
2226 				break;
2227 			case OCON_NODE6:
2228 				for (j = 0; j < 4; j++)
2229 					n->u.node6.addr[j] = c->u.node6.addr[j];
2230 				for (j = 0; j < 4; j++)
2231 					n->u.node6.mask[j] = c->u.node6.mask[j];
2232 				break;
2233 			default:
2234 				/* shouldn't get here */
2235 				ERR(state->handle, "Unknown ocontext");
2236 				return -1;
2237 			}
2238 			if (context_copy(&n->context[0], &c->context[0], state)) {
2239 				ERR(state->handle, "Out of memory!");
2240 				return -1;
2241 			}
2242 		}
2243 	}
2244 	return 0;
2245 }
2246 
ocontext_copy(expand_state_t * state,uint32_t target)2247 static int ocontext_copy(expand_state_t *state, uint32_t target)
2248 {
2249 	int rc = -1;
2250 	switch (target) {
2251 	case SEPOL_TARGET_SELINUX:
2252 		rc = ocontext_copy_selinux(state);
2253 		break;
2254 	case SEPOL_TARGET_XEN:
2255 		rc = ocontext_copy_xen(state);
2256 		break;
2257 	default:
2258 		ERR(state->handle, "Unknown target");
2259 		return -1;
2260 	}
2261 	return rc;
2262 }
2263 
genfs_copy(expand_state_t * state)2264 static int genfs_copy(expand_state_t * state)
2265 {
2266 	ocontext_t *c, *newc, *l;
2267 	genfs_t *genfs, *newgenfs, *end;
2268 
2269 	end = NULL;
2270 	for (genfs = state->base->genfs; genfs; genfs = genfs->next) {
2271 		newgenfs = malloc(sizeof(genfs_t));
2272 		if (!newgenfs) {
2273 			ERR(state->handle, "Out of memory!");
2274 			return -1;
2275 		}
2276 		memset(newgenfs, 0, sizeof(genfs_t));
2277 		newgenfs->fstype = strdup(genfs->fstype);
2278 		if (!newgenfs->fstype) {
2279 			free(newgenfs);
2280 			ERR(state->handle, "Out of memory!");
2281 			return -1;
2282 		}
2283 		if (!end)
2284 			state->out->genfs = newgenfs;
2285 		else
2286 			end->next = newgenfs;
2287 		end = newgenfs;
2288 
2289 		l = NULL;
2290 		for (c = genfs->head; c; c = c->next) {
2291 			newc = malloc(sizeof(ocontext_t));
2292 			if (!newc) {
2293 				ERR(state->handle, "Out of memory!");
2294 				return -1;
2295 			}
2296 			memset(newc, 0, sizeof(ocontext_t));
2297 			newc->u.name = strdup(c->u.name);
2298 			if (!newc->u.name) {
2299 				ERR(state->handle, "Out of memory!");
2300 				free(newc);
2301 				return -1;
2302 			}
2303 			newc->v.sclass = c->v.sclass;
2304 			context_copy(&newc->context[0], &c->context[0], state);
2305 			if (l)
2306 				l->next = newc;
2307 			else
2308 				newgenfs->head = newc;
2309 			l = newc;
2310 		}
2311 	}
2312 	return 0;
2313 }
2314 
type_attr_map(hashtab_key_t key,hashtab_datum_t datum,void * ptr)2315 static int type_attr_map(hashtab_key_t key
2316 			 __attribute__ ((unused)), hashtab_datum_t datum,
2317 			 void *ptr)
2318 {
2319 	type_datum_t *type;
2320 	expand_state_t *state = ptr;
2321 	policydb_t *p = state->out;
2322 	unsigned int i;
2323 	ebitmap_node_t *tnode;
2324 	int value;
2325 
2326 	type = (type_datum_t *) datum;
2327 	value = type->s.value;
2328 
2329 	if (type->flavor == TYPE_ATTRIB) {
2330 		if (!(type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE)) {
2331 			if (ebitmap_cpy(&p->attr_type_map[value - 1], &type->types)) {
2332 				goto oom;
2333 			}
2334 			ebitmap_for_each_positive_bit(&type->types, tnode, i) {
2335 				if (ebitmap_set_bit(&p->type_attr_map[i], value - 1, 1)) {
2336 					goto oom;
2337 				}
2338 			}
2339 		} else {
2340 			/* Attribute is being expanded, so remove */
2341 			if (ebitmap_set_bit(&p->type_attr_map[value - 1], value - 1, 0)) {
2342 				goto oom;
2343 			}
2344 		}
2345 	} else {
2346 		if (ebitmap_set_bit(&p->attr_type_map[value - 1], value - 1, 1)) {
2347 			goto oom;
2348 		}
2349 	}
2350 
2351 	return 0;
2352 
2353 oom:
2354 	ERR(state->handle, "Out of memory!");
2355 	return -1;
2356 }
2357 
2358 /* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy.
2359  * this should not be called until after all the blocks have been processed and the attributes in target policy
2360  * are complete. */
expand_convert_type_set(policydb_t * p,uint32_t * typemap,type_set_t * set,ebitmap_t * types,unsigned char alwaysexpand)2361 int expand_convert_type_set(policydb_t * p, uint32_t * typemap,
2362 			    type_set_t * set, ebitmap_t * types,
2363 			    unsigned char alwaysexpand)
2364 {
2365 	type_set_t tmpset;
2366 
2367 	type_set_init(&tmpset);
2368 
2369 	if (map_ebitmap(&set->types, &tmpset.types, typemap))
2370 		return -1;
2371 
2372 	if (map_ebitmap(&set->negset, &tmpset.negset, typemap))
2373 		return -1;
2374 
2375 	tmpset.flags = set->flags;
2376 
2377 	if (type_set_expand(&tmpset, types, p, alwaysexpand))
2378 		return -1;
2379 
2380 	type_set_destroy(&tmpset);
2381 
2382 	return 0;
2383 }
2384 
2385 /* Expand a rule into a given avtab - checking for conflicting type
2386  * rules.  Return 1 on success, 0 if the rule conflicts with something
2387  * (and hence was not added), or -1 on error. */
expand_rule(sepol_handle_t * handle,policydb_t * source_pol,avrule_t * source_rule,avtab_t * dest_avtab,cond_av_list_t ** cond,cond_av_list_t ** other,int enabled)2388 int expand_rule(sepol_handle_t * handle,
2389 		policydb_t * source_pol,
2390 		avrule_t * source_rule, avtab_t * dest_avtab,
2391 		cond_av_list_t ** cond, cond_av_list_t ** other, int enabled)
2392 {
2393 	int retval;
2394 	ebitmap_t stypes, ttypes;
2395 
2396 	if ((source_rule->specified & AVRULE_NEVERALLOW)
2397 		|| (source_rule->specified & AVRULE_XPERMS_NEVERALLOW))
2398 		return 1;
2399 
2400 	ebitmap_init(&stypes);
2401 	ebitmap_init(&ttypes);
2402 
2403 	if (type_set_expand(&source_rule->stypes, &stypes, source_pol, 1))
2404 		return -1;
2405 	if (type_set_expand(&source_rule->ttypes, &ttypes, source_pol, 1))
2406 		return -1;
2407 	retval = expand_rule_helper(handle, source_pol, NULL,
2408 				    source_rule, dest_avtab,
2409 				    cond, other, enabled, &stypes, &ttypes);
2410 	ebitmap_destroy(&stypes);
2411 	ebitmap_destroy(&ttypes);
2412 	return retval;
2413 }
2414 
2415 /* Expand a role set into an ebitmap containing the roles.
2416  * This handles the attribute and flags.
2417  * Attribute expansion depends on if the rolemap is available.
2418  * During module compile the rolemap is not available, the
2419  * possible duplicates of a regular role and the role attribute
2420  * the regular role belongs to could be properly handled by
2421  * copy_role_trans and copy_role_allow.
2422  */
role_set_expand(role_set_t * x,ebitmap_t * r,policydb_t * out,policydb_t * base,uint32_t * rolemap)2423 int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap)
2424 {
2425 	unsigned int i;
2426 	ebitmap_node_t *rnode;
2427 	ebitmap_t mapped_roles, roles;
2428 	policydb_t *p = out;
2429 	role_datum_t *role;
2430 
2431 	ebitmap_init(r);
2432 
2433 	if (x->flags & ROLE_STAR) {
2434 		for (i = 0; i < p->p_roles.nprim; i++)
2435 			if (ebitmap_set_bit(r, i, 1))
2436 				return -1;
2437 		return 0;
2438 	}
2439 
2440 	ebitmap_init(&mapped_roles);
2441 	ebitmap_init(&roles);
2442 
2443 	if (rolemap) {
2444 		assert(base != NULL);
2445 		ebitmap_for_each_positive_bit(&x->roles, rnode, i) {
2446 			/* take advantage of p_role_val_to_struct[]
2447 			 * of the base module */
2448 			role = base->role_val_to_struct[i];
2449 			assert(role != NULL);
2450 			if (role->flavor == ROLE_ATTRIB) {
2451 				if (ebitmap_union(&roles,
2452 						  &role->roles))
2453 					goto bad;
2454 			} else {
2455 				if (ebitmap_set_bit(&roles, i, 1))
2456 					goto bad;
2457 			}
2458 		}
2459 		if (map_ebitmap(&roles, &mapped_roles, rolemap))
2460 			goto bad;
2461 	} else {
2462 		if (ebitmap_cpy(&mapped_roles, &x->roles))
2463 			goto bad;
2464 	}
2465 
2466 	ebitmap_for_each_positive_bit(&mapped_roles, rnode, i) {
2467 		if (ebitmap_set_bit(r, i, 1))
2468 			goto bad;
2469 	}
2470 
2471 	ebitmap_destroy(&mapped_roles);
2472 	ebitmap_destroy(&roles);
2473 
2474 	/* if role is to be complimented, invert the entire bitmap here */
2475 	if (x->flags & ROLE_COMP) {
2476 		for (i = 0; i < ebitmap_length(r); i++) {
2477 			if (ebitmap_get_bit(r, i)) {
2478 				if (ebitmap_set_bit(r, i, 0))
2479 					return -1;
2480 			} else {
2481 				if (ebitmap_set_bit(r, i, 1))
2482 					return -1;
2483 			}
2484 		}
2485 	}
2486 	return 0;
2487 
2488 bad:
2489 	ebitmap_destroy(&mapped_roles);
2490 	ebitmap_destroy(&roles);
2491 	return -1;
2492 }
2493 
2494 /* Expand a type set into an ebitmap containing the types. This
2495  * handles the negset, attributes, and flags.
2496  * Attribute expansion depends on several factors:
2497  * - if alwaysexpand is 1, then they will be expanded,
2498  * - if the type set has a negset or flags, then they will be expanded,
2499  * - otherwise, they will not be expanded.
2500  */
type_set_expand(type_set_t * set,ebitmap_t * t,policydb_t * p,unsigned char alwaysexpand)2501 int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p,
2502 		    unsigned char alwaysexpand)
2503 {
2504 	unsigned int i;
2505 	ebitmap_t types, neg_types;
2506 	ebitmap_node_t *tnode;
2507 	unsigned char expand = alwaysexpand || ebitmap_length(&set->negset) || set->flags;
2508 	type_datum_t *type;
2509 	int rc =-1;
2510 
2511 	ebitmap_init(&types);
2512 	ebitmap_init(t);
2513 
2514 	/* First go through the types and OR all the attributes to types */
2515 	ebitmap_for_each_positive_bit(&set->types, tnode, i) {
2516 		/*
2517 		 * invalid policies might have more types set in the ebitmap than
2518 		 * what's available in the type_val_to_struct mapping
2519 		 */
2520 		if (i >= p->p_types.nprim)
2521 			goto err_types;
2522 
2523 		type = p->type_val_to_struct[i];
2524 
2525 		if (!type) {
2526 			goto err_types;
2527 		}
2528 
2529 		if (type->flavor == TYPE_ATTRIB &&
2530 		    (expand || (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE))) {
2531 			if (ebitmap_union(&types, &type->types)) {
2532 				goto err_types;
2533 			}
2534 		} else {
2535 			if (ebitmap_set_bit(&types, i, 1)) {
2536 				goto err_types;
2537 			}
2538 		}
2539 	}
2540 
2541 	/* Now do the same thing for negset */
2542 	ebitmap_init(&neg_types);
2543 	ebitmap_for_each_positive_bit(&set->negset, tnode, i) {
2544 		if (p->type_val_to_struct[i] &&
2545 		    p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) {
2546 			if (ebitmap_union
2547 			    (&neg_types,
2548 			     &p->type_val_to_struct[i]->types)) {
2549 				goto err_neg;
2550 			}
2551 		} else {
2552 			if (ebitmap_set_bit(&neg_types, i, 1)) {
2553 				goto err_neg;
2554 			}
2555 		}
2556 	}
2557 
2558 	if (set->flags & TYPE_STAR) {
2559 		/* set all types not in neg_types */
2560 		for (i = 0; i < p->p_types.nprim; i++) {
2561 			if (ebitmap_get_bit(&neg_types, i))
2562 				continue;
2563 			if (p->type_val_to_struct[i] &&
2564 			    p->type_val_to_struct[i]->flavor == TYPE_ATTRIB)
2565 				continue;
2566 			if (ebitmap_set_bit(t, i, 1))
2567 				goto err_neg;
2568 		}
2569 		goto out;
2570 	}
2571 
2572 	ebitmap_for_each_positive_bit(&types, tnode, i) {
2573 		if (!ebitmap_get_bit(&neg_types, i))
2574 			if (ebitmap_set_bit(t, i, 1))
2575 				goto err_neg;
2576 	}
2577 
2578 	if (set->flags & TYPE_COMP) {
2579 		for (i = 0; i < p->p_types.nprim; i++) {
2580 			if (p->type_val_to_struct[i] &&
2581 			    p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) {
2582 				assert(!ebitmap_get_bit(t, i));
2583 				continue;
2584 			}
2585 			if (ebitmap_get_bit(t, i)) {
2586 				if (ebitmap_set_bit(t, i, 0))
2587 					goto err_neg;
2588 			} else {
2589 				if (ebitmap_set_bit(t, i, 1))
2590 					goto err_neg;
2591 			}
2592 		}
2593 	}
2594 
2595 	  out:
2596 	rc = 0;
2597 
2598 	  err_neg:
2599 	ebitmap_destroy(&neg_types);
2600 	  err_types:
2601 	ebitmap_destroy(&types);
2602 
2603 	return rc;
2604 }
2605 
copy_neverallow(policydb_t * dest_pol,uint32_t * typemap,avrule_t * source_rule)2606 static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap,
2607 			   avrule_t * source_rule)
2608 {
2609 	ebitmap_t stypes, ttypes;
2610 	avrule_t *avrule;
2611 	class_perm_node_t *cur_perm, *new_perm, *tail_perm;
2612 	av_extended_perms_t *xperms = NULL;
2613 
2614 	ebitmap_init(&stypes);
2615 	ebitmap_init(&ttypes);
2616 
2617 	if (expand_convert_type_set
2618 	    (dest_pol, typemap, &source_rule->stypes, &stypes, 1))
2619 		return -1;
2620 	if (expand_convert_type_set
2621 	    (dest_pol, typemap, &source_rule->ttypes, &ttypes, 1))
2622 		return -1;
2623 
2624 	avrule = (avrule_t *) malloc(sizeof(avrule_t));
2625 	if (!avrule)
2626 		return -1;
2627 
2628 	avrule_init(avrule);
2629 	avrule->specified = source_rule->specified;
2630 	avrule->line = source_rule->line;
2631 	avrule->flags = source_rule->flags;
2632 	avrule->source_line = source_rule->source_line;
2633 	if (source_rule->source_filename) {
2634 		avrule->source_filename = strdup(source_rule->source_filename);
2635 		if (!avrule->source_filename)
2636 			goto err;
2637 	}
2638 
2639 	if (ebitmap_cpy(&avrule->stypes.types, &stypes))
2640 		goto err;
2641 
2642 	if (ebitmap_cpy(&avrule->ttypes.types, &ttypes))
2643 		goto err;
2644 
2645 	cur_perm = source_rule->perms;
2646 	tail_perm = NULL;
2647 	while (cur_perm) {
2648 		new_perm =
2649 		    (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2650 		if (!new_perm)
2651 			goto err;
2652 		class_perm_node_init(new_perm);
2653 		new_perm->tclass = cur_perm->tclass;
2654 		assert(new_perm->tclass);
2655 
2656 		/* once we have modules with permissions we'll need to map the permissions (and classes) */
2657 		new_perm->data = cur_perm->data;
2658 
2659 		if (!avrule->perms)
2660 			avrule->perms = new_perm;
2661 
2662 		if (tail_perm)
2663 			tail_perm->next = new_perm;
2664 		tail_perm = new_perm;
2665 		cur_perm = cur_perm->next;
2666 	}
2667 
2668 	/* copy over extended permissions */
2669 	if (source_rule->xperms) {
2670 		xperms = calloc(1, sizeof(av_extended_perms_t));
2671 		if (!xperms)
2672 			goto err;
2673 		memcpy(xperms, source_rule->xperms, sizeof(av_extended_perms_t));
2674 		avrule->xperms = xperms;
2675 	}
2676 
2677 	/* just prepend the avrule to the first branch; it'll never be
2678 	   written to disk */
2679 	if (!dest_pol->global->branch_list->avrules)
2680 		dest_pol->global->branch_list->avrules = avrule;
2681 	else {
2682 		avrule->next = dest_pol->global->branch_list->avrules;
2683 		dest_pol->global->branch_list->avrules = avrule;
2684 	}
2685 
2686 	ebitmap_destroy(&stypes);
2687 	ebitmap_destroy(&ttypes);
2688 
2689 	return 0;
2690 
2691       err:
2692 	ebitmap_destroy(&stypes);
2693 	ebitmap_destroy(&ttypes);
2694 	ebitmap_destroy(&avrule->stypes.types);
2695 	ebitmap_destroy(&avrule->ttypes.types);
2696 	cur_perm = avrule->perms;
2697 	while (cur_perm) {
2698 		tail_perm = cur_perm->next;
2699 		free(cur_perm);
2700 		cur_perm = tail_perm;
2701 	}
2702 	free(xperms);
2703 	free(avrule);
2704 	return -1;
2705 }
2706 
2707 /*
2708  * Expands the avrule blocks for a policy. RBAC rules are copied. Neverallow
2709  * rules are copied or expanded as per the settings in the state object; all
2710  * other AV rules are expanded.  If neverallow rules are expanded, they are not
2711  * copied, otherwise they are copied for later use by the assertion checker.
2712  */
copy_and_expand_avrule_block(expand_state_t * state)2713 static int copy_and_expand_avrule_block(expand_state_t * state)
2714 {
2715 	avrule_block_t *curblock = state->base->global;
2716 	avrule_block_t *prevblock;
2717 	int retval = -1;
2718 
2719 	if (avtab_alloc(&state->out->te_avtab, MAX_AVTAB_SIZE)) {
2720  		ERR(state->handle, "Out of Memory!");
2721  		return -1;
2722  	}
2723 
2724  	if (avtab_alloc(&state->out->te_cond_avtab, MAX_AVTAB_SIZE)) {
2725  		ERR(state->handle, "Out of Memory!");
2726  		return -1;
2727  	}
2728 
2729 	while (curblock) {
2730 		avrule_decl_t *decl = curblock->enabled;
2731 		avrule_t *cur_avrule;
2732 
2733 		if (decl == NULL) {
2734 			/* nothing was enabled within this block */
2735 			goto cont;
2736 		}
2737 
2738 		/* copy role allows and role trans */
2739 		if (copy_role_allows(state, decl->role_allow_rules) != 0 ||
2740 		    copy_role_trans(state, decl->role_tr_rules) != 0) {
2741 			goto cleanup;
2742 		}
2743 
2744 		if (expand_filename_trans(state, decl->filename_trans_rules))
2745 			goto cleanup;
2746 
2747 		/* expand the range transition rules */
2748 		if (expand_range_trans(state, decl->range_tr_rules))
2749 			goto cleanup;
2750 
2751 		/* copy rules */
2752 		cur_avrule = decl->avrules;
2753 		while (cur_avrule != NULL) {
2754 			if (!(state->expand_neverallow)
2755 			    && cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)) {
2756 				/* copy this over directly so that assertions are checked later */
2757 				if (copy_neverallow
2758 				    (state->out, state->typemap, cur_avrule))
2759 					ERR(state->handle,
2760 					    "Error while copying neverallow.");
2761 			} else {
2762 				if (cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW))
2763 					state->out->unsupported_format = 1;
2764 				if (convert_and_expand_rule
2765 				    (state->handle, state->out, state->typemap,
2766 				     cur_avrule, &state->out->te_avtab, NULL,
2767 				     NULL, 0,
2768 				     state->expand_neverallow) !=
2769 				    EXPAND_RULE_SUCCESS) {
2770 					goto cleanup;
2771 				}
2772 			}
2773 			cur_avrule = cur_avrule->next;
2774 		}
2775 
2776 		/* copy conditional rules */
2777 		if (cond_node_copy(state, decl->cond_list))
2778 			goto cleanup;
2779 
2780       cont:
2781 		prevblock = curblock;
2782 		curblock = curblock->next;
2783 
2784 		if (state->handle && state->handle->expand_consume_base) {
2785 			/* set base top avrule block in case there
2786  			 * is an error condition and the policy needs
2787  			 * to be destroyed */
2788 			state->base->global = curblock;
2789 			avrule_block_destroy(prevblock);
2790 		}
2791 	}
2792 
2793 	retval = 0;
2794 
2795       cleanup:
2796 	return retval;
2797 }
2798 
2799 /*
2800  * This function allows external users of the library (such as setools) to
2801  * expand only the avrules and optionally perform expansion of neverallow rules
2802  * or expand into the same policy for analysis purposes.
2803  */
expand_module_avrules(sepol_handle_t * handle,policydb_t * base,policydb_t * out,uint32_t * typemap,uint32_t * boolmap,uint32_t * rolemap,uint32_t * usermap,int verbose,int expand_neverallow)2804 int expand_module_avrules(sepol_handle_t * handle, policydb_t * base,
2805 			  policydb_t * out, uint32_t * typemap,
2806 			  uint32_t * boolmap, uint32_t * rolemap,
2807 			  uint32_t * usermap, int verbose,
2808 			  int expand_neverallow)
2809 {
2810 	expand_state_t state;
2811 
2812 	expand_state_init(&state);
2813 
2814 	state.base = base;
2815 	state.out = out;
2816 	state.typemap = typemap;
2817 	state.boolmap = boolmap;
2818 	state.rolemap = rolemap;
2819 	state.usermap = usermap;
2820 	state.handle = handle;
2821 	state.verbose = verbose;
2822 	state.expand_neverallow = expand_neverallow;
2823 
2824 	return copy_and_expand_avrule_block(&state);
2825 }
2826 
discard_tunables(sepol_handle_t * sh,policydb_t * pol)2827 static void discard_tunables(sepol_handle_t *sh, policydb_t *pol)
2828 {
2829 	avrule_block_t *block;
2830 	avrule_decl_t *decl;
2831 	cond_node_t *cur_node;
2832 	cond_expr_t *cur_expr;
2833 	int cur_state, preserve_tunables = 0;
2834 	avrule_t *tail, *to_be_appended;
2835 
2836 	if (sh && sh->preserve_tunables)
2837 		preserve_tunables = 1;
2838 
2839 	/* Iterate through all cond_node of all enabled decls, if a cond_node
2840 	 * is about tunable, calculate its state value and concatenate one of
2841 	 * its avrule list to the current decl->avrules list. On the other
2842 	 * hand, the disabled unused branch of a tunable would be discarded.
2843 	 *
2844 	 * Note, such tunable cond_node would be skipped over in expansion,
2845 	 * so we won't have to worry about removing it from decl->cond_list
2846 	 * here :-)
2847 	 *
2848 	 * If tunables are requested to be preserved then they would be
2849 	 * "transformed" as booleans by having their TUNABLE flag cleared.
2850 	 */
2851 	for (block = pol->global; block != NULL; block = block->next) {
2852 		decl = block->enabled;
2853 		if (decl == NULL || decl->enabled == 0)
2854 			continue;
2855 
2856 		tail = decl->avrules;
2857 		while (tail && tail->next)
2858 			tail = tail->next;
2859 
2860 		for (cur_node = decl->cond_list; cur_node != NULL;
2861 		     cur_node = cur_node->next) {
2862 			int booleans, tunables, i;
2863 			cond_bool_datum_t *booldatum;
2864 			cond_bool_datum_t *tmp[COND_EXPR_MAXDEPTH];
2865 
2866 			booleans = tunables = 0;
2867 			memset(tmp, 0, sizeof(cond_bool_datum_t *) * COND_EXPR_MAXDEPTH);
2868 
2869 			for (cur_expr = cur_node->expr; cur_expr != NULL;
2870 			     cur_expr = cur_expr->next) {
2871 				if (cur_expr->expr_type != COND_BOOL)
2872 					continue;
2873 				booldatum = pol->bool_val_to_struct[cur_expr->bool - 1];
2874 				if (booldatum->flags & COND_BOOL_FLAGS_TUNABLE)
2875 					tmp[tunables++] = booldatum;
2876 				else
2877 					booleans++;
2878 			}
2879 
2880 			/* bool_copy_callback() at link phase has ensured
2881 			 * that no mixture of tunables and booleans in one
2882 			 * expression. However, this would be broken by the
2883 			 * request to preserve tunables */
2884 			if (!preserve_tunables)
2885 				assert(!(booleans && tunables));
2886 
2887 			if (booleans || preserve_tunables) {
2888 				cur_node->flags &= ~COND_NODE_FLAGS_TUNABLE;
2889 				if (tunables) {
2890 					for (i = 0; i < tunables; i++)
2891 						tmp[i]->flags &= ~COND_BOOL_FLAGS_TUNABLE;
2892 				}
2893 			} else {
2894 				cur_node->flags |= COND_NODE_FLAGS_TUNABLE;
2895 				cur_state = cond_evaluate_expr(pol, cur_node->expr);
2896 				if (cur_state == -1) {
2897 					printf("Expression result was "
2898 					       "undefined, skipping all"
2899 					       "rules\n");
2900 					continue;
2901 				}
2902 
2903 				to_be_appended = (cur_state == 1) ?
2904 					cur_node->avtrue_list : cur_node->avfalse_list;
2905 
2906 				if (tail)
2907 					tail->next = to_be_appended;
2908 				else
2909 					tail = decl->avrules = to_be_appended;
2910 
2911 				/* Now that the effective branch has been
2912 				 * appended, neutralize its original pointer */
2913 				if (cur_state == 1)
2914 					cur_node->avtrue_list = NULL;
2915 				else
2916 					cur_node->avfalse_list = NULL;
2917 
2918 				/* Update the tail of decl->avrules for
2919 				 * further concatenation */
2920 				while (tail && tail->next)
2921 					tail = tail->next;
2922 			}
2923 		}
2924 	}
2925 }
2926 
2927 /* Linking should always be done before calling expand, even if
2928  * there is only a base since all optionals are dealt with at link time
2929  * the base passed in should be indexed and avrule blocks should be
2930  * enabled.
2931  */
expand_module(sepol_handle_t * handle,policydb_t * base,policydb_t * out,int verbose,int check)2932 int expand_module(sepol_handle_t * handle,
2933 		  policydb_t * base, policydb_t * out, int verbose, int check)
2934 {
2935 	int retval = -1;
2936 	unsigned int i;
2937 	expand_state_t state;
2938 	avrule_block_t *curblock;
2939 
2940 	/* Append tunable's avtrue_list or avfalse_list to the avrules list
2941 	 * of its home decl depending on its state value, so that the effect
2942 	 * rules of a tunable would be added to te_avtab permanently. Whereas
2943 	 * the disabled unused branch would be discarded.
2944 	 *
2945 	 * Originally this function is called at the very end of link phase,
2946 	 * however, we need to keep the linked policy intact for analysis
2947 	 * purpose. */
2948 	discard_tunables(handle, base);
2949 
2950 	expand_state_init(&state);
2951 
2952 	state.verbose = verbose;
2953 	state.typemap = NULL;
2954 	state.base = base;
2955 	state.out = out;
2956 	state.handle = handle;
2957 
2958 	if (base->policy_type != POLICY_BASE) {
2959 		ERR(handle, "Target of expand was not a base policy.");
2960 		return -1;
2961 	}
2962 
2963 	state.out->policy_type = POLICY_KERN;
2964 	state.out->policyvers = POLICYDB_VERSION_MAX;
2965 
2966 	/* Copy mls state from base to out */
2967 	out->mls = base->mls;
2968 	out->handle_unknown = base->handle_unknown;
2969 
2970 	/* Copy target from base to out */
2971 	out->target_platform = base->target_platform;
2972 
2973 	/* Copy policy capabilities */
2974 	if (ebitmap_cpy(&out->policycaps, &base->policycaps)) {
2975 		ERR(handle, "Out of memory!");
2976 		goto cleanup;
2977 	}
2978 
2979 	if ((state.typemap =
2980 	     (uint32_t *) calloc(state.base->p_types.nprim,
2981 				 sizeof(uint32_t))) == NULL) {
2982 		ERR(handle, "Out of memory!");
2983 		goto cleanup;
2984 	}
2985 
2986 	state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t));
2987 	if (!state.boolmap) {
2988 		ERR(handle, "Out of memory!");
2989 		goto cleanup;
2990 	}
2991 
2992 	state.rolemap = (uint32_t *)calloc(state.base->p_roles.nprim, sizeof(uint32_t));
2993 	if (!state.rolemap) {
2994 		ERR(handle, "Out of memory!");
2995 		goto cleanup;
2996 	}
2997 
2998 	state.usermap = (uint32_t *)calloc(state.base->p_users.nprim, sizeof(uint32_t));
2999 	if (!state.usermap) {
3000 		ERR(handle, "Out of memory!");
3001 		goto cleanup;
3002 	}
3003 
3004 	/* order is important - types must be first */
3005 
3006 	/* copy types */
3007 	if (hashtab_map(state.base->p_types.table, type_copy_callback, &state)) {
3008 		goto cleanup;
3009 	}
3010 
3011 	/* convert attribute type sets */
3012 	if (hashtab_map
3013 	    (state.base->p_types.table, attr_convert_callback, &state)) {
3014 		goto cleanup;
3015 	}
3016 
3017 	/* copy commons */
3018 	if (hashtab_map
3019 	    (state.base->p_commons.table, common_copy_callback, &state)) {
3020 		goto cleanup;
3021 	}
3022 
3023 	/* copy classes, note, this does not copy constraints, constraints can't be
3024 	 * copied until after all the blocks have been processed and attributes are complete */
3025 	if (hashtab_map
3026 	    (state.base->p_classes.table, class_copy_callback, &state)) {
3027 		goto cleanup;
3028 	}
3029 
3030 	/* copy type bounds */
3031 	if (hashtab_map(state.base->p_types.table,
3032 			type_bounds_copy_callback, &state))
3033 		goto cleanup;
3034 
3035 	/* copy aliases */
3036 	if (hashtab_map(state.base->p_types.table, alias_copy_callback, &state))
3037 		goto cleanup;
3038 
3039 	/* index here so that type indexes are available for role_copy_callback */
3040 	if (policydb_index_others(handle, out, verbose)) {
3041 		ERR(handle, "Error while indexing out symbols");
3042 		goto cleanup;
3043 	}
3044 
3045 	/* copy roles */
3046 	if (hashtab_map(state.base->p_roles.table, role_copy_callback, &state))
3047 		goto cleanup;
3048 	if (hashtab_map(state.base->p_roles.table,
3049 			role_bounds_copy_callback, &state))
3050 		goto cleanup;
3051 	/* escalate the type_set_t in a role attribute to all regular roles
3052 	 * that belongs to it. */
3053 	if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state))
3054 		goto cleanup;
3055 
3056 	/* copy MLS's sensitivity level and categories - this needs to be done
3057 	 * before expanding users (they need to be indexed too) */
3058 	if (hashtab_map(state.base->p_levels.table, sens_copy_callback, &state))
3059 		goto cleanup;
3060 	if (hashtab_map(state.base->p_cats.table, cats_copy_callback, &state))
3061 		goto cleanup;
3062 	if (policydb_index_others(handle, out, verbose)) {
3063 		ERR(handle, "Error while indexing out symbols");
3064 		goto cleanup;
3065 	}
3066 
3067 	/* copy users */
3068 	if (hashtab_map(state.base->p_users.table, user_copy_callback, &state))
3069 		goto cleanup;
3070 	if (hashtab_map(state.base->p_users.table,
3071 			user_bounds_copy_callback, &state))
3072 		goto cleanup;
3073 
3074 	/* copy bools */
3075 	if (hashtab_map(state.base->p_bools.table, bool_copy_callback, &state))
3076 		goto cleanup;
3077 
3078 	if (policydb_index_classes(out)) {
3079 		ERR(handle, "Error while indexing out classes");
3080 		goto cleanup;
3081 	}
3082 	if (policydb_index_others(handle, out, verbose)) {
3083 		ERR(handle, "Error while indexing out symbols");
3084 		goto cleanup;
3085 	}
3086 
3087 	/* loop through all decls and union attributes, roles, users */
3088 	for (curblock = state.base->global; curblock != NULL;
3089 	     curblock = curblock->next) {
3090 		avrule_decl_t *decl = curblock->enabled;
3091 
3092 		if (decl == NULL) {
3093 			/* nothing was enabled within this block */
3094 			continue;
3095 		}
3096 
3097 		/* convert attribute type sets */
3098 		if (hashtab_map
3099 		    (decl->p_types.table, attr_convert_callback, &state)) {
3100 			goto cleanup;
3101 		}
3102 
3103 		/* copy roles */
3104 		if (hashtab_map
3105 		    (decl->p_roles.table, role_copy_callback, &state))
3106 			goto cleanup;
3107 
3108 		/* copy users */
3109 		if (hashtab_map
3110 		    (decl->p_users.table, user_copy_callback, &state))
3111 			goto cleanup;
3112 
3113 	}
3114 
3115 	/* remap role dominates bitmaps */
3116 	 if (hashtab_map(state.out->p_roles.table, role_remap_dominates, &state)) {
3117 		goto cleanup;
3118 	}
3119 
3120 	if (copy_and_expand_avrule_block(&state) < 0) {
3121 		ERR(handle, "Error during expand");
3122 		goto cleanup;
3123 	}
3124 
3125 	/* copy constraints */
3126 	if (hashtab_map
3127 	    (state.base->p_classes.table, constraint_copy_callback, &state)) {
3128 		goto cleanup;
3129 	}
3130 
3131 	cond_optimize_lists(state.out->cond_list);
3132 	if (evaluate_conds(state.out))
3133 		goto cleanup;
3134 
3135 	/* copy ocontexts */
3136 	if (ocontext_copy(&state, out->target_platform))
3137 		goto cleanup;
3138 
3139 	/* copy genfs */
3140 	if (genfs_copy(&state))
3141 		goto cleanup;
3142 
3143 	/* Build the type<->attribute maps and remove attributes. */
3144 	state.out->attr_type_map = malloc(state.out->p_types.nprim *
3145 					  sizeof(ebitmap_t));
3146 	state.out->type_attr_map = malloc(state.out->p_types.nprim *
3147 					  sizeof(ebitmap_t));
3148 	if (!state.out->attr_type_map || !state.out->type_attr_map) {
3149 		ERR(handle, "Out of memory!");
3150 		goto cleanup;
3151 	}
3152 	for (i = 0; i < state.out->p_types.nprim; i++) {
3153 		ebitmap_init(&state.out->type_attr_map[i]);
3154 		ebitmap_init(&state.out->attr_type_map[i]);
3155 		/* add the type itself as the degenerate case */
3156 		if (ebitmap_set_bit(&state.out->type_attr_map[i], i, 1)) {
3157 			ERR(handle, "Out of memory!");
3158 			goto cleanup;
3159 		}
3160 	}
3161 	if (hashtab_map(state.out->p_types.table, type_attr_map, &state))
3162 		goto cleanup;
3163 	if (check) {
3164 		if (hierarchy_check_constraints(handle, state.out))
3165 			goto cleanup;
3166 
3167 		if (check_assertions
3168 		    (handle, state.out,
3169 		     state.out->global->branch_list->avrules))
3170 			 goto cleanup;
3171 	}
3172 
3173 	retval = 0;
3174 
3175       cleanup:
3176 	free(state.typemap);
3177 	free(state.boolmap);
3178 	free(state.rolemap);
3179 	free(state.usermap);
3180 	return retval;
3181 }
3182 
expand_avtab_insert(avtab_t * a,avtab_key_t * k,avtab_datum_t * d)3183 static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d)
3184 {
3185 	avtab_ptr_t node;
3186 	avtab_datum_t *avd;
3187 	avtab_extended_perms_t *xperms;
3188 	unsigned int i;
3189 	unsigned int match = 0;
3190 
3191 	if (k->specified & AVTAB_XPERMS) {
3192 		/*
3193 		 * AVTAB_XPERMS entries are not necessarily unique.
3194 		 * find node with matching xperms
3195 		 */
3196 		node = avtab_search_node(a, k);
3197 		while (node) {
3198 			if ((node->datum.xperms->specified == d->xperms->specified) &&
3199 				(node->datum.xperms->driver == d->xperms->driver)) {
3200 				match = 1;
3201 				break;
3202 			}
3203 			node = avtab_search_node_next(node, k->specified);
3204 		}
3205 		if (!match)
3206 			node = NULL;
3207 	} else {
3208 		node = avtab_search_node(a, k);
3209 	}
3210 
3211 	if (!node || ((k->specified & AVTAB_ENABLED) !=
3212 			(node->key.specified & AVTAB_ENABLED))) {
3213 		node = avtab_insert_nonunique(a, k, d);
3214 		if (!node) {
3215 			ERR(NULL, "Out of memory!");
3216 			return -1;
3217 		}
3218 		return 0;
3219 	}
3220 
3221 	avd = &node->datum;
3222 	xperms = node->datum.xperms;
3223 	switch (k->specified & ~AVTAB_ENABLED) {
3224 	case AVTAB_ALLOWED:
3225 	case AVTAB_AUDITALLOW:
3226 		avd->data |= d->data;
3227 		break;
3228 	case AVTAB_AUDITDENY:
3229 		avd->data &= d->data;
3230 		break;
3231 	case AVTAB_XPERMS_ALLOWED:
3232 	case AVTAB_XPERMS_AUDITALLOW:
3233 	case AVTAB_XPERMS_DONTAUDIT:
3234 		for (i = 0; i < ARRAY_SIZE(xperms->perms); i++)
3235 			xperms->perms[i] |= d->xperms->perms[i];
3236 		break;
3237 	default:
3238 		ERR(NULL, "Type conflict!");
3239 		return -1;
3240 	}
3241 
3242 	return 0;
3243 }
3244 
3245 struct expand_avtab_data {
3246 	avtab_t *expa;
3247 	policydb_t *p;
3248 
3249 };
3250 
expand_avtab_node(avtab_key_t * k,avtab_datum_t * d,void * args)3251 static int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args)
3252 {
3253 	struct expand_avtab_data *ptr = args;
3254 	avtab_t *expa = ptr->expa;
3255 	policydb_t *p = ptr->p;
3256 	type_datum_t *stype = p->type_val_to_struct[k->source_type - 1];
3257 	type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1];
3258 	ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1];
3259 	ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1];
3260 	ebitmap_node_t *snode, *tnode;
3261 	unsigned int i, j;
3262 	avtab_key_t newkey;
3263 	int rc;
3264 
3265 	newkey.target_class = k->target_class;
3266 	newkey.specified = k->specified;
3267 
3268 	if (stype && ttype && stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) {
3269 		/* Both are individual types, no expansion required. */
3270 		return expand_avtab_insert(expa, k, d);
3271 	}
3272 
3273 	if (stype && stype->flavor != TYPE_ATTRIB) {
3274 		/* Source is an individual type, target is an attribute. */
3275 		newkey.source_type = k->source_type;
3276 		ebitmap_for_each_positive_bit(tattr, tnode, j) {
3277 			newkey.target_type = j + 1;
3278 			rc = expand_avtab_insert(expa, &newkey, d);
3279 			if (rc)
3280 				return -1;
3281 		}
3282 		return 0;
3283 	}
3284 
3285 	if (ttype && ttype->flavor != TYPE_ATTRIB) {
3286 		/* Target is an individual type, source is an attribute. */
3287 		newkey.target_type = k->target_type;
3288 		ebitmap_for_each_positive_bit(sattr, snode, i) {
3289 			newkey.source_type = i + 1;
3290 			rc = expand_avtab_insert(expa, &newkey, d);
3291 			if (rc)
3292 				return -1;
3293 		}
3294 		return 0;
3295 	}
3296 
3297 	/* Both source and target type are attributes. */
3298 	ebitmap_for_each_positive_bit(sattr, snode, i) {
3299 		ebitmap_for_each_positive_bit(tattr, tnode, j) {
3300 			newkey.source_type = i + 1;
3301 			newkey.target_type = j + 1;
3302 			rc = expand_avtab_insert(expa, &newkey, d);
3303 			if (rc)
3304 				return -1;
3305 		}
3306 	}
3307 
3308 	return 0;
3309 }
3310 
expand_avtab(policydb_t * p,avtab_t * a,avtab_t * expa)3311 int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa)
3312 {
3313 	struct expand_avtab_data data;
3314 
3315 	if (avtab_alloc(expa, MAX_AVTAB_SIZE)) {
3316 		ERR(NULL, "Out of memory!");
3317 		return -1;
3318 	}
3319 
3320 	data.expa = expa;
3321 	data.p = p;
3322 	return avtab_map(a, expand_avtab_node, &data);
3323 }
3324 
expand_cond_insert(cond_av_list_t ** l,avtab_t * expa,avtab_key_t * k,avtab_datum_t * d)3325 static int expand_cond_insert(cond_av_list_t ** l,
3326 			      avtab_t * expa,
3327 			      avtab_key_t * k, avtab_datum_t * d)
3328 {
3329 	avtab_ptr_t node;
3330 	avtab_datum_t *avd;
3331 	cond_av_list_t *nl;
3332 
3333 	node = avtab_search_node(expa, k);
3334 	if (!node ||
3335 	    (k->specified & AVTAB_ENABLED) !=
3336 	    (node->key.specified & AVTAB_ENABLED)) {
3337 		node = avtab_insert_nonunique(expa, k, d);
3338 		if (!node) {
3339 			ERR(NULL, "Out of memory!");
3340 			return -1;
3341 		}
3342 		node->parse_context = (void *)1;
3343 		nl = (cond_av_list_t *) malloc(sizeof(*nl));
3344 		if (!nl) {
3345 			ERR(NULL, "Out of memory!");
3346 			return -1;
3347 		}
3348 		memset(nl, 0, sizeof(*nl));
3349 		nl->node = node;
3350 		nl->next = *l;
3351 		*l = nl;
3352 		return 0;
3353 	}
3354 
3355 	avd = &node->datum;
3356 	switch (k->specified & ~AVTAB_ENABLED) {
3357 	case AVTAB_ALLOWED:
3358 	case AVTAB_AUDITALLOW:
3359 		avd->data |= d->data;
3360 		break;
3361 	case AVTAB_AUDITDENY:
3362 		avd->data &= d->data;
3363 		break;
3364 	default:
3365 		ERR(NULL, "Type conflict!");
3366 		return -1;
3367 	}
3368 
3369 	return 0;
3370 }
3371 
expand_cond_av_node(policydb_t * p,avtab_ptr_t node,cond_av_list_t ** newl,avtab_t * expa)3372 int expand_cond_av_node(policydb_t * p,
3373 			avtab_ptr_t node,
3374 			cond_av_list_t ** newl, avtab_t * expa)
3375 {
3376 	avtab_key_t *k = &node->key;
3377 	avtab_datum_t *d = &node->datum;
3378 	type_datum_t *stype = p->type_val_to_struct[k->source_type - 1];
3379 	type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1];
3380 	ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1];
3381 	ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1];
3382 	ebitmap_node_t *snode, *tnode;
3383 	unsigned int i, j;
3384 	avtab_key_t newkey;
3385 	int rc;
3386 
3387 	newkey.target_class = k->target_class;
3388 	newkey.specified = k->specified;
3389 
3390 	if (stype && ttype && stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) {
3391 		/* Both are individual types, no expansion required. */
3392 		return expand_cond_insert(newl, expa, k, d);
3393 	}
3394 
3395 	if (stype && stype->flavor != TYPE_ATTRIB) {
3396 		/* Source is an individual type, target is an attribute. */
3397 		newkey.source_type = k->source_type;
3398 		ebitmap_for_each_positive_bit(tattr, tnode, j) {
3399 			newkey.target_type = j + 1;
3400 			rc = expand_cond_insert(newl, expa, &newkey, d);
3401 			if (rc)
3402 				return -1;
3403 		}
3404 		return 0;
3405 	}
3406 
3407 	if (ttype && ttype->flavor != TYPE_ATTRIB) {
3408 		/* Target is an individual type, source is an attribute. */
3409 		newkey.target_type = k->target_type;
3410 		ebitmap_for_each_positive_bit(sattr, snode, i) {
3411 			newkey.source_type = i + 1;
3412 			rc = expand_cond_insert(newl, expa, &newkey, d);
3413 			if (rc)
3414 				return -1;
3415 		}
3416 		return 0;
3417 	}
3418 
3419 	/* Both source and target type are attributes. */
3420 	ebitmap_for_each_positive_bit(sattr, snode, i) {
3421 		ebitmap_for_each_positive_bit(tattr, tnode, j) {
3422 			newkey.source_type = i + 1;
3423 			newkey.target_type = j + 1;
3424 			rc = expand_cond_insert(newl, expa, &newkey, d);
3425 			if (rc)
3426 				return -1;
3427 		}
3428 	}
3429 
3430 	return 0;
3431 }
3432 
expand_cond_av_list(policydb_t * p,cond_av_list_t * l,cond_av_list_t ** newl,avtab_t * expa)3433 int expand_cond_av_list(policydb_t * p, cond_av_list_t * l,
3434 			cond_av_list_t ** newl, avtab_t * expa)
3435 {
3436 	cond_av_list_t *cur;
3437 	avtab_ptr_t node;
3438 	int rc;
3439 
3440 	if (avtab_alloc(expa, MAX_AVTAB_SIZE)) {
3441 		ERR(NULL, "Out of memory!");
3442 		return -1;
3443 	}
3444 
3445 	*newl = NULL;
3446 	for (cur = l; cur; cur = cur->next) {
3447 		node = cur->node;
3448 		rc = expand_cond_av_node(p, node, newl, expa);
3449 		if (rc)
3450 			return rc;
3451 	}
3452 
3453 	return 0;
3454 }
3455