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