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