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