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