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