1
2 /* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */
3
4 /*
5 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
6 *
7 * Support for enhanced MLS infrastructure.
8 *
9 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
10 *
11 * Added conditional policy language extensions
12 *
13 * Updated: Red Hat, Inc. James Morris <jmorris@redhat.com>
14 * Fine-grained netlink support
15 * IPv6 support
16 * Code cleanup
17 *
18 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
19 * Copyright (C) 2003 - 2005 Tresys Technology, LLC
20 * Copyright (C) 2003 - 2007 Red Hat, Inc.
21 *
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License as published by the Free Software Foundation; either
25 * version 2.1 of the License, or (at your option) any later version.
26 *
27 * This library is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 * Lesser General Public License for more details.
31 *
32 * You should have received a copy of the GNU Lesser General Public
33 * License along with this library; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
35 */
36
37 /* FLASK */
38
39 /*
40 * Implementation of the policy database.
41 */
42
43 #include <assert.h>
44 #include <stdlib.h>
45
46 #include <sepol/policydb/policydb.h>
47 #include <sepol/policydb/expand.h>
48 #include <sepol/policydb/conditional.h>
49 #include <sepol/policydb/avrule_block.h>
50 #include <sepol/policydb/util.h>
51 #include <sepol/policydb/flask.h>
52
53 #include "private.h"
54 #include "debug.h"
55 #include "mls.h"
56
57 #define POLICYDB_TARGET_SZ ARRAY_SIZE(policydb_target_strings)
58 char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };
59
60 /* These need to be updated if SYM_NUM or OCON_NUM changes */
61 static struct policydb_compat_info policydb_compat[] = {
62 {
63 .type = POLICY_KERN,
64 .version = POLICYDB_VERSION_BOUNDARY,
65 .sym_num = SYM_NUM,
66 .ocon_num = OCON_XEN_PCIDEVICE + 1,
67 .target_platform = SEPOL_TARGET_XEN,
68 },
69 {
70 .type = POLICY_KERN,
71 .version = POLICYDB_VERSION_BASE,
72 .sym_num = SYM_NUM - 3,
73 .ocon_num = OCON_FSUSE + 1,
74 .target_platform = SEPOL_TARGET_SELINUX,
75 },
76 {
77 .type = POLICY_KERN,
78 .version = POLICYDB_VERSION_BOOL,
79 .sym_num = SYM_NUM - 2,
80 .ocon_num = OCON_FSUSE + 1,
81 .target_platform = SEPOL_TARGET_SELINUX,
82 },
83 {
84 .type = POLICY_KERN,
85 .version = POLICYDB_VERSION_IPV6,
86 .sym_num = SYM_NUM - 2,
87 .ocon_num = OCON_NODE6 + 1,
88 .target_platform = SEPOL_TARGET_SELINUX,
89 },
90 {
91 .type = POLICY_KERN,
92 .version = POLICYDB_VERSION_NLCLASS,
93 .sym_num = SYM_NUM - 2,
94 .ocon_num = OCON_NODE6 + 1,
95 .target_platform = SEPOL_TARGET_SELINUX,
96 },
97 {
98 .type = POLICY_KERN,
99 .version = POLICYDB_VERSION_MLS,
100 .sym_num = SYM_NUM,
101 .ocon_num = OCON_NODE6 + 1,
102 .target_platform = SEPOL_TARGET_SELINUX,
103 },
104 {
105 .type = POLICY_KERN,
106 .version = POLICYDB_VERSION_AVTAB,
107 .sym_num = SYM_NUM,
108 .ocon_num = OCON_NODE6 + 1,
109 .target_platform = SEPOL_TARGET_SELINUX,
110 },
111 {
112 .type = POLICY_KERN,
113 .version = POLICYDB_VERSION_RANGETRANS,
114 .sym_num = SYM_NUM,
115 .ocon_num = OCON_NODE6 + 1,
116 .target_platform = SEPOL_TARGET_SELINUX,
117 },
118 {
119 .type = POLICY_KERN,
120 .version = POLICYDB_VERSION_POLCAP,
121 .sym_num = SYM_NUM,
122 .ocon_num = OCON_NODE6 + 1,
123 .target_platform = SEPOL_TARGET_SELINUX,
124 },
125 {
126 .type = POLICY_KERN,
127 .version = POLICYDB_VERSION_PERMISSIVE,
128 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NODE6 + 1,
130 .target_platform = SEPOL_TARGET_SELINUX,
131 },
132 {
133 .type = POLICY_KERN,
134 .version = POLICYDB_VERSION_BOUNDARY,
135 .sym_num = SYM_NUM,
136 .ocon_num = OCON_NODE6 + 1,
137 .target_platform = SEPOL_TARGET_SELINUX,
138 },
139 {
140 .type = POLICY_KERN,
141 .version = POLICYDB_VERSION_FILENAME_TRANS,
142 .sym_num = SYM_NUM,
143 .ocon_num = OCON_NODE6 + 1,
144 .target_platform = SEPOL_TARGET_SELINUX,
145 },
146 {
147 .type = POLICY_KERN,
148 .version = POLICYDB_VERSION_ROLETRANS,
149 .sym_num = SYM_NUM,
150 .ocon_num = OCON_NODE6 + 1,
151 .target_platform = SEPOL_TARGET_SELINUX,
152 },
153 {
154 .type = POLICY_KERN,
155 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
156 .sym_num = SYM_NUM,
157 .ocon_num = OCON_NODE6 + 1,
158 .target_platform = SEPOL_TARGET_SELINUX,
159 },
160 {
161 .type = POLICY_BASE,
162 .version = MOD_POLICYDB_VERSION_BASE,
163 .sym_num = SYM_NUM,
164 .ocon_num = OCON_NODE6 + 1,
165 .target_platform = SEPOL_TARGET_SELINUX,
166 },
167 {
168 .type = POLICY_BASE,
169 .version = MOD_POLICYDB_VERSION_MLS,
170 .sym_num = SYM_NUM,
171 .ocon_num = OCON_NODE6 + 1,
172 .target_platform = SEPOL_TARGET_SELINUX,
173 },
174 {
175 .type = POLICY_BASE,
176 .version = MOD_POLICYDB_VERSION_MLS_USERS,
177 .sym_num = SYM_NUM,
178 .ocon_num = OCON_NODE6 + 1,
179 .target_platform = SEPOL_TARGET_SELINUX,
180 },
181 {
182 .type = POLICY_BASE,
183 .version = MOD_POLICYDB_VERSION_POLCAP,
184 .sym_num = SYM_NUM,
185 .ocon_num = OCON_NODE6 + 1,
186 .target_platform = SEPOL_TARGET_SELINUX,
187 },
188 {
189 .type = POLICY_BASE,
190 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
191 .sym_num = SYM_NUM,
192 .ocon_num = OCON_NODE6 + 1,
193 .target_platform = SEPOL_TARGET_SELINUX,
194 },
195 {
196 .type = POLICY_BASE,
197 .version = MOD_POLICYDB_VERSION_BOUNDARY,
198 .sym_num = SYM_NUM,
199 .ocon_num = OCON_NODE6 + 1,
200 .target_platform = SEPOL_TARGET_SELINUX,
201 },
202 {
203 .type = POLICY_BASE,
204 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
205 .sym_num = SYM_NUM,
206 .ocon_num = OCON_NODE6 + 1,
207 .target_platform = SEPOL_TARGET_SELINUX,
208 },
209 {
210 .type = POLICY_BASE,
211 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
212 .sym_num = SYM_NUM,
213 .ocon_num = OCON_NODE6 + 1,
214 .target_platform = SEPOL_TARGET_SELINUX,
215 },
216 {
217 .type = POLICY_BASE,
218 .version = MOD_POLICYDB_VERSION_ROLETRANS,
219 .sym_num = SYM_NUM,
220 .ocon_num = OCON_NODE6 + 1,
221 .target_platform = SEPOL_TARGET_SELINUX,
222 },
223 {
224 .type = POLICY_BASE,
225 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
226 .sym_num = SYM_NUM,
227 .ocon_num = OCON_NODE6 + 1,
228 .target_platform = SEPOL_TARGET_SELINUX,
229 },
230 {
231 .type = POLICY_BASE,
232 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
233 .sym_num = SYM_NUM,
234 .ocon_num = OCON_NODE6 + 1,
235 .target_platform = SEPOL_TARGET_SELINUX,
236 },
237 {
238 .type = POLICY_BASE,
239 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
240 .sym_num = SYM_NUM,
241 .ocon_num = OCON_NODE6 + 1,
242 .target_platform = SEPOL_TARGET_SELINUX,
243 },
244 {
245 .type = POLICY_MOD,
246 .version = MOD_POLICYDB_VERSION_BASE,
247 .sym_num = SYM_NUM,
248 .ocon_num = 0,
249 .target_platform = SEPOL_TARGET_SELINUX,
250 },
251 {
252 .type = POLICY_MOD,
253 .version = MOD_POLICYDB_VERSION_MLS,
254 .sym_num = SYM_NUM,
255 .ocon_num = 0,
256 .target_platform = SEPOL_TARGET_SELINUX,
257 },
258 {
259 .type = POLICY_MOD,
260 .version = MOD_POLICYDB_VERSION_MLS_USERS,
261 .sym_num = SYM_NUM,
262 .ocon_num = 0,
263 .target_platform = SEPOL_TARGET_SELINUX,
264 },
265 {
266 .type = POLICY_MOD,
267 .version = MOD_POLICYDB_VERSION_POLCAP,
268 .sym_num = SYM_NUM,
269 .ocon_num = 0,
270 .target_platform = SEPOL_TARGET_SELINUX,
271 },
272 {
273 .type = POLICY_MOD,
274 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
275 .sym_num = SYM_NUM,
276 .ocon_num = 0,
277 .target_platform = SEPOL_TARGET_SELINUX,
278 },
279 {
280 .type = POLICY_MOD,
281 .version = MOD_POLICYDB_VERSION_BOUNDARY,
282 .sym_num = SYM_NUM,
283 .ocon_num = 0,
284 .target_platform = SEPOL_TARGET_SELINUX,
285 },
286 {
287 .type = POLICY_MOD,
288 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
289 .sym_num = SYM_NUM,
290 .ocon_num = 0,
291 .target_platform = SEPOL_TARGET_SELINUX,
292 },
293 {
294 .type = POLICY_MOD,
295 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
296 .sym_num = SYM_NUM,
297 .ocon_num = 0,
298 .target_platform = SEPOL_TARGET_SELINUX,
299 },
300 {
301 .type = POLICY_MOD,
302 .version = MOD_POLICYDB_VERSION_ROLETRANS,
303 .sym_num = SYM_NUM,
304 .ocon_num = 0,
305 .target_platform = SEPOL_TARGET_SELINUX,
306 },
307 {
308 .type = POLICY_MOD,
309 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
310 .sym_num = SYM_NUM,
311 .ocon_num = 0,
312 .target_platform = SEPOL_TARGET_SELINUX,
313 },
314 {
315 .type = POLICY_MOD,
316 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
317 .sym_num = SYM_NUM,
318 .ocon_num = 0,
319 .target_platform = SEPOL_TARGET_SELINUX,
320 },
321 {
322 .type = POLICY_MOD,
323 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
324 .sym_num = SYM_NUM,
325 .ocon_num = 0,
326 .target_platform = SEPOL_TARGET_SELINUX,
327 },
328 };
329
330 #if 0
331 static char *symtab_name[SYM_NUM] = {
332 "common prefixes",
333 "classes",
334 "roles",
335 "types",
336 "users",
337 "bools" mls_symtab_names cond_symtab_names
338 };
339 #endif
340
341 static unsigned int symtab_sizes[SYM_NUM] = {
342 2,
343 32,
344 16,
345 512,
346 128,
347 16,
348 16,
349 16,
350 };
351
policydb_lookup_compat(unsigned int version,unsigned int type,unsigned int target_platform)352 struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
353 unsigned int type,
354 unsigned int target_platform)
355 {
356 unsigned int i;
357 struct policydb_compat_info *info = NULL;
358
359 for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) {
360 if (policydb_compat[i].version == version &&
361 policydb_compat[i].type == type &&
362 policydb_compat[i].target_platform == target_platform) {
363 info = &policydb_compat[i];
364 break;
365 }
366 }
367 return info;
368 }
369
type_set_init(type_set_t * x)370 void type_set_init(type_set_t * x)
371 {
372 memset(x, 0, sizeof(type_set_t));
373 ebitmap_init(&x->types);
374 ebitmap_init(&x->negset);
375 }
376
type_set_destroy(type_set_t * x)377 void type_set_destroy(type_set_t * x)
378 {
379 if (x != NULL) {
380 ebitmap_destroy(&x->types);
381 ebitmap_destroy(&x->negset);
382 }
383 }
384
role_set_init(role_set_t * x)385 void role_set_init(role_set_t * x)
386 {
387 memset(x, 0, sizeof(role_set_t));
388 ebitmap_init(&x->roles);
389 }
390
role_set_destroy(role_set_t * x)391 void role_set_destroy(role_set_t * x)
392 {
393 ebitmap_destroy(&x->roles);
394 }
395
role_datum_init(role_datum_t * x)396 void role_datum_init(role_datum_t * x)
397 {
398 memset(x, 0, sizeof(role_datum_t));
399 ebitmap_init(&x->dominates);
400 type_set_init(&x->types);
401 ebitmap_init(&x->cache);
402 ebitmap_init(&x->roles);
403 }
404
role_datum_destroy(role_datum_t * x)405 void role_datum_destroy(role_datum_t * x)
406 {
407 if (x != NULL) {
408 ebitmap_destroy(&x->dominates);
409 type_set_destroy(&x->types);
410 ebitmap_destroy(&x->cache);
411 ebitmap_destroy(&x->roles);
412 }
413 }
414
type_datum_init(type_datum_t * x)415 void type_datum_init(type_datum_t * x)
416 {
417 memset(x, 0, sizeof(*x));
418 ebitmap_init(&x->types);
419 }
420
type_datum_destroy(type_datum_t * x)421 void type_datum_destroy(type_datum_t * x)
422 {
423 if (x != NULL) {
424 ebitmap_destroy(&x->types);
425 }
426 }
427
user_datum_init(user_datum_t * x)428 void user_datum_init(user_datum_t * x)
429 {
430 memset(x, 0, sizeof(user_datum_t));
431 role_set_init(&x->roles);
432 mls_semantic_range_init(&x->range);
433 mls_semantic_level_init(&x->dfltlevel);
434 ebitmap_init(&x->cache);
435 mls_range_init(&x->exp_range);
436 mls_level_init(&x->exp_dfltlevel);
437 }
438
user_datum_destroy(user_datum_t * x)439 void user_datum_destroy(user_datum_t * x)
440 {
441 if (x != NULL) {
442 role_set_destroy(&x->roles);
443 mls_semantic_range_destroy(&x->range);
444 mls_semantic_level_destroy(&x->dfltlevel);
445 ebitmap_destroy(&x->cache);
446 mls_range_destroy(&x->exp_range);
447 mls_level_destroy(&x->exp_dfltlevel);
448 }
449 }
450
level_datum_init(level_datum_t * x)451 void level_datum_init(level_datum_t * x)
452 {
453 memset(x, 0, sizeof(level_datum_t));
454 }
455
level_datum_destroy(level_datum_t * x)456 void level_datum_destroy(level_datum_t * x __attribute__ ((unused)))
457 {
458 /* the mls_level_t referenced by the level_datum is managed
459 * separately for now, so there is nothing to destroy */
460 return;
461 }
462
cat_datum_init(cat_datum_t * x)463 void cat_datum_init(cat_datum_t * x)
464 {
465 memset(x, 0, sizeof(cat_datum_t));
466 }
467
cat_datum_destroy(cat_datum_t * x)468 void cat_datum_destroy(cat_datum_t * x __attribute__ ((unused)))
469 {
470 /* it's currently a simple struct - really nothing to destroy */
471 return;
472 }
473
class_perm_node_init(class_perm_node_t * x)474 void class_perm_node_init(class_perm_node_t * x)
475 {
476 memset(x, 0, sizeof(class_perm_node_t));
477 }
478
avrule_init(avrule_t * x)479 void avrule_init(avrule_t * x)
480 {
481 memset(x, 0, sizeof(avrule_t));
482 type_set_init(&x->stypes);
483 type_set_init(&x->ttypes);
484 }
485
avrule_destroy(avrule_t * x)486 void avrule_destroy(avrule_t * x)
487 {
488 class_perm_node_t *cur, *next;
489
490 if (x == NULL) {
491 return;
492 }
493 type_set_destroy(&x->stypes);
494 type_set_destroy(&x->ttypes);
495
496 next = x->perms;
497 while (next) {
498 cur = next;
499 next = cur->next;
500 free(cur);
501 }
502 }
503
role_trans_rule_init(role_trans_rule_t * x)504 void role_trans_rule_init(role_trans_rule_t * x)
505 {
506 memset(x, 0, sizeof(*x));
507 role_set_init(&x->roles);
508 type_set_init(&x->types);
509 ebitmap_init(&x->classes);
510 }
511
role_trans_rule_destroy(role_trans_rule_t * x)512 void role_trans_rule_destroy(role_trans_rule_t * x)
513 {
514 if (x != NULL) {
515 role_set_destroy(&x->roles);
516 type_set_destroy(&x->types);
517 ebitmap_destroy(&x->classes);
518 }
519 }
520
role_trans_rule_list_destroy(role_trans_rule_t * x)521 void role_trans_rule_list_destroy(role_trans_rule_t * x)
522 {
523 while (x != NULL) {
524 role_trans_rule_t *next = x->next;
525 role_trans_rule_destroy(x);
526 free(x);
527 x = next;
528 }
529 }
530
filename_trans_rule_init(filename_trans_rule_t * x)531 void filename_trans_rule_init(filename_trans_rule_t * x)
532 {
533 memset(x, 0, sizeof(*x));
534 type_set_init(&x->stypes);
535 type_set_init(&x->ttypes);
536 }
537
filename_trans_rule_destroy(filename_trans_rule_t * x)538 static void filename_trans_rule_destroy(filename_trans_rule_t * x)
539 {
540 if (!x)
541 return;
542 type_set_destroy(&x->stypes);
543 type_set_destroy(&x->ttypes);
544 free(x->name);
545 }
546
filename_trans_rule_list_destroy(filename_trans_rule_t * x)547 void filename_trans_rule_list_destroy(filename_trans_rule_t * x)
548 {
549 filename_trans_rule_t *next;
550 while (x) {
551 next = x->next;
552 filename_trans_rule_destroy(x);
553 free(x);
554 x = next;
555 }
556 }
557
role_allow_rule_init(role_allow_rule_t * x)558 void role_allow_rule_init(role_allow_rule_t * x)
559 {
560 memset(x, 0, sizeof(role_allow_rule_t));
561 role_set_init(&x->roles);
562 role_set_init(&x->new_roles);
563 }
564
role_allow_rule_destroy(role_allow_rule_t * x)565 void role_allow_rule_destroy(role_allow_rule_t * x)
566 {
567 role_set_destroy(&x->roles);
568 role_set_destroy(&x->new_roles);
569 }
570
role_allow_rule_list_destroy(role_allow_rule_t * x)571 void role_allow_rule_list_destroy(role_allow_rule_t * x)
572 {
573 while (x != NULL) {
574 role_allow_rule_t *next = x->next;
575 role_allow_rule_destroy(x);
576 free(x);
577 x = next;
578 }
579 }
580
range_trans_rule_init(range_trans_rule_t * x)581 void range_trans_rule_init(range_trans_rule_t * x)
582 {
583 type_set_init(&x->stypes);
584 type_set_init(&x->ttypes);
585 ebitmap_init(&x->tclasses);
586 mls_semantic_range_init(&x->trange);
587 x->next = NULL;
588 }
589
range_trans_rule_destroy(range_trans_rule_t * x)590 void range_trans_rule_destroy(range_trans_rule_t * x)
591 {
592 type_set_destroy(&x->stypes);
593 type_set_destroy(&x->ttypes);
594 ebitmap_destroy(&x->tclasses);
595 mls_semantic_range_destroy(&x->trange);
596 }
597
range_trans_rule_list_destroy(range_trans_rule_t * x)598 void range_trans_rule_list_destroy(range_trans_rule_t * x)
599 {
600 while (x != NULL) {
601 range_trans_rule_t *next = x->next;
602 range_trans_rule_destroy(x);
603 free(x);
604 x = next;
605 }
606 }
607
avrule_list_destroy(avrule_t * x)608 void avrule_list_destroy(avrule_t * x)
609 {
610 avrule_t *next, *cur;
611
612 if (!x)
613 return;
614
615 next = x;
616 while (next) {
617 cur = next;
618 next = next->next;
619 avrule_destroy(cur);
620 free(cur);
621 }
622 }
623
624 /*
625 * Initialize the role table by implicitly adding role 'object_r'. If
626 * the policy is a module, set object_r's scope to be SCOPE_REQ,
627 * otherwise set it to SCOPE_DECL.
628 */
roles_init(policydb_t * p)629 static int roles_init(policydb_t * p)
630 {
631 char *key = 0;
632 int rc;
633 role_datum_t *role;
634
635 role = calloc(1, sizeof(role_datum_t));
636 if (!role) {
637 rc = -ENOMEM;
638 goto out;
639 }
640 key = malloc(strlen(OBJECT_R) + 1);
641 if (!key) {
642 rc = -ENOMEM;
643 goto out_free_role;
644 }
645 strcpy(key, OBJECT_R);
646 rc = symtab_insert(p, SYM_ROLES, key, role,
647 (p->policy_type ==
648 POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1,
649 &role->s.value);
650 if (rc)
651 goto out_free_key;
652 if (role->s.value != OBJECT_R_VAL) {
653 rc = -EINVAL;
654 goto out_free_role;
655 }
656 out:
657 return rc;
658
659 out_free_key:
660 free(key);
661 out_free_role:
662 free(role);
663 goto out;
664 }
665
666 /*
667 * Initialize a policy database structure.
668 */
policydb_init(policydb_t * p)669 int policydb_init(policydb_t * p)
670 {
671 int i, rc;
672
673 memset(p, 0, sizeof(policydb_t));
674
675 ebitmap_init(&p->policycaps);
676
677 ebitmap_init(&p->permissive_map);
678
679 for (i = 0; i < SYM_NUM; i++) {
680 p->sym_val_to_name[i] = NULL;
681 rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
682 if (rc)
683 goto out_free_symtab;
684 }
685
686 /* initialize the module stuff */
687 for (i = 0; i < SYM_NUM; i++) {
688 if (symtab_init(&p->scope[i], symtab_sizes[i])) {
689 goto out_free_symtab;
690 }
691 }
692 if ((p->global = avrule_block_create()) == NULL ||
693 (p->global->branch_list = avrule_decl_create(1)) == NULL) {
694 goto out_free_symtab;
695 }
696 p->decl_val_to_struct = NULL;
697
698 rc = avtab_init(&p->te_avtab);
699 if (rc)
700 goto out_free_symtab;
701
702 rc = roles_init(p);
703 if (rc)
704 goto out_free_symtab;
705
706 rc = cond_policydb_init(p);
707 if (rc)
708 goto out_free_symtab;
709 out:
710 return rc;
711
712 out_free_symtab:
713 for (i = 0; i < SYM_NUM; i++) {
714 hashtab_destroy(p->symtab[i].table);
715 hashtab_destroy(p->scope[i].table);
716 }
717 avrule_block_list_destroy(p->global);
718 goto out;
719 }
720
policydb_role_cache(hashtab_key_t key,hashtab_datum_t datum,void * arg)721 int policydb_role_cache(hashtab_key_t key
722 __attribute__ ((unused)), hashtab_datum_t datum,
723 void *arg)
724 {
725 policydb_t *p;
726 role_datum_t *role;
727
728 role = (role_datum_t *) datum;
729 p = (policydb_t *) arg;
730
731 ebitmap_destroy(&role->cache);
732 if (type_set_expand(&role->types, &role->cache, p, 1)) {
733 return -1;
734 }
735
736 return 0;
737 }
738
policydb_user_cache(hashtab_key_t key,hashtab_datum_t datum,void * arg)739 int policydb_user_cache(hashtab_key_t key
740 __attribute__ ((unused)), hashtab_datum_t datum,
741 void *arg)
742 {
743 policydb_t *p;
744 user_datum_t *user;
745
746 user = (user_datum_t *) datum;
747 p = (policydb_t *) arg;
748
749 ebitmap_destroy(&user->cache);
750 if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) {
751 return -1;
752 }
753
754 /* we do not expand user's MLS info in kernel policies because the
755 * semantic representation is not present and we do not expand user's
756 * MLS info in module policies because all of the necessary mls
757 * information is not present */
758 if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) {
759 mls_range_destroy(&user->exp_range);
760 if (mls_semantic_range_expand(&user->range,
761 &user->exp_range, p, NULL)) {
762 return -1;
763 }
764
765 mls_level_destroy(&user->exp_dfltlevel);
766 if (mls_semantic_level_expand(&user->dfltlevel,
767 &user->exp_dfltlevel, p, NULL)) {
768 return -1;
769 }
770 }
771
772 return 0;
773 }
774
775 /*
776 * The following *_index functions are used to
777 * define the val_to_name and val_to_struct arrays
778 * in a policy database structure. The val_to_name
779 * arrays are used when converting security context
780 * structures into string representations. The
781 * val_to_struct arrays are used when the attributes
782 * of a class, role, or user are needed.
783 */
784
common_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)785 static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
786 {
787 policydb_t *p;
788 common_datum_t *comdatum;
789
790 comdatum = (common_datum_t *) datum;
791 p = (policydb_t *) datap;
792 if (!comdatum->s.value || comdatum->s.value > p->p_commons.nprim)
793 return -EINVAL;
794 p->p_common_val_to_name[comdatum->s.value - 1] = (char *)key;
795
796 return 0;
797 }
798
class_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)799 static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
800 {
801 policydb_t *p;
802 class_datum_t *cladatum;
803
804 cladatum = (class_datum_t *) datum;
805 p = (policydb_t *) datap;
806 if (!cladatum->s.value || cladatum->s.value > p->p_classes.nprim)
807 return -EINVAL;
808 p->p_class_val_to_name[cladatum->s.value - 1] = (char *)key;
809 p->class_val_to_struct[cladatum->s.value - 1] = cladatum;
810
811 return 0;
812 }
813
role_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)814 static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
815 {
816 policydb_t *p;
817 role_datum_t *role;
818
819 role = (role_datum_t *) datum;
820 p = (policydb_t *) datap;
821 if (!role->s.value || role->s.value > p->p_roles.nprim)
822 return -EINVAL;
823 p->p_role_val_to_name[role->s.value - 1] = (char *)key;
824 p->role_val_to_struct[role->s.value - 1] = role;
825
826 return 0;
827 }
828
type_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)829 static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
830 {
831 policydb_t *p;
832 type_datum_t *typdatum;
833
834 typdatum = (type_datum_t *) datum;
835 p = (policydb_t *) datap;
836
837 if (typdatum->primary) {
838 if (!typdatum->s.value || typdatum->s.value > p->p_types.nprim)
839 return -EINVAL;
840 p->p_type_val_to_name[typdatum->s.value - 1] = (char *)key;
841 p->type_val_to_struct[typdatum->s.value - 1] = typdatum;
842 }
843
844 return 0;
845 }
846
user_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)847 static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
848 {
849 policydb_t *p;
850 user_datum_t *usrdatum;
851
852 usrdatum = (user_datum_t *) datum;
853 p = (policydb_t *) datap;
854
855 if (!usrdatum->s.value || usrdatum->s.value > p->p_users.nprim)
856 return -EINVAL;
857
858 p->p_user_val_to_name[usrdatum->s.value - 1] = (char *)key;
859 p->user_val_to_struct[usrdatum->s.value - 1] = usrdatum;
860
861 return 0;
862 }
863
sens_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)864 static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
865 {
866 policydb_t *p;
867 level_datum_t *levdatum;
868
869 levdatum = (level_datum_t *) datum;
870 p = (policydb_t *) datap;
871
872 if (!levdatum->isalias) {
873 if (!levdatum->level->sens ||
874 levdatum->level->sens > p->p_levels.nprim)
875 return -EINVAL;
876 p->p_sens_val_to_name[levdatum->level->sens - 1] = (char *)key;
877 }
878
879 return 0;
880 }
881
cat_index(hashtab_key_t key,hashtab_datum_t datum,void * datap)882 static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
883 {
884 policydb_t *p;
885 cat_datum_t *catdatum;
886
887 catdatum = (cat_datum_t *) datum;
888 p = (policydb_t *) datap;
889
890 if (!catdatum->isalias) {
891 if (!catdatum->s.value || catdatum->s.value > p->p_cats.nprim)
892 return -EINVAL;
893 p->p_cat_val_to_name[catdatum->s.value - 1] = (char *)key;
894 }
895
896 return 0;
897 }
898
899 static int (*index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
900 void *datap) = {
901 common_index, class_index, role_index, type_index, user_index,
902 cond_index_bool, sens_index, cat_index,};
903
904 /*
905 * Define the common val_to_name array and the class
906 * val_to_name and val_to_struct arrays in a policy
907 * database structure.
908 */
policydb_index_classes(policydb_t * p)909 int policydb_index_classes(policydb_t * p)
910 {
911 free(p->p_common_val_to_name);
912 p->p_common_val_to_name = (char **)
913 malloc(p->p_commons.nprim * sizeof(char *));
914 if (!p->p_common_val_to_name)
915 return -1;
916
917 if (hashtab_map(p->p_commons.table, common_index, p))
918 return -1;
919
920 free(p->class_val_to_struct);
921 p->class_val_to_struct = (class_datum_t **)
922 malloc(p->p_classes.nprim * sizeof(class_datum_t *));
923 if (!p->class_val_to_struct)
924 return -1;
925
926 free(p->p_class_val_to_name);
927 p->p_class_val_to_name = (char **)
928 malloc(p->p_classes.nprim * sizeof(char *));
929 if (!p->p_class_val_to_name)
930 return -1;
931
932 if (hashtab_map(p->p_classes.table, class_index, p))
933 return -1;
934
935 return 0;
936 }
937
policydb_index_bools(policydb_t * p)938 int policydb_index_bools(policydb_t * p)
939 {
940
941 if (cond_init_bool_indexes(p) == -1)
942 return -1;
943 p->p_bool_val_to_name = (char **)
944 malloc(p->p_bools.nprim * sizeof(char *));
945 if (!p->p_bool_val_to_name)
946 return -1;
947 if (hashtab_map(p->p_bools.table, cond_index_bool, p))
948 return -1;
949 return 0;
950 }
951
policydb_index_decls(policydb_t * p)952 int policydb_index_decls(policydb_t * p)
953 {
954 avrule_block_t *curblock;
955 avrule_decl_t *decl;
956 int num_decls = 0;
957
958 free(p->decl_val_to_struct);
959
960 for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
961 for (decl = curblock->branch_list; decl != NULL;
962 decl = decl->next) {
963 num_decls++;
964 }
965 }
966
967 p->decl_val_to_struct =
968 calloc(num_decls, sizeof(*(p->decl_val_to_struct)));
969 if (!p->decl_val_to_struct) {
970 return -1;
971 }
972
973 for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
974 for (decl = curblock->branch_list; decl != NULL;
975 decl = decl->next) {
976 p->decl_val_to_struct[decl->decl_id - 1] = decl;
977 }
978 }
979
980 return 0;
981 }
982
983 /*
984 * Define the other val_to_name and val_to_struct arrays
985 * in a policy database structure.
986 */
policydb_index_others(sepol_handle_t * handle,policydb_t * p,unsigned verbose)987 int policydb_index_others(sepol_handle_t * handle,
988 policydb_t * p, unsigned verbose)
989 {
990 int i;
991
992 if (verbose) {
993 INFO(handle,
994 "security: %d users, %d roles, %d types, %d bools",
995 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
996 p->p_bools.nprim);
997
998 if (p->mls)
999 INFO(handle, "security: %d sens, %d cats",
1000 p->p_levels.nprim, p->p_cats.nprim);
1001
1002 INFO(handle, "security: %d classes, %d rules, %d cond rules",
1003 p->p_classes.nprim, p->te_avtab.nel, p->te_cond_avtab.nel);
1004 }
1005 #if 0
1006 avtab_hash_eval(&p->te_avtab, "rules");
1007 for (i = 0; i < SYM_NUM; i++)
1008 hashtab_hash_eval(p->symtab[i].table, symtab_name[i]);
1009 #endif
1010
1011 free(p->role_val_to_struct);
1012 p->role_val_to_struct = (role_datum_t **)
1013 malloc(p->p_roles.nprim * sizeof(role_datum_t *));
1014 if (!p->role_val_to_struct)
1015 return -1;
1016
1017 free(p->user_val_to_struct);
1018 p->user_val_to_struct = (user_datum_t **)
1019 malloc(p->p_users.nprim * sizeof(user_datum_t *));
1020 if (!p->user_val_to_struct)
1021 return -1;
1022
1023 free(p->type_val_to_struct);
1024 p->type_val_to_struct = (type_datum_t **)
1025 calloc(p->p_types.nprim, sizeof(type_datum_t *));
1026 if (!p->type_val_to_struct)
1027 return -1;
1028
1029 cond_init_bool_indexes(p);
1030
1031 for (i = SYM_ROLES; i < SYM_NUM; i++) {
1032 free(p->sym_val_to_name[i]);
1033 p->sym_val_to_name[i] = NULL;
1034 if (p->symtab[i].nprim) {
1035 p->sym_val_to_name[i] = (char **)
1036 calloc(p->symtab[i].nprim, sizeof(char *));
1037 if (!p->sym_val_to_name[i])
1038 return -1;
1039 if (hashtab_map(p->symtab[i].table, index_f[i], p))
1040 return -1;
1041 }
1042 }
1043
1044 /* This pre-expands the roles and users for context validity checking */
1045 if (hashtab_map(p->p_roles.table, policydb_role_cache, p))
1046 return -1;
1047
1048 if (hashtab_map(p->p_users.table, policydb_user_cache, p))
1049 return -1;
1050
1051 return 0;
1052 }
1053
1054 /*
1055 * The following *_destroy functions are used to
1056 * free any memory allocated for each kind of
1057 * symbol data in the policy database.
1058 */
1059
perm_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1060 static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1061 __attribute__ ((unused)))
1062 {
1063 if (key)
1064 free(key);
1065 free(datum);
1066 return 0;
1067 }
1068
common_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1069 static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1070 __attribute__ ((unused)))
1071 {
1072 common_datum_t *comdatum;
1073
1074 if (key)
1075 free(key);
1076 comdatum = (common_datum_t *) datum;
1077 hashtab_map(comdatum->permissions.table, perm_destroy, 0);
1078 hashtab_destroy(comdatum->permissions.table);
1079 free(datum);
1080 return 0;
1081 }
1082
class_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1083 static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1084 __attribute__ ((unused)))
1085 {
1086 class_datum_t *cladatum;
1087 constraint_node_t *constraint, *ctemp;
1088 constraint_expr_t *e, *etmp;
1089
1090 if (key)
1091 free(key);
1092 cladatum = (class_datum_t *) datum;
1093 if (cladatum == NULL) {
1094 return 0;
1095 }
1096 hashtab_map(cladatum->permissions.table, perm_destroy, 0);
1097 hashtab_destroy(cladatum->permissions.table);
1098 constraint = cladatum->constraints;
1099 while (constraint) {
1100 e = constraint->expr;
1101 while (e) {
1102 etmp = e;
1103 e = e->next;
1104 constraint_expr_destroy(etmp);
1105 }
1106 ctemp = constraint;
1107 constraint = constraint->next;
1108 free(ctemp);
1109 }
1110
1111 constraint = cladatum->validatetrans;
1112 while (constraint) {
1113 e = constraint->expr;
1114 while (e) {
1115 etmp = e;
1116 e = e->next;
1117 constraint_expr_destroy(etmp);
1118 }
1119 ctemp = constraint;
1120 constraint = constraint->next;
1121 free(ctemp);
1122 }
1123
1124 if (cladatum->comkey)
1125 free(cladatum->comkey);
1126 free(datum);
1127 return 0;
1128 }
1129
role_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1130 static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1131 __attribute__ ((unused)))
1132 {
1133 free(key);
1134 role_datum_destroy((role_datum_t *) datum);
1135 free(datum);
1136 return 0;
1137 }
1138
type_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1139 static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1140 __attribute__ ((unused)))
1141 {
1142 free(key);
1143 type_datum_destroy((type_datum_t *) datum);
1144 free(datum);
1145 return 0;
1146 }
1147
user_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1148 static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1149 __attribute__ ((unused)))
1150 {
1151 free(key);
1152 user_datum_destroy((user_datum_t *) datum);
1153 free(datum);
1154 return 0;
1155 }
1156
sens_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1157 static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1158 __attribute__ ((unused)))
1159 {
1160 level_datum_t *levdatum;
1161
1162 if (key)
1163 free(key);
1164 levdatum = (level_datum_t *) datum;
1165 mls_level_destroy(levdatum->level);
1166 free(levdatum->level);
1167 level_datum_destroy(levdatum);
1168 free(levdatum);
1169 return 0;
1170 }
1171
cat_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1172 static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1173 __attribute__ ((unused)))
1174 {
1175 if (key)
1176 free(key);
1177 cat_datum_destroy((cat_datum_t *) datum);
1178 free(datum);
1179 return 0;
1180 }
1181
1182 static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
1183 void *datap) = {
1184 common_destroy, class_destroy, role_destroy, type_destroy, user_destroy,
1185 cond_destroy_bool, sens_destroy, cat_destroy,};
1186
ocontext_selinux_free(ocontext_t ** ocontexts)1187 void ocontext_selinux_free(ocontext_t **ocontexts)
1188 {
1189 ocontext_t *c, *ctmp;
1190 int i;
1191
1192 for (i = 0; i < OCON_NUM; i++) {
1193 c = ocontexts[i];
1194 while (c) {
1195 ctmp = c;
1196 c = c->next;
1197 context_destroy(&ctmp->context[0]);
1198 context_destroy(&ctmp->context[1]);
1199 if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
1200 || i == OCON_FSUSE)
1201 free(ctmp->u.name);
1202 free(ctmp);
1203 }
1204 }
1205 }
1206
ocontext_xen_free(ocontext_t ** ocontexts)1207 void ocontext_xen_free(ocontext_t **ocontexts)
1208 {
1209 ocontext_t *c, *ctmp;
1210 int i;
1211
1212 for (i = 0; i < OCON_NUM; i++) {
1213 c = ocontexts[i];
1214 while (c) {
1215 ctmp = c;
1216 c = c->next;
1217 context_destroy(&ctmp->context[0]);
1218 context_destroy(&ctmp->context[1]);
1219 if (i == OCON_ISID)
1220 free(ctmp->u.name);
1221 free(ctmp);
1222 }
1223 }
1224 }
1225
1226 /*
1227 * Free any memory allocated by a policy database structure.
1228 */
policydb_destroy(policydb_t * p)1229 void policydb_destroy(policydb_t * p)
1230 {
1231 ocontext_t *c, *ctmp;
1232 genfs_t *g, *gtmp;
1233 unsigned int i;
1234 role_allow_t *ra, *lra = NULL;
1235 role_trans_t *tr, *ltr = NULL;
1236 range_trans_t *rt, *lrt = NULL;
1237 filename_trans_t *ft, *nft;
1238
1239 if (!p)
1240 return;
1241
1242 ebitmap_destroy(&p->policycaps);
1243
1244 ebitmap_destroy(&p->permissive_map);
1245
1246 symtabs_destroy(p->symtab);
1247
1248 for (i = 0; i < SYM_NUM; i++) {
1249 if (p->sym_val_to_name[i])
1250 free(p->sym_val_to_name[i]);
1251 }
1252
1253 if (p->class_val_to_struct)
1254 free(p->class_val_to_struct);
1255 if (p->role_val_to_struct)
1256 free(p->role_val_to_struct);
1257 if (p->user_val_to_struct)
1258 free(p->user_val_to_struct);
1259 if (p->type_val_to_struct)
1260 free(p->type_val_to_struct);
1261 free(p->decl_val_to_struct);
1262
1263 for (i = 0; i < SYM_NUM; i++) {
1264 hashtab_map(p->scope[i].table, scope_destroy, 0);
1265 hashtab_destroy(p->scope[i].table);
1266 }
1267 avrule_block_list_destroy(p->global);
1268 free(p->name);
1269 free(p->version);
1270
1271 avtab_destroy(&p->te_avtab);
1272
1273 if (p->target_platform == SEPOL_TARGET_SELINUX)
1274 ocontext_selinux_free(p->ocontexts);
1275 else if (p->target_platform == SEPOL_TARGET_XEN)
1276 ocontext_xen_free(p->ocontexts);
1277
1278 g = p->genfs;
1279 while (g) {
1280 free(g->fstype);
1281 c = g->head;
1282 while (c) {
1283 ctmp = c;
1284 c = c->next;
1285 context_destroy(&ctmp->context[0]);
1286 free(ctmp->u.name);
1287 free(ctmp);
1288 }
1289 gtmp = g;
1290 g = g->next;
1291 free(gtmp);
1292 }
1293 cond_policydb_destroy(p);
1294
1295 for (tr = p->role_tr; tr; tr = tr->next) {
1296 if (ltr)
1297 free(ltr);
1298 ltr = tr;
1299 }
1300 if (ltr)
1301 free(ltr);
1302
1303 ft = p->filename_trans;
1304 while (ft) {
1305 nft = ft->next;
1306 free(ft->name);
1307 free(ft);
1308 ft = nft;
1309 }
1310
1311 for (ra = p->role_allow; ra; ra = ra->next) {
1312 if (lra)
1313 free(lra);
1314 lra = ra;
1315 }
1316 if (lra)
1317 free(lra);
1318
1319 for (rt = p->range_tr; rt; rt = rt->next) {
1320 if (lrt) {
1321 ebitmap_destroy(&lrt->target_range.level[0].cat);
1322 ebitmap_destroy(&lrt->target_range.level[1].cat);
1323 free(lrt);
1324 }
1325 lrt = rt;
1326 }
1327 if (lrt) {
1328 ebitmap_destroy(&lrt->target_range.level[0].cat);
1329 ebitmap_destroy(&lrt->target_range.level[1].cat);
1330 free(lrt);
1331 }
1332
1333 if (p->type_attr_map) {
1334 for (i = 0; i < p->p_types.nprim; i++) {
1335 ebitmap_destroy(&p->type_attr_map[i]);
1336 }
1337 free(p->type_attr_map);
1338 }
1339
1340 if (p->attr_type_map) {
1341 for (i = 0; i < p->p_types.nprim; i++) {
1342 ebitmap_destroy(&p->attr_type_map[i]);
1343 }
1344 free(p->attr_type_map);
1345 }
1346
1347 return;
1348 }
1349
symtabs_destroy(symtab_t * symtab)1350 void symtabs_destroy(symtab_t * symtab)
1351 {
1352 int i;
1353 for (i = 0; i < SYM_NUM; i++) {
1354 hashtab_map(symtab[i].table, destroy_f[i], 0);
1355 hashtab_destroy(symtab[i].table);
1356 }
1357 }
1358
scope_destroy(hashtab_key_t key,hashtab_datum_t datum,void * p)1359 int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
1360 __attribute__ ((unused)))
1361 {
1362 scope_datum_t *cur = (scope_datum_t *) datum;
1363 free(key);
1364 if (cur != NULL) {
1365 free(cur->decl_ids);
1366 }
1367 free(cur);
1368 return 0;
1369 }
1370
get_symtab_destroy_func(int sym_num)1371 hashtab_destroy_func_t get_symtab_destroy_func(int sym_num)
1372 {
1373 if (sym_num < 0 || sym_num >= SYM_NUM) {
1374 return NULL;
1375 }
1376 return (hashtab_destroy_func_t) destroy_f[sym_num];
1377 }
1378
1379 /*
1380 * Load the initial SIDs specified in a policy database
1381 * structure into a SID table.
1382 */
policydb_load_isids(policydb_t * p,sidtab_t * s)1383 int policydb_load_isids(policydb_t * p, sidtab_t * s)
1384 {
1385 ocontext_t *head, *c;
1386
1387 if (sepol_sidtab_init(s)) {
1388 ERR(NULL, "out of memory on SID table init");
1389 return -1;
1390 }
1391
1392 head = p->ocontexts[OCON_ISID];
1393 for (c = head; c; c = c->next) {
1394 if (!c->context[0].user) {
1395 ERR(NULL, "SID %s was never defined", c->u.name);
1396 return -1;
1397 }
1398 if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) {
1399 ERR(NULL, "unable to load initial SID %s", c->u.name);
1400 return -1;
1401 }
1402 }
1403
1404 return 0;
1405 }
1406
1407 /* Declare a symbol for a certain avrule_block context. Insert it
1408 * into a symbol table for a policy. This function will handle
1409 * inserting the appropriate scope information in addition to
1410 * inserting the symbol into the hash table.
1411 *
1412 * arguments:
1413 * policydb_t *pol module policy to modify
1414 * uint32_t sym the symbole table for insertion (SYM_*)
1415 * hashtab_key_t key the key for the symbol - not cloned
1416 * hashtab_datum_t data the data for the symbol - not cloned
1417 * scope scope of this symbol, either SCOPE_REQ or SCOPE_DECL
1418 * avrule_decl_id identifier for this symbol's encapsulating declaration
1419 * value (out) assigned value to the symbol (if value is not NULL)
1420 *
1421 * returns:
1422 * 0 success
1423 * 1 success, but symbol already existed as a requirement
1424 * (datum was not inserted and needs to be free()d)
1425 * -1 general error
1426 * -2 scope conflicted
1427 * -ENOMEM memory error
1428 * error codes from hashtab_insert
1429 */
symtab_insert(policydb_t * pol,uint32_t sym,hashtab_key_t key,hashtab_datum_t datum,uint32_t scope,uint32_t avrule_decl_id,uint32_t * value)1430 int symtab_insert(policydb_t * pol, uint32_t sym,
1431 hashtab_key_t key, hashtab_datum_t datum,
1432 uint32_t scope, uint32_t avrule_decl_id, uint32_t * value)
1433 {
1434 int rc, retval = 0;
1435 unsigned int i;
1436 scope_datum_t *scope_datum;
1437
1438 /* check if the symbol is already there. multiple
1439 * declarations of non-roles/non-users are illegal, but
1440 * multiple requires are allowed. */
1441
1442 /* FIX ME - the failures after the hashtab_insert will leave
1443 * the policy in a inconsistent state. */
1444 rc = hashtab_insert(pol->symtab[sym].table, key, datum);
1445 if (rc == SEPOL_OK) {
1446 /* if no value is passed in the symbol is not primary
1447 * (i.e. aliases) */
1448 if (value)
1449 *value = ++pol->symtab[sym].nprim;
1450 } else if (rc == SEPOL_EEXIST) {
1451 retval = 1; /* symbol not added -- need to free() later */
1452 } else {
1453 return rc;
1454 }
1455
1456 /* get existing scope information; if there is not one then
1457 * create it */
1458 scope_datum =
1459 (scope_datum_t *) hashtab_search(pol->scope[sym].table, key);
1460 if (scope_datum == NULL) {
1461 hashtab_key_t key2 = strdup((char *)key);
1462 if (!key2)
1463 return -ENOMEM;
1464 if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) {
1465 free(key2);
1466 return -ENOMEM;
1467 }
1468 scope_datum->scope = scope;
1469 scope_datum->decl_ids = NULL;
1470 scope_datum->decl_ids_len = 0;
1471 if ((rc =
1472 hashtab_insert(pol->scope[sym].table, key2,
1473 scope_datum)) != 0) {
1474 free(key2);
1475 free(scope_datum);
1476 return rc;
1477 }
1478 } else if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_DECL) {
1479 /* disallow multiple declarations for non-roles/users */
1480 if (sym != SYM_ROLES && sym != SYM_USERS) {
1481 return -2;
1482 }
1483 /* Further confine that a role attribute can't have the same
1484 * name as another regular role, and a role attribute can't
1485 * be declared more than once. */
1486 if (sym == SYM_ROLES) {
1487 role_datum_t *base_role;
1488 role_datum_t *cur_role = (role_datum_t *)datum;
1489
1490 base_role = (role_datum_t *)
1491 hashtab_search(pol->symtab[sym].table,
1492 key);
1493 assert(base_role != NULL);
1494
1495 if (!((base_role->flavor == ROLE_ROLE) &&
1496 (cur_role->flavor == ROLE_ROLE))) {
1497 /* Only regular roles are allowed to have
1498 * multiple declarations. */
1499 return -2;
1500 }
1501 }
1502 } else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) {
1503 scope_datum->scope = SCOPE_DECL;
1504 } else if (scope_datum->scope != scope) {
1505 /* This only happens in DECL then REQUIRE case, which is handled by caller */
1506 return -2;
1507 }
1508
1509 /* search through the pre-existing list to avoid adding duplicates */
1510 for (i = 0; i < scope_datum->decl_ids_len; i++) {
1511 if (scope_datum->decl_ids[i] == avrule_decl_id) {
1512 /* already there, so don't modify its scope */
1513 return retval;
1514 }
1515 }
1516
1517 if (add_i_to_a(avrule_decl_id,
1518 &scope_datum->decl_ids_len,
1519 &scope_datum->decl_ids) == -1) {
1520 return -ENOMEM;
1521 }
1522
1523 return retval;
1524 }
1525
type_set_or(type_set_t * dst,type_set_t * a,type_set_t * b)1526 int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b)
1527 {
1528 type_set_init(dst);
1529
1530 if (ebitmap_or(&dst->types, &a->types, &b->types)) {
1531 return -1;
1532 }
1533 if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) {
1534 return -1;
1535 }
1536
1537 dst->flags |= a->flags;
1538 dst->flags |= b->flags;
1539
1540 return 0;
1541 }
1542
type_set_cpy(type_set_t * dst,type_set_t * src)1543 int type_set_cpy(type_set_t * dst, type_set_t * src)
1544 {
1545 type_set_init(dst);
1546
1547 dst->flags = src->flags;
1548 if (ebitmap_cpy(&dst->types, &src->types))
1549 return -1;
1550 if (ebitmap_cpy(&dst->negset, &src->negset))
1551 return -1;
1552
1553 return 0;
1554 }
1555
type_set_or_eq(type_set_t * dst,type_set_t * other)1556 int type_set_or_eq(type_set_t * dst, type_set_t * other)
1557 {
1558 int ret;
1559 type_set_t tmp;
1560
1561 if (type_set_or(&tmp, dst, other))
1562 return -1;
1563 type_set_destroy(dst);
1564 ret = type_set_cpy(dst, &tmp);
1565 type_set_destroy(&tmp);
1566
1567 return ret;
1568 }
1569
role_set_get_role(role_set_t * x,uint32_t role)1570 int role_set_get_role(role_set_t * x, uint32_t role)
1571 {
1572 if (x->flags & ROLE_STAR)
1573 return 1;
1574
1575 if (ebitmap_get_bit(&x->roles, role - 1)) {
1576 if (x->flags & ROLE_COMP)
1577 return 0;
1578 else
1579 return 1;
1580 } else {
1581 if (x->flags & ROLE_COMP)
1582 return 1;
1583 else
1584 return 0;
1585 }
1586 }
1587
1588 /***********************************************************************/
1589 /* everything below is for policy reads */
1590
1591 /* The following are read functions for module structures */
1592
role_set_read(role_set_t * r,struct policy_file * fp)1593 static int role_set_read(role_set_t * r, struct policy_file *fp)
1594 {
1595 uint32_t buf[1];
1596 int rc;
1597
1598 if (ebitmap_read(&r->roles, fp))
1599 return -1;
1600 rc = next_entry(buf, fp, sizeof(uint32_t));
1601 if (rc < 0)
1602 return -1;
1603 r->flags = le32_to_cpu(buf[0]);
1604
1605 return 0;
1606 }
1607
type_set_read(type_set_t * t,struct policy_file * fp)1608 static int type_set_read(type_set_t * t, struct policy_file *fp)
1609 {
1610 uint32_t buf[1];
1611 int rc;
1612
1613 if (ebitmap_read(&t->types, fp))
1614 return -1;
1615 if (ebitmap_read(&t->negset, fp))
1616 return -1;
1617
1618 rc = next_entry(buf, fp, sizeof(uint32_t));
1619 if (rc < 0)
1620 return -1;
1621 t->flags = le32_to_cpu(buf[0]);
1622
1623 return 0;
1624 }
1625
1626 /*
1627 * Read a MLS range structure from a policydb binary
1628 * representation file.
1629 */
mls_read_range_helper(mls_range_t * r,struct policy_file * fp)1630 static int mls_read_range_helper(mls_range_t * r, struct policy_file *fp)
1631 {
1632 uint32_t buf[2], items;
1633 int rc;
1634
1635 rc = next_entry(buf, fp, sizeof(uint32_t));
1636 if (rc < 0)
1637 goto out;
1638
1639 items = le32_to_cpu(buf[0]);
1640 if (items > ARRAY_SIZE(buf)) {
1641 ERR(fp->handle, "range overflow");
1642 rc = -EINVAL;
1643 goto out;
1644 }
1645 rc = next_entry(buf, fp, sizeof(uint32_t) * items);
1646 if (rc < 0) {
1647 ERR(fp->handle, "truncated range");
1648 goto out;
1649 }
1650 r->level[0].sens = le32_to_cpu(buf[0]);
1651 if (items > 1)
1652 r->level[1].sens = le32_to_cpu(buf[1]);
1653 else
1654 r->level[1].sens = r->level[0].sens;
1655
1656 rc = ebitmap_read(&r->level[0].cat, fp);
1657 if (rc) {
1658 ERR(fp->handle, "error reading low categories");
1659 goto out;
1660 }
1661 if (items > 1) {
1662 rc = ebitmap_read(&r->level[1].cat, fp);
1663 if (rc) {
1664 ERR(fp->handle, "error reading high categories");
1665 goto bad_high;
1666 }
1667 } else {
1668 rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);
1669 if (rc) {
1670 ERR(fp->handle, "out of memory");
1671 goto bad_high;
1672 }
1673 }
1674
1675 rc = 0;
1676 out:
1677 return rc;
1678 bad_high:
1679 ebitmap_destroy(&r->level[0].cat);
1680 goto out;
1681 }
1682
1683 /*
1684 * Read a semantic MLS level structure from a policydb binary
1685 * representation file.
1686 */
mls_read_semantic_level_helper(mls_semantic_level_t * l,struct policy_file * fp)1687 static int mls_read_semantic_level_helper(mls_semantic_level_t * l,
1688 struct policy_file *fp)
1689 {
1690 uint32_t buf[2], ncat;
1691 unsigned int i;
1692 mls_semantic_cat_t *cat;
1693 int rc;
1694
1695 mls_semantic_level_init(l);
1696
1697 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
1698 if (rc < 0) {
1699 ERR(fp->handle, "truncated level");
1700 goto bad;
1701 }
1702 l->sens = le32_to_cpu(buf[0]);
1703
1704 ncat = le32_to_cpu(buf[1]);
1705 for (i = 0; i < ncat; i++) {
1706 cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
1707 if (!cat) {
1708 ERR(fp->handle, "out of memory");
1709 goto bad;
1710 }
1711
1712 mls_semantic_cat_init(cat);
1713 cat->next = l->cat;
1714 l->cat = cat;
1715
1716 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
1717 if (rc < 0) {
1718 ERR(fp->handle, "error reading level categories");
1719 goto bad;
1720 }
1721 cat->low = le32_to_cpu(buf[0]);
1722 cat->high = le32_to_cpu(buf[1]);
1723 }
1724
1725 return 0;
1726
1727 bad:
1728 return -EINVAL;
1729 }
1730
1731 /*
1732 * Read a semantic MLS range structure from a policydb binary
1733 * representation file.
1734 */
mls_read_semantic_range_helper(mls_semantic_range_t * r,struct policy_file * fp)1735 static int mls_read_semantic_range_helper(mls_semantic_range_t * r,
1736 struct policy_file *fp)
1737 {
1738 int rc;
1739
1740 rc = mls_read_semantic_level_helper(&r->level[0], fp);
1741 if (rc)
1742 return rc;
1743
1744 rc = mls_read_semantic_level_helper(&r->level[1], fp);
1745
1746 return rc;
1747 }
1748
mls_level_to_semantic(mls_level_t * l,mls_semantic_level_t * sl)1749 static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl)
1750 {
1751 unsigned int i;
1752 ebitmap_node_t *cnode;
1753 mls_semantic_cat_t *open_cat = NULL;
1754
1755 mls_semantic_level_init(sl);
1756 sl->sens = l->sens;
1757 ebitmap_for_each_bit(&l->cat, cnode, i) {
1758 if (ebitmap_node_get_bit(cnode, i)) {
1759 if (open_cat)
1760 continue;
1761 open_cat = (mls_semantic_cat_t *)
1762 malloc(sizeof(mls_semantic_cat_t));
1763 if (!open_cat)
1764 return -1;
1765
1766 mls_semantic_cat_init(open_cat);
1767 open_cat->low = i + 1;
1768 open_cat->next = sl->cat;
1769 sl->cat = open_cat;
1770 } else {
1771 if (!open_cat)
1772 continue;
1773 open_cat->high = i;
1774 open_cat = NULL;
1775 }
1776 }
1777 if (open_cat)
1778 open_cat->high = i;
1779
1780 return 0;
1781 }
1782
mls_range_to_semantic(mls_range_t * r,mls_semantic_range_t * sr)1783 static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr)
1784 {
1785 if (mls_level_to_semantic(&r->level[0], &sr->level[0]))
1786 return -1;
1787
1788 if (mls_level_to_semantic(&r->level[1], &sr->level[1]))
1789 return -1;
1790
1791 return 0;
1792 }
1793
1794 /*
1795 * Read and validate a security context structure
1796 * from a policydb binary representation file.
1797 */
context_read_and_validate(context_struct_t * c,policydb_t * p,struct policy_file * fp)1798 static int context_read_and_validate(context_struct_t * c,
1799 policydb_t * p, struct policy_file *fp)
1800 {
1801 uint32_t buf[3];
1802 int rc;
1803
1804 rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
1805 if (rc < 0) {
1806 ERR(fp->handle, "context truncated");
1807 return -1;
1808 }
1809 c->user = le32_to_cpu(buf[0]);
1810 c->role = le32_to_cpu(buf[1]);
1811 c->type = le32_to_cpu(buf[2]);
1812 if ((p->policy_type == POLICY_KERN
1813 && p->policyvers >= POLICYDB_VERSION_MLS)
1814 || (p->policy_type == POLICY_BASE
1815 && p->policyvers >= MOD_POLICYDB_VERSION_MLS)) {
1816 if (mls_read_range_helper(&c->range, fp)) {
1817 ERR(fp->handle, "error reading MLS range "
1818 "of context");
1819 return -1;
1820 }
1821 }
1822
1823 if (!policydb_context_isvalid(p, c)) {
1824 ERR(fp->handle, "invalid security context");
1825 context_destroy(c);
1826 return -1;
1827 }
1828 return 0;
1829 }
1830
1831 /*
1832 * The following *_read functions are used to
1833 * read the symbol data from a policy database
1834 * binary representation file.
1835 */
1836
perm_read(policydb_t * p,hashtab_t h,struct policy_file * fp)1837 static int perm_read(policydb_t * p
1838 __attribute__ ((unused)), hashtab_t h,
1839 struct policy_file *fp)
1840 {
1841 char *key = 0;
1842 perm_datum_t *perdatum;
1843 uint32_t buf[2];
1844 size_t len;
1845 int rc;
1846
1847 perdatum = calloc(1, sizeof(perm_datum_t));
1848 if (!perdatum)
1849 return -1;
1850
1851 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
1852 if (rc < 0)
1853 goto bad;
1854
1855 len = le32_to_cpu(buf[0]);
1856 perdatum->s.value = le32_to_cpu(buf[1]);
1857
1858 key = malloc(len + 1);
1859 if (!key)
1860 goto bad;
1861 rc = next_entry(key, fp, len);
1862 if (rc < 0)
1863 goto bad;
1864 key[len] = 0;
1865
1866 if (hashtab_insert(h, key, perdatum))
1867 goto bad;
1868
1869 return 0;
1870
1871 bad:
1872 perm_destroy(key, perdatum, NULL);
1873 return -1;
1874 }
1875
common_read(policydb_t * p,hashtab_t h,struct policy_file * fp)1876 static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
1877 {
1878 char *key = 0;
1879 common_datum_t *comdatum;
1880 uint32_t buf[4];
1881 size_t len, nel;
1882 unsigned int i;
1883 int rc;
1884
1885 comdatum = calloc(1, sizeof(common_datum_t));
1886 if (!comdatum)
1887 return -1;
1888
1889 rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
1890 if (rc < 0)
1891 goto bad;
1892
1893 len = le32_to_cpu(buf[0]);
1894 comdatum->s.value = le32_to_cpu(buf[1]);
1895
1896 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE))
1897 goto bad;
1898 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1899 nel = le32_to_cpu(buf[3]);
1900
1901 key = malloc(len + 1);
1902 if (!key)
1903 goto bad;
1904 rc = next_entry(key, fp, len);
1905 if (rc < 0)
1906 goto bad;
1907 key[len] = 0;
1908
1909 for (i = 0; i < nel; i++) {
1910 if (perm_read(p, comdatum->permissions.table, fp))
1911 goto bad;
1912 }
1913
1914 if (hashtab_insert(h, key, comdatum))
1915 goto bad;
1916
1917 return 0;
1918
1919 bad:
1920 common_destroy(key, comdatum, NULL);
1921 return -1;
1922 }
1923
read_cons_helper(policydb_t * p,constraint_node_t ** nodep,unsigned int ncons,int allowxtarget,struct policy_file * fp)1924 static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep,
1925 unsigned int ncons,
1926 int allowxtarget, struct policy_file *fp)
1927 {
1928 constraint_node_t *c, *lc;
1929 constraint_expr_t *e, *le;
1930 uint32_t buf[3];
1931 size_t nexpr;
1932 unsigned int i, j;
1933 int rc, depth;
1934
1935 lc = NULL;
1936 for (i = 0; i < ncons; i++) {
1937 c = calloc(1, sizeof(constraint_node_t));
1938 if (!c)
1939 return -1;
1940
1941 if (lc)
1942 lc->next = c;
1943 else
1944 *nodep = c;
1945
1946 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
1947 if (rc < 0)
1948 return -1;
1949 c->permissions = le32_to_cpu(buf[0]);
1950 nexpr = le32_to_cpu(buf[1]);
1951 le = NULL;
1952 depth = -1;
1953 for (j = 0; j < nexpr; j++) {
1954 e = malloc(sizeof(constraint_expr_t));
1955 if (!e)
1956 return -1;
1957 if (constraint_expr_init(e) == -1) {
1958 free(e);
1959 return -1;
1960 }
1961 if (le) {
1962 le->next = e;
1963 } else {
1964 c->expr = e;
1965 }
1966
1967 rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
1968 if (rc < 0)
1969 return -1;
1970 e->expr_type = le32_to_cpu(buf[0]);
1971 e->attr = le32_to_cpu(buf[1]);
1972 e->op = le32_to_cpu(buf[2]);
1973
1974 switch (e->expr_type) {
1975 case CEXPR_NOT:
1976 if (depth < 0)
1977 return -1;
1978 break;
1979 case CEXPR_AND:
1980 case CEXPR_OR:
1981 if (depth < 1)
1982 return -1;
1983 depth--;
1984 break;
1985 case CEXPR_ATTR:
1986 if (depth == (CEXPR_MAXDEPTH - 1))
1987 return -1;
1988 depth++;
1989 break;
1990 case CEXPR_NAMES:
1991 if (!allowxtarget && (e->attr & CEXPR_XTARGET))
1992 return -1;
1993 if (depth == (CEXPR_MAXDEPTH - 1))
1994 return -1;
1995 depth++;
1996 if (ebitmap_read(&e->names, fp))
1997 return -1;
1998 if (p->policy_type != POLICY_KERN &&
1999 type_set_read(e->type_names, fp))
2000 return -1;
2001 break;
2002 default:
2003 return -1;
2004 }
2005 le = e;
2006 }
2007 if (depth != 0)
2008 return -1;
2009 lc = c;
2010 }
2011
2012 return 0;
2013 }
2014
class_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2015 static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2016 {
2017 char *key = 0;
2018 class_datum_t *cladatum;
2019 uint32_t buf[6];
2020 size_t len, len2, ncons, nel;
2021 unsigned int i;
2022 int rc;
2023
2024 cladatum = (class_datum_t *) calloc(1, sizeof(class_datum_t));
2025 if (!cladatum)
2026 return -1;
2027
2028 rc = next_entry(buf, fp, sizeof(uint32_t) * 6);
2029 if (rc < 0)
2030 goto bad;
2031
2032 len = le32_to_cpu(buf[0]);
2033 len2 = le32_to_cpu(buf[1]);
2034 cladatum->s.value = le32_to_cpu(buf[2]);
2035
2036 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE))
2037 goto bad;
2038 cladatum->permissions.nprim = le32_to_cpu(buf[3]);
2039 nel = le32_to_cpu(buf[4]);
2040
2041 ncons = le32_to_cpu(buf[5]);
2042
2043 key = malloc(len + 1);
2044 if (!key)
2045 goto bad;
2046 rc = next_entry(key, fp, len);
2047 if (rc < 0)
2048 goto bad;
2049 key[len] = 0;
2050
2051 if (len2) {
2052 cladatum->comkey = malloc(len2 + 1);
2053 if (!cladatum->comkey)
2054 goto bad;
2055 rc = next_entry(cladatum->comkey, fp, len2);
2056 if (rc < 0)
2057 goto bad;
2058 cladatum->comkey[len2] = 0;
2059
2060 cladatum->comdatum = hashtab_search(p->p_commons.table,
2061 cladatum->comkey);
2062 if (!cladatum->comdatum) {
2063 ERR(fp->handle, "unknown common %s", cladatum->comkey);
2064 goto bad;
2065 }
2066 }
2067 for (i = 0; i < nel; i++) {
2068 if (perm_read(p, cladatum->permissions.table, fp))
2069 goto bad;
2070 }
2071
2072 if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp))
2073 goto bad;
2074
2075 if ((p->policy_type == POLICY_KERN
2076 && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
2077 || (p->policy_type == POLICY_BASE
2078 && p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) {
2079 /* grab the validatetrans rules */
2080 rc = next_entry(buf, fp, sizeof(uint32_t));
2081 if (rc < 0)
2082 goto bad;
2083 ncons = le32_to_cpu(buf[0]);
2084 if (read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp))
2085 goto bad;
2086 }
2087
2088 if ((p->policy_type == POLICY_KERN &&
2089 p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) ||
2090 (p->policy_type == POLICY_BASE &&
2091 p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) {
2092 rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2093 if (rc < 0)
2094 goto bad;
2095 cladatum->default_user = le32_to_cpu(buf[0]);
2096 cladatum->default_role = le32_to_cpu(buf[1]);
2097 cladatum->default_range = le32_to_cpu(buf[2]);
2098 }
2099
2100 if (hashtab_insert(h, key, cladatum))
2101 goto bad;
2102
2103 return 0;
2104
2105 bad:
2106 class_destroy(key, cladatum, NULL);
2107 return -1;
2108 }
2109
role_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2110 static int role_read(policydb_t * p
2111 __attribute__ ((unused)), hashtab_t h,
2112 struct policy_file *fp)
2113 {
2114 char *key = 0;
2115 role_datum_t *role;
2116 uint32_t buf[3];
2117 size_t len;
2118 int rc, to_read = 2;
2119
2120 role = calloc(1, sizeof(role_datum_t));
2121 if (!role)
2122 return -1;
2123
2124 if (policydb_has_boundary_feature(p))
2125 to_read = 3;
2126
2127 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
2128 if (rc < 0)
2129 goto bad;
2130
2131 len = le32_to_cpu(buf[0]);
2132 role->s.value = le32_to_cpu(buf[1]);
2133 if (policydb_has_boundary_feature(p))
2134 role->bounds = le32_to_cpu(buf[2]);
2135
2136 key = malloc(len + 1);
2137 if (!key)
2138 goto bad;
2139 rc = next_entry(key, fp, len);
2140 if (rc < 0)
2141 goto bad;
2142 key[len] = 0;
2143
2144 if (ebitmap_read(&role->dominates, fp))
2145 goto bad;
2146
2147 if (p->policy_type == POLICY_KERN) {
2148 if (ebitmap_read(&role->types.types, fp))
2149 goto bad;
2150 } else {
2151 if (type_set_read(&role->types, fp))
2152 goto bad;
2153 }
2154
2155 if (p->policy_type != POLICY_KERN &&
2156 p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) {
2157 rc = next_entry(buf, fp, sizeof(uint32_t));
2158 if (rc < 0)
2159 goto bad;
2160
2161 role->flavor = le32_to_cpu(buf[0]);
2162
2163 if (ebitmap_read(&role->roles, fp))
2164 goto bad;
2165 }
2166
2167 if (strcmp(key, OBJECT_R) == 0) {
2168 if (role->s.value != OBJECT_R_VAL) {
2169 ERR(fp->handle, "role %s has wrong value %d",
2170 OBJECT_R, role->s.value);
2171 role_destroy(key, role, NULL);
2172 return -1;
2173 }
2174 role_destroy(key, role, NULL);
2175 return 0;
2176 }
2177
2178 if (hashtab_insert(h, key, role))
2179 goto bad;
2180
2181 return 0;
2182
2183 bad:
2184 role_destroy(key, role, NULL);
2185 return -1;
2186 }
2187
type_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2188 static int type_read(policydb_t * p
2189 __attribute__ ((unused)), hashtab_t h,
2190 struct policy_file *fp)
2191 {
2192 char *key = 0;
2193 type_datum_t *typdatum;
2194 uint32_t buf[5];
2195 size_t len;
2196 int rc, to_read;
2197 int pos = 0;
2198
2199 typdatum = calloc(1, sizeof(type_datum_t));
2200 if (!typdatum)
2201 return -1;
2202
2203 if (policydb_has_boundary_feature(p)) {
2204 if (p->policy_type != POLICY_KERN
2205 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS)
2206 to_read = 5;
2207 else
2208 to_read = 4;
2209 }
2210 else if (p->policy_type == POLICY_KERN)
2211 to_read = 3;
2212 else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
2213 to_read = 5;
2214 else
2215 to_read = 4;
2216
2217 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
2218 if (rc < 0)
2219 goto bad;
2220
2221 len = le32_to_cpu(buf[pos]);
2222 typdatum->s.value = le32_to_cpu(buf[++pos]);
2223 if (policydb_has_boundary_feature(p)) {
2224 uint32_t properties;
2225
2226 if (p->policy_type != POLICY_KERN
2227 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) {
2228 typdatum->primary = le32_to_cpu(buf[++pos]);
2229 properties = le32_to_cpu(buf[++pos]);
2230 }
2231 else {
2232 properties = le32_to_cpu(buf[++pos]);
2233
2234 if (properties & TYPEDATUM_PROPERTY_PRIMARY)
2235 typdatum->primary = 1;
2236 }
2237
2238 if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE)
2239 typdatum->flavor = TYPE_ATTRIB;
2240 if (properties & TYPEDATUM_PROPERTY_ALIAS
2241 && p->policy_type != POLICY_KERN)
2242 typdatum->flavor = TYPE_ALIAS;
2243 if (properties & TYPEDATUM_PROPERTY_PERMISSIVE
2244 && p->policy_type != POLICY_KERN)
2245 typdatum->flags |= TYPE_FLAGS_PERMISSIVE;
2246
2247 typdatum->bounds = le32_to_cpu(buf[++pos]);
2248 } else {
2249 typdatum->primary = le32_to_cpu(buf[++pos]);
2250 if (p->policy_type != POLICY_KERN) {
2251 typdatum->flavor = le32_to_cpu(buf[++pos]);
2252 if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
2253 typdatum->flags = le32_to_cpu(buf[++pos]);
2254 }
2255 }
2256
2257 if (p->policy_type != POLICY_KERN) {
2258 if (ebitmap_read(&typdatum->types, fp))
2259 goto bad;
2260 }
2261
2262 key = malloc(len + 1);
2263 if (!key)
2264 goto bad;
2265 rc = next_entry(key, fp, len);
2266 if (rc < 0)
2267 goto bad;
2268 key[len] = 0;
2269
2270 if (hashtab_insert(h, key, typdatum))
2271 goto bad;
2272
2273 return 0;
2274
2275 bad:
2276 type_destroy(key, typdatum, NULL);
2277 return -1;
2278 }
2279
role_trans_read(policydb_t * p,struct policy_file * fp)2280 int role_trans_read(policydb_t *p, struct policy_file *fp)
2281 {
2282 role_trans_t **t = &p->role_tr;
2283 unsigned int i;
2284 uint32_t buf[3], nel;
2285 role_trans_t *tr, *ltr;
2286 int rc;
2287 int new_roletr = (p->policy_type == POLICY_KERN &&
2288 p->policyvers >= POLICYDB_VERSION_ROLETRANS);
2289
2290 rc = next_entry(buf, fp, sizeof(uint32_t));
2291 if (rc < 0)
2292 return -1;
2293 nel = le32_to_cpu(buf[0]);
2294 ltr = NULL;
2295 for (i = 0; i < nel; i++) {
2296 tr = calloc(1, sizeof(struct role_trans));
2297 if (!tr) {
2298 return -1;
2299 }
2300 if (ltr) {
2301 ltr->next = tr;
2302 } else {
2303 *t = tr;
2304 }
2305 rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2306 if (rc < 0)
2307 return -1;
2308 tr->role = le32_to_cpu(buf[0]);
2309 tr->type = le32_to_cpu(buf[1]);
2310 tr->new_role = le32_to_cpu(buf[2]);
2311 if (new_roletr) {
2312 rc = next_entry(buf, fp, sizeof(uint32_t));
2313 if (rc < 0)
2314 return -1;
2315 tr->tclass = le32_to_cpu(buf[0]);
2316 } else
2317 tr->tclass = SECCLASS_PROCESS;
2318 ltr = tr;
2319 }
2320 return 0;
2321 }
2322
role_allow_read(role_allow_t ** r,struct policy_file * fp)2323 int role_allow_read(role_allow_t ** r, struct policy_file *fp)
2324 {
2325 unsigned int i;
2326 uint32_t buf[2], nel;
2327 role_allow_t *ra, *lra;
2328 int rc;
2329
2330 rc = next_entry(buf, fp, sizeof(uint32_t));
2331 if (rc < 0)
2332 return -1;
2333 nel = le32_to_cpu(buf[0]);
2334 lra = NULL;
2335 for (i = 0; i < nel; i++) {
2336 ra = calloc(1, sizeof(struct role_allow));
2337 if (!ra) {
2338 return -1;
2339 }
2340 if (lra) {
2341 lra->next = ra;
2342 } else {
2343 *r = ra;
2344 }
2345 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2346 if (rc < 0)
2347 return -1;
2348 ra->role = le32_to_cpu(buf[0]);
2349 ra->new_role = le32_to_cpu(buf[1]);
2350 lra = ra;
2351 }
2352 return 0;
2353 }
2354
filename_trans_read(filename_trans_t ** t,struct policy_file * fp)2355 int filename_trans_read(filename_trans_t **t, struct policy_file *fp)
2356 {
2357 unsigned int i;
2358 uint32_t buf[4], nel, len;
2359 filename_trans_t *ft, *lft;
2360 int rc;
2361 char *name;
2362
2363 rc = next_entry(buf, fp, sizeof(uint32_t));
2364 if (rc < 0)
2365 return -1;
2366 nel = le32_to_cpu(buf[0]);
2367
2368 lft = NULL;
2369 for (i = 0; i < nel; i++) {
2370 ft = calloc(1, sizeof(struct filename_trans));
2371 if (!ft)
2372 return -1;
2373 if (lft)
2374 lft->next = ft;
2375 else
2376 *t = ft;
2377 lft = ft;
2378 rc = next_entry(buf, fp, sizeof(uint32_t));
2379 if (rc < 0)
2380 return -1;
2381 len = le32_to_cpu(buf[0]);
2382
2383 name = calloc(len + 1, sizeof(*name));
2384 if (!name)
2385 return -1;
2386
2387 ft->name = name;
2388
2389 rc = next_entry(name, fp, len);
2390 if (rc < 0)
2391 return -1;
2392
2393 rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
2394 if (rc < 0)
2395 return -1;
2396
2397 ft->stype = le32_to_cpu(buf[0]);
2398 ft->ttype = le32_to_cpu(buf[1]);
2399 ft->tclass = le32_to_cpu(buf[2]);
2400 ft->otype = le32_to_cpu(buf[3]);
2401 }
2402 return 0;
2403 }
2404
ocontext_read_xen(struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)2405 static int ocontext_read_xen(struct policydb_compat_info *info,
2406 policydb_t *p, struct policy_file *fp)
2407 {
2408 unsigned int i, j;
2409 size_t nel;
2410 ocontext_t *l, *c;
2411 uint32_t buf[8];
2412 int rc;
2413
2414 for (i = 0; i < info->ocon_num; i++) {
2415 rc = next_entry(buf, fp, sizeof(uint32_t));
2416 if (rc < 0)
2417 return -1;
2418 nel = le32_to_cpu(buf[0]);
2419 l = NULL;
2420 for (j = 0; j < nel; j++) {
2421 c = calloc(1, sizeof(ocontext_t));
2422 if (!c)
2423 return -1;
2424 if (l)
2425 l->next = c;
2426 else
2427 p->ocontexts[i] = c;
2428 l = c;
2429 switch (i) {
2430 case OCON_XEN_ISID:
2431 rc = next_entry(buf, fp, sizeof(uint32_t));
2432 if (rc < 0)
2433 return -1;
2434 c->sid[0] = le32_to_cpu(buf[0]);
2435 if (context_read_and_validate
2436 (&c->context[0], p, fp))
2437 return -1;
2438 break;
2439 case OCON_XEN_PIRQ:
2440 rc = next_entry(buf, fp, sizeof(uint32_t));
2441 if (rc < 0)
2442 return -1;
2443 c->u.pirq = le32_to_cpu(buf[0]);
2444 if (context_read_and_validate
2445 (&c->context[0], p, fp))
2446 return -1;
2447 break;
2448 case OCON_XEN_IOPORT:
2449 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2450 if (rc < 0)
2451 return -1;
2452 c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
2453 c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
2454 if (context_read_and_validate
2455 (&c->context[0], p, fp))
2456 return -1;
2457 break;
2458 case OCON_XEN_IOMEM:
2459 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2460 if (rc < 0)
2461 return -1;
2462 c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
2463 c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
2464 if (context_read_and_validate
2465 (&c->context[0], p, fp))
2466 return -1;
2467 break;
2468 case OCON_XEN_PCIDEVICE:
2469 rc = next_entry(buf, fp, sizeof(uint32_t));
2470 if (rc < 0)
2471 return -1;
2472 c->u.device = le32_to_cpu(buf[0]);
2473 if (context_read_and_validate
2474 (&c->context[0], p, fp))
2475 return -1;
2476 break;
2477 default:
2478 /* should never get here */
2479 ERR(fp->handle, "Unknown Xen ocontext");
2480 return -1;
2481 }
2482 }
2483 }
2484 return 0;
2485 }
ocontext_read_selinux(struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)2486 static int ocontext_read_selinux(struct policydb_compat_info *info,
2487 policydb_t * p, struct policy_file *fp)
2488 {
2489 unsigned int i, j;
2490 size_t nel, len;
2491 ocontext_t *l, *c;
2492 uint32_t buf[8];
2493 int rc;
2494
2495 for (i = 0; i < info->ocon_num; i++) {
2496 rc = next_entry(buf, fp, sizeof(uint32_t));
2497 if (rc < 0)
2498 return -1;
2499 nel = le32_to_cpu(buf[0]);
2500 l = NULL;
2501 for (j = 0; j < nel; j++) {
2502 c = calloc(1, sizeof(ocontext_t));
2503 if (!c) {
2504 return -1;
2505 }
2506 if (l) {
2507 l->next = c;
2508 } else {
2509 p->ocontexts[i] = c;
2510 }
2511 l = c;
2512 switch (i) {
2513 case OCON_ISID:
2514 rc = next_entry(buf, fp, sizeof(uint32_t));
2515 if (rc < 0)
2516 return -1;
2517 c->sid[0] = le32_to_cpu(buf[0]);
2518 if (context_read_and_validate
2519 (&c->context[0], p, fp))
2520 return -1;
2521 break;
2522 case OCON_FS:
2523 case OCON_NETIF:
2524 rc = next_entry(buf, fp, sizeof(uint32_t));
2525 if (rc < 0)
2526 return -1;
2527 len = le32_to_cpu(buf[0]);
2528 c->u.name = malloc(len + 1);
2529 if (!c->u.name)
2530 return -1;
2531 rc = next_entry(c->u.name, fp, len);
2532 if (rc < 0)
2533 return -1;
2534 c->u.name[len] = 0;
2535 if (context_read_and_validate
2536 (&c->context[0], p, fp))
2537 return -1;
2538 if (context_read_and_validate
2539 (&c->context[1], p, fp))
2540 return -1;
2541 break;
2542 case OCON_PORT:
2543 rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
2544 if (rc < 0)
2545 return -1;
2546 c->u.port.protocol = le32_to_cpu(buf[0]);
2547 c->u.port.low_port = le32_to_cpu(buf[1]);
2548 c->u.port.high_port = le32_to_cpu(buf[2]);
2549 if (context_read_and_validate
2550 (&c->context[0], p, fp))
2551 return -1;
2552 break;
2553 case OCON_NODE:
2554 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2555 if (rc < 0)
2556 return -1;
2557 c->u.node.addr = buf[0]; /* network order */
2558 c->u.node.mask = buf[1]; /* network order */
2559 if (context_read_and_validate
2560 (&c->context[0], p, fp))
2561 return -1;
2562 break;
2563 case OCON_FSUSE:
2564 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2565 if (rc < 0)
2566 return -1;
2567 c->v.behavior = le32_to_cpu(buf[0]);
2568 len = le32_to_cpu(buf[1]);
2569 c->u.name = malloc(len + 1);
2570 if (!c->u.name)
2571 return -1;
2572 rc = next_entry(c->u.name, fp, len);
2573 if (rc < 0)
2574 return -1;
2575 c->u.name[len] = 0;
2576 if (context_read_and_validate
2577 (&c->context[0], p, fp))
2578 return -1;
2579 break;
2580 case OCON_NODE6:{
2581 int k;
2582
2583 rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
2584 if (rc < 0)
2585 return -1;
2586 for (k = 0; k < 4; k++)
2587 /* network order */
2588 c->u.node6.addr[k] = buf[k];
2589 for (k = 0; k < 4; k++)
2590 /* network order */
2591 c->u.node6.mask[k] = buf[k + 4];
2592 if (context_read_and_validate
2593 (&c->context[0], p, fp))
2594 return -1;
2595 break;
2596 }
2597 default:{
2598 ERR(fp->handle, "Unknown SELinux ocontext");
2599 return -1;
2600 }
2601 }
2602 }
2603 }
2604 return 0;
2605 }
2606
ocontext_read(struct policydb_compat_info * info,policydb_t * p,struct policy_file * fp)2607 static int ocontext_read(struct policydb_compat_info *info,
2608 policydb_t *p, struct policy_file *fp)
2609 {
2610 int rc = -1;
2611 switch (p->target_platform) {
2612 case SEPOL_TARGET_SELINUX:
2613 rc = ocontext_read_selinux(info, p, fp);
2614 break;
2615 case SEPOL_TARGET_XEN:
2616 rc = ocontext_read_xen(info, p, fp);
2617 break;
2618 default:
2619 ERR(fp->handle, "Unknown target");
2620 }
2621 return rc;
2622 }
2623
genfs_read(policydb_t * p,struct policy_file * fp)2624 static int genfs_read(policydb_t * p, struct policy_file *fp)
2625 {
2626 uint32_t buf[1];
2627 size_t nel, nel2, len, len2;
2628 genfs_t *genfs_p, *newgenfs, *genfs;
2629 unsigned int i, j;
2630 ocontext_t *l, *c, *newc = NULL;
2631 int rc;
2632
2633 rc = next_entry(buf, fp, sizeof(uint32_t));
2634 if (rc < 0)
2635 goto bad;
2636 nel = le32_to_cpu(buf[0]);
2637 genfs_p = NULL;
2638 for (i = 0; i < nel; i++) {
2639 rc = next_entry(buf, fp, sizeof(uint32_t));
2640 if (rc < 0)
2641 goto bad;
2642 len = le32_to_cpu(buf[0]);
2643 newgenfs = calloc(1, sizeof(genfs_t));
2644 if (!newgenfs)
2645 goto bad;
2646 newgenfs->fstype = malloc(len + 1);
2647 if (!newgenfs->fstype) {
2648 free(newgenfs);
2649 goto bad;
2650 }
2651 rc = next_entry(newgenfs->fstype, fp, len);
2652 if (rc < 0) {
2653 free(newgenfs->fstype);
2654 free(newgenfs);
2655 goto bad;
2656 }
2657 newgenfs->fstype[len] = 0;
2658 for (genfs_p = NULL, genfs = p->genfs; genfs;
2659 genfs_p = genfs, genfs = genfs->next) {
2660 if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
2661 ERR(fp->handle, "dup genfs fstype %s",
2662 newgenfs->fstype);
2663 free(newgenfs->fstype);
2664 free(newgenfs);
2665 goto bad;
2666 }
2667 if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
2668 break;
2669 }
2670 newgenfs->next = genfs;
2671 if (genfs_p)
2672 genfs_p->next = newgenfs;
2673 else
2674 p->genfs = newgenfs;
2675 rc = next_entry(buf, fp, sizeof(uint32_t));
2676 if (rc < 0)
2677 goto bad;
2678 nel2 = le32_to_cpu(buf[0]);
2679 for (j = 0; j < nel2; j++) {
2680 newc = calloc(1, sizeof(ocontext_t));
2681 if (!newc) {
2682 goto bad;
2683 }
2684 rc = next_entry(buf, fp, sizeof(uint32_t));
2685 if (rc < 0)
2686 goto bad;
2687 len = le32_to_cpu(buf[0]);
2688 newc->u.name = malloc(len + 1);
2689 if (!newc->u.name) {
2690 goto bad;
2691 }
2692 rc = next_entry(newc->u.name, fp, len);
2693 if (rc < 0)
2694 goto bad;
2695 newc->u.name[len] = 0;
2696 rc = next_entry(buf, fp, sizeof(uint32_t));
2697 if (rc < 0)
2698 goto bad;
2699 newc->v.sclass = le32_to_cpu(buf[0]);
2700 if (context_read_and_validate(&newc->context[0], p, fp))
2701 goto bad;
2702 for (l = NULL, c = newgenfs->head; c;
2703 l = c, c = c->next) {
2704 if (!strcmp(newc->u.name, c->u.name) &&
2705 (!c->v.sclass || !newc->v.sclass ||
2706 newc->v.sclass == c->v.sclass)) {
2707 ERR(fp->handle, "dup genfs entry "
2708 "(%s,%s)", newgenfs->fstype,
2709 c->u.name);
2710 goto bad;
2711 }
2712 len = strlen(newc->u.name);
2713 len2 = strlen(c->u.name);
2714 if (len > len2)
2715 break;
2716 }
2717 newc->next = c;
2718 if (l)
2719 l->next = newc;
2720 else
2721 newgenfs->head = newc;
2722 }
2723 }
2724
2725 return 0;
2726
2727 bad:
2728 if (newc) {
2729 context_destroy(&newc->context[0]);
2730 context_destroy(&newc->context[1]);
2731 free(newc->u.name);
2732 free(newc);
2733 }
2734 return -1;
2735 }
2736
2737 /*
2738 * Read a MLS level structure from a policydb binary
2739 * representation file.
2740 */
mls_read_level(mls_level_t * lp,struct policy_file * fp)2741 static int mls_read_level(mls_level_t * lp, struct policy_file *fp)
2742 {
2743 uint32_t buf[1];
2744 int rc;
2745
2746 mls_level_init(lp);
2747
2748 rc = next_entry(buf, fp, sizeof(uint32_t));
2749 if (rc < 0) {
2750 ERR(fp->handle, "truncated level");
2751 goto bad;
2752 }
2753 lp->sens = le32_to_cpu(buf[0]);
2754
2755 if (ebitmap_read(&lp->cat, fp)) {
2756 ERR(fp->handle, "error reading level categories");
2757 goto bad;
2758 }
2759 return 0;
2760
2761 bad:
2762 return -EINVAL;
2763 }
2764
user_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2765 static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
2766 {
2767 char *key = 0;
2768 user_datum_t *usrdatum;
2769 uint32_t buf[3];
2770 size_t len;
2771 int rc, to_read = 2;
2772
2773 usrdatum = calloc(1, sizeof(user_datum_t));
2774 if (!usrdatum)
2775 return -1;
2776
2777 if (policydb_has_boundary_feature(p))
2778 to_read = 3;
2779
2780 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
2781 if (rc < 0)
2782 goto bad;
2783
2784 len = le32_to_cpu(buf[0]);
2785 usrdatum->s.value = le32_to_cpu(buf[1]);
2786 if (policydb_has_boundary_feature(p))
2787 usrdatum->bounds = le32_to_cpu(buf[2]);
2788
2789 key = malloc(len + 1);
2790 if (!key)
2791 goto bad;
2792 rc = next_entry(key, fp, len);
2793 if (rc < 0)
2794 goto bad;
2795 key[len] = 0;
2796
2797 if (p->policy_type == POLICY_KERN) {
2798 if (ebitmap_read(&usrdatum->roles.roles, fp))
2799 goto bad;
2800 } else {
2801 if (role_set_read(&usrdatum->roles, fp))
2802 goto bad;
2803 }
2804
2805 /* users were not allowed in mls modules before version
2806 * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been
2807 * required - the mls fields will be empty. user declarations in
2808 * non-mls modules will also have empty mls fields */
2809 if ((p->policy_type == POLICY_KERN
2810 && p->policyvers >= POLICYDB_VERSION_MLS)
2811 || (p->policy_type == POLICY_MOD
2812 && p->policyvers >= MOD_POLICYDB_VERSION_MLS
2813 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)
2814 || (p->policy_type == POLICY_BASE
2815 && p->policyvers >= MOD_POLICYDB_VERSION_MLS
2816 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) {
2817 if (mls_read_range_helper(&usrdatum->exp_range, fp))
2818 goto bad;
2819 if (mls_read_level(&usrdatum->exp_dfltlevel, fp))
2820 goto bad;
2821 if (p->policy_type != POLICY_KERN) {
2822 if (mls_range_to_semantic(&usrdatum->exp_range,
2823 &usrdatum->range))
2824 goto bad;
2825 if (mls_level_to_semantic(&usrdatum->exp_dfltlevel,
2826 &usrdatum->dfltlevel))
2827 goto bad;
2828 }
2829 } else if ((p->policy_type == POLICY_MOD
2830 && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)
2831 || (p->policy_type == POLICY_BASE
2832 && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) {
2833 if (mls_read_semantic_range_helper(&usrdatum->range, fp))
2834 goto bad;
2835 if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp))
2836 goto bad;
2837 }
2838
2839 if (hashtab_insert(h, key, usrdatum))
2840 goto bad;
2841
2842 return 0;
2843
2844 bad:
2845 user_destroy(key, usrdatum, NULL);
2846 return -1;
2847 }
2848
sens_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2849 static int sens_read(policydb_t * p
2850 __attribute__ ((unused)), hashtab_t h,
2851 struct policy_file *fp)
2852 {
2853 char *key = 0;
2854 level_datum_t *levdatum;
2855 uint32_t buf[2], len;
2856 int rc;
2857
2858 levdatum = malloc(sizeof(level_datum_t));
2859 if (!levdatum)
2860 return -1;
2861 level_datum_init(levdatum);
2862
2863 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
2864 if (rc < 0)
2865 goto bad;
2866
2867 len = le32_to_cpu(buf[0]);
2868 levdatum->isalias = le32_to_cpu(buf[1]);
2869
2870 key = malloc(len + 1);
2871 if (!key)
2872 goto bad;
2873 rc = next_entry(key, fp, len);
2874 if (rc < 0)
2875 goto bad;
2876 key[len] = 0;
2877
2878 levdatum->level = malloc(sizeof(mls_level_t));
2879 if (!levdatum->level || mls_read_level(levdatum->level, fp))
2880 goto bad;
2881
2882 if (hashtab_insert(h, key, levdatum))
2883 goto bad;
2884
2885 return 0;
2886
2887 bad:
2888 sens_destroy(key, levdatum, NULL);
2889 return -1;
2890 }
2891
cat_read(policydb_t * p,hashtab_t h,struct policy_file * fp)2892 static int cat_read(policydb_t * p
2893 __attribute__ ((unused)), hashtab_t h,
2894 struct policy_file *fp)
2895 {
2896 char *key = 0;
2897 cat_datum_t *catdatum;
2898 uint32_t buf[3], len;
2899 int rc;
2900
2901 catdatum = malloc(sizeof(cat_datum_t));
2902 if (!catdatum)
2903 return -1;
2904 cat_datum_init(catdatum);
2905
2906 rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
2907 if (rc < 0)
2908 goto bad;
2909
2910 len = le32_to_cpu(buf[0]);
2911 catdatum->s.value = le32_to_cpu(buf[1]);
2912 catdatum->isalias = le32_to_cpu(buf[2]);
2913
2914 key = malloc(len + 1);
2915 if (!key)
2916 goto bad;
2917 rc = next_entry(key, fp, len);
2918 if (rc < 0)
2919 goto bad;
2920 key[len] = 0;
2921
2922 if (hashtab_insert(h, key, catdatum))
2923 goto bad;
2924
2925 return 0;
2926
2927 bad:
2928 cat_destroy(key, catdatum, NULL);
2929 return -1;
2930 }
2931
2932 static int (*read_f[SYM_NUM]) (policydb_t * p, hashtab_t h,
2933 struct policy_file * fp) = {
2934 common_read, class_read, role_read, type_read, user_read,
2935 cond_read_bool, sens_read, cat_read,};
2936
2937 /************** module reading functions below **************/
2938
avrule_read(policydb_t * p,struct policy_file * fp)2939 static avrule_t *avrule_read(policydb_t * p
2940 __attribute__ ((unused)), struct policy_file *fp)
2941 {
2942 unsigned int i;
2943 uint32_t buf[2], len;
2944 class_perm_node_t *cur, *tail = NULL;
2945 avrule_t *avrule;
2946 int rc;
2947
2948 avrule = (avrule_t *) malloc(sizeof(avrule_t));
2949 if (!avrule)
2950 return NULL;
2951
2952 avrule_init(avrule);
2953
2954 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2955 if (rc < 0)
2956 goto bad;
2957
2958 (avrule)->specified = le32_to_cpu(buf[0]);
2959 (avrule)->flags = le32_to_cpu(buf[1]);
2960
2961 if (type_set_read(&avrule->stypes, fp))
2962 goto bad;
2963
2964 if (type_set_read(&avrule->ttypes, fp))
2965 goto bad;
2966
2967 rc = next_entry(buf, fp, sizeof(uint32_t));
2968 if (rc < 0)
2969 goto bad;
2970 len = le32_to_cpu(buf[0]);
2971
2972 for (i = 0; i < len; i++) {
2973 cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2974 if (!cur)
2975 goto bad;
2976 class_perm_node_init(cur);
2977
2978 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
2979 if (rc < 0) {
2980 free(cur);
2981 goto bad;
2982 }
2983
2984 cur->class = le32_to_cpu(buf[0]);
2985 cur->data = le32_to_cpu(buf[1]);
2986
2987 if (!tail) {
2988 avrule->perms = cur;
2989 } else {
2990 tail->next = cur;
2991 }
2992 tail = cur;
2993 }
2994
2995 return avrule;
2996 bad:
2997 if (avrule) {
2998 avrule_destroy(avrule);
2999 free(avrule);
3000 }
3001 return NULL;
3002 }
3003
range_read(policydb_t * p,struct policy_file * fp)3004 static int range_read(policydb_t * p, struct policy_file *fp)
3005 {
3006 uint32_t buf[2], nel;
3007 range_trans_t *rt, *lrt;
3008 range_trans_rule_t *rtr, *lrtr = NULL;
3009 unsigned int i;
3010 int new_rangetr = (p->policy_type == POLICY_KERN &&
3011 p->policyvers >= POLICYDB_VERSION_RANGETRANS);
3012 int rc;
3013
3014 rc = next_entry(buf, fp, sizeof(uint32_t));
3015 if (rc < 0)
3016 return -1;
3017 nel = le32_to_cpu(buf[0]);
3018 lrt = NULL;
3019 for (i = 0; i < nel; i++) {
3020 rt = calloc(1, sizeof(range_trans_t));
3021 if (!rt)
3022 return -1;
3023 if (lrt)
3024 lrt->next = rt;
3025 else
3026 p->range_tr = rt;
3027 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
3028 if (rc < 0)
3029 return -1;
3030 rt->source_type = le32_to_cpu(buf[0]);
3031 rt->target_type = le32_to_cpu(buf[1]);
3032 if (new_rangetr) {
3033 rc = next_entry(buf, fp, (sizeof(uint32_t)));
3034 if (rc < 0)
3035 return -1;
3036 rt->target_class = le32_to_cpu(buf[0]);
3037 } else
3038 rt->target_class = SECCLASS_PROCESS;
3039 if (mls_read_range_helper(&rt->target_range, fp))
3040 return -1;
3041 lrt = rt;
3042 }
3043
3044 /* if this is a kernel policy, we are done - otherwise we need to
3045 * convert these structs to range_trans_rule_ts */
3046 if (p->policy_type == POLICY_KERN)
3047 return 0;
3048
3049 /* create range_trans_rules_ts that correspond to the range_trans_ts
3050 * that were just read in from an older policy */
3051 for (rt = p->range_tr; rt; rt = rt->next) {
3052 rtr = malloc(sizeof(range_trans_rule_t));
3053 if (!rtr) {
3054 return -1;
3055 }
3056 range_trans_rule_init(rtr);
3057
3058 if (lrtr)
3059 lrtr->next = rtr;
3060 else
3061 p->global->enabled->range_tr_rules = rtr;
3062
3063 if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1))
3064 return -1;
3065
3066 if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1))
3067 return -1;
3068
3069 if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1))
3070 return -1;
3071
3072 if (mls_range_to_semantic(&rt->target_range, &rtr->trange))
3073 return -1;
3074
3075 lrtr = rtr;
3076 }
3077
3078 /* now destroy the range_trans_ts */
3079 lrt = NULL;
3080 for (rt = p->range_tr; rt; rt = rt->next) {
3081 if (lrt) {
3082 ebitmap_destroy(&lrt->target_range.level[0].cat);
3083 ebitmap_destroy(&lrt->target_range.level[1].cat);
3084 free(lrt);
3085 }
3086 lrt = rt;
3087 }
3088 if (lrt) {
3089 ebitmap_destroy(&lrt->target_range.level[0].cat);
3090 ebitmap_destroy(&lrt->target_range.level[1].cat);
3091 free(lrt);
3092 }
3093 p->range_tr = NULL;
3094
3095 return 0;
3096 }
3097
avrule_read_list(policydb_t * p,avrule_t ** avrules,struct policy_file * fp)3098 int avrule_read_list(policydb_t * p, avrule_t ** avrules,
3099 struct policy_file *fp)
3100 {
3101 unsigned int i;
3102 avrule_t *cur, *tail;
3103 uint32_t buf[1], len;
3104 int rc;
3105
3106 *avrules = tail = NULL;
3107
3108 rc = next_entry(buf, fp, sizeof(uint32_t));
3109 if (rc < 0) {
3110 return -1;
3111 }
3112 len = le32_to_cpu(buf[0]);
3113
3114 for (i = 0; i < len; i++) {
3115 cur = avrule_read(p, fp);
3116 if (!cur) {
3117 return -1;
3118 }
3119
3120 if (!tail) {
3121 *avrules = cur;
3122 } else {
3123 tail->next = cur;
3124 }
3125 tail = cur;
3126 }
3127
3128 return 0;
3129 }
3130
role_trans_rule_read(policydb_t * p,role_trans_rule_t ** r,struct policy_file * fp)3131 static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r,
3132 struct policy_file *fp)
3133 {
3134 uint32_t buf[1], nel;
3135 unsigned int i;
3136 role_trans_rule_t *tr, *ltr;
3137 int rc;
3138
3139 rc = next_entry(buf, fp, sizeof(uint32_t));
3140 if (rc < 0)
3141 return -1;
3142 nel = le32_to_cpu(buf[0]);
3143 ltr = NULL;
3144 for (i = 0; i < nel; i++) {
3145 tr = malloc(sizeof(role_trans_rule_t));
3146 if (!tr) {
3147 return -1;
3148 }
3149 role_trans_rule_init(tr);
3150
3151 if (ltr) {
3152 ltr->next = tr;
3153 } else {
3154 *r = tr;
3155 }
3156
3157 if (role_set_read(&tr->roles, fp))
3158 return -1;
3159
3160 if (type_set_read(&tr->types, fp))
3161 return -1;
3162
3163 if (p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS) {
3164 if (ebitmap_read(&tr->classes, fp))
3165 return -1;
3166 } else {
3167 if (ebitmap_set_bit(&tr->classes, SECCLASS_PROCESS - 1, 1))
3168 return -1;
3169 }
3170
3171 rc = next_entry(buf, fp, sizeof(uint32_t));
3172 if (rc < 0)
3173 return -1;
3174 tr->new_role = le32_to_cpu(buf[0]);
3175 ltr = tr;
3176 }
3177
3178 return 0;
3179 }
3180
role_allow_rule_read(role_allow_rule_t ** r,struct policy_file * fp)3181 static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp)
3182 {
3183 unsigned int i;
3184 uint32_t buf[1], nel;
3185 role_allow_rule_t *ra, *lra;
3186 int rc;
3187
3188 rc = next_entry(buf, fp, sizeof(uint32_t));
3189 if (rc < 0)
3190 return -1;
3191 nel = le32_to_cpu(buf[0]);
3192 lra = NULL;
3193 for (i = 0; i < nel; i++) {
3194 ra = malloc(sizeof(role_allow_rule_t));
3195 if (!ra) {
3196 return -1;
3197 }
3198 role_allow_rule_init(ra);
3199
3200 if (lra) {
3201 lra->next = ra;
3202 } else {
3203 *r = ra;
3204 }
3205
3206 if (role_set_read(&ra->roles, fp))
3207 return -1;
3208
3209 if (role_set_read(&ra->new_roles, fp))
3210 return -1;
3211
3212 lra = ra;
3213 }
3214 return 0;
3215 }
3216
filename_trans_rule_read(filename_trans_rule_t ** r,struct policy_file * fp)3217 static int filename_trans_rule_read(filename_trans_rule_t ** r, struct policy_file *fp)
3218 {
3219 uint32_t buf[2], nel;
3220 unsigned int i, len;
3221 filename_trans_rule_t *ftr, *lftr;
3222 int rc;
3223
3224 rc = next_entry(buf, fp, sizeof(uint32_t));
3225 if (rc < 0)
3226 return -1;
3227 nel = le32_to_cpu(buf[0]);
3228 lftr = NULL;
3229 for (i = 0; i < nel; i++) {
3230 ftr = malloc(sizeof(*ftr));
3231 if (!ftr)
3232 return -1;
3233
3234 filename_trans_rule_init(ftr);
3235
3236 if (lftr)
3237 lftr->next = ftr;
3238 else
3239 *r = ftr;
3240 lftr = ftr;
3241
3242 rc = next_entry(buf, fp, sizeof(uint32_t));
3243 if (rc < 0)
3244 return -1;
3245
3246 len = le32_to_cpu(buf[0]);
3247
3248 ftr->name = malloc(len + 1);
3249 if (!ftr->name)
3250 return -1;
3251
3252 rc = next_entry(ftr->name, fp, len);
3253 if (rc)
3254 return -1;
3255 ftr->name[len] = 0;
3256
3257 if (type_set_read(&ftr->stypes, fp))
3258 return -1;
3259
3260 if (type_set_read(&ftr->ttypes, fp))
3261 return -1;
3262
3263 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3264 if (rc < 0)
3265 return -1;
3266 ftr->tclass = le32_to_cpu(buf[0]);
3267 ftr->otype = le32_to_cpu(buf[1]);
3268 }
3269
3270 return 0;
3271 }
3272
range_trans_rule_read(range_trans_rule_t ** r,struct policy_file * fp)3273 static int range_trans_rule_read(range_trans_rule_t ** r,
3274 struct policy_file *fp)
3275 {
3276 uint32_t buf[1], nel;
3277 unsigned int i;
3278 range_trans_rule_t *rt, *lrt = NULL;
3279 int rc;
3280
3281 rc = next_entry(buf, fp, sizeof(uint32_t));
3282 if (rc < 0)
3283 return -1;
3284 nel = le32_to_cpu(buf[0]);
3285 for (i = 0; i < nel; i++) {
3286 rt = malloc(sizeof(range_trans_rule_t));
3287 if (!rt) {
3288 return -1;
3289 }
3290 range_trans_rule_init(rt);
3291
3292 if (lrt)
3293 lrt->next = rt;
3294 else
3295 *r = rt;
3296
3297 if (type_set_read(&rt->stypes, fp))
3298 return -1;
3299
3300 if (type_set_read(&rt->ttypes, fp))
3301 return -1;
3302
3303 if (ebitmap_read(&rt->tclasses, fp))
3304 return -1;
3305
3306 if (mls_read_semantic_range_helper(&rt->trange, fp))
3307 return -1;
3308
3309 lrt = rt;
3310 }
3311
3312 return 0;
3313 }
3314
scope_index_read(scope_index_t * scope_index,unsigned int num_scope_syms,struct policy_file * fp)3315 static int scope_index_read(scope_index_t * scope_index,
3316 unsigned int num_scope_syms, struct policy_file *fp)
3317 {
3318 unsigned int i;
3319 uint32_t buf[1];
3320 int rc;
3321
3322 for (i = 0; i < num_scope_syms; i++) {
3323 if (ebitmap_read(scope_index->scope + i, fp) == -1) {
3324 return -1;
3325 }
3326 }
3327 rc = next_entry(buf, fp, sizeof(uint32_t));
3328 if (rc < 0)
3329 return -1;
3330 scope_index->class_perms_len = le32_to_cpu(buf[0]);
3331 if (scope_index->class_perms_len == 0) {
3332 scope_index->class_perms_map = NULL;
3333 return 0;
3334 }
3335 if ((scope_index->class_perms_map =
3336 calloc(scope_index->class_perms_len,
3337 sizeof(*scope_index->class_perms_map))) == NULL) {
3338 return -1;
3339 }
3340 for (i = 0; i < scope_index->class_perms_len; i++) {
3341 if (ebitmap_read(scope_index->class_perms_map + i, fp) == -1) {
3342 return -1;
3343 }
3344 }
3345 return 0;
3346 }
3347
avrule_decl_read(policydb_t * p,avrule_decl_t * decl,unsigned int num_scope_syms,struct policy_file * fp)3348 static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl,
3349 unsigned int num_scope_syms, struct policy_file *fp)
3350 {
3351 uint32_t buf[2], nprim, nel;
3352 unsigned int i, j;
3353 int rc;
3354
3355 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3356 if (rc < 0)
3357 return -1;
3358 decl->decl_id = le32_to_cpu(buf[0]);
3359 decl->enabled = le32_to_cpu(buf[1]);
3360 if (cond_read_list(p, &decl->cond_list, fp) == -1 ||
3361 avrule_read_list(p, &decl->avrules, fp) == -1 ||
3362 role_trans_rule_read(p, &decl->role_tr_rules, fp) == -1 ||
3363 role_allow_rule_read(&decl->role_allow_rules, fp) == -1) {
3364 return -1;
3365 }
3366
3367 if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
3368 filename_trans_rule_read(&decl->filename_trans_rules, fp))
3369 return -1;
3370
3371 if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
3372 range_trans_rule_read(&decl->range_tr_rules, fp) == -1) {
3373 return -1;
3374 }
3375 if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 ||
3376 scope_index_read(&decl->declared, num_scope_syms, fp) == -1) {
3377 return -1;
3378 }
3379
3380 for (i = 0; i < num_scope_syms; i++) {
3381 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3382 if (rc < 0)
3383 return -1;
3384 nprim = le32_to_cpu(buf[0]);
3385 nel = le32_to_cpu(buf[1]);
3386 for (j = 0; j < nel; j++) {
3387 if (read_f[i] (p, decl->symtab[i].table, fp)) {
3388 return -1;
3389 }
3390 }
3391 decl->symtab[i].nprim = nprim;
3392 }
3393 return 0;
3394 }
3395
avrule_block_read(policydb_t * p,avrule_block_t ** block,unsigned int num_scope_syms,struct policy_file * fp)3396 static int avrule_block_read(policydb_t * p,
3397 avrule_block_t ** block,
3398 unsigned int num_scope_syms,
3399 struct policy_file *fp)
3400 {
3401 avrule_block_t *last_block = NULL, *curblock;
3402 uint32_t buf[1], num_blocks, nel;
3403 int rc;
3404
3405 rc = next_entry(buf, fp, sizeof(uint32_t));
3406 if (rc < 0)
3407 return -1;
3408 num_blocks = le32_to_cpu(buf[0]);
3409 nel = num_blocks;
3410 while (num_blocks > 0) {
3411 avrule_decl_t *last_decl = NULL, *curdecl;
3412 uint32_t num_decls;
3413 if ((curblock = calloc(1, sizeof(*curblock))) == NULL) {
3414 return -1;
3415 }
3416 rc = next_entry(buf, fp, sizeof(uint32_t));
3417 if (rc < 0) {
3418 free(curblock);
3419 return -1;
3420 }
3421 /* if this is the first block its non-optional, else its optional */
3422 if (num_blocks != nel)
3423 curblock->flags |= AVRULE_OPTIONAL;
3424
3425 num_decls = le32_to_cpu(buf[0]);
3426 while (num_decls > 0) {
3427 if ((curdecl = avrule_decl_create(0)) == NULL) {
3428 avrule_block_destroy(curblock);
3429 return -1;
3430 }
3431 if (avrule_decl_read(p, curdecl, num_scope_syms, fp) ==
3432 -1) {
3433 avrule_decl_destroy(curdecl);
3434 avrule_block_destroy(curblock);
3435 return -1;
3436 }
3437 if (curdecl->enabled) {
3438 if (curblock->enabled != NULL) {
3439 /* probably a corrupt file */
3440 avrule_decl_destroy(curdecl);
3441 avrule_block_destroy(curblock);
3442 return -1;
3443 }
3444 curblock->enabled = curdecl;
3445 }
3446 /* one must be careful to reconstruct the
3447 * decl chain in its correct order */
3448 if (curblock->branch_list == NULL) {
3449 curblock->branch_list = curdecl;
3450 } else if (last_decl != NULL) {
3451 last_decl->next = curdecl;
3452 }
3453 last_decl = curdecl;
3454 num_decls--;
3455 }
3456
3457 if (*block == NULL) {
3458 *block = curblock;
3459 } else if (last_block != NULL) {
3460 last_block->next = curblock;
3461 }
3462 last_block = curblock;
3463
3464 num_blocks--;
3465 }
3466
3467 return 0;
3468 }
3469
scope_read(policydb_t * p,int symnum,struct policy_file * fp)3470 static int scope_read(policydb_t * p, int symnum, struct policy_file *fp)
3471 {
3472 scope_datum_t *scope = NULL;
3473 uint32_t buf[2];
3474 char *key = NULL;
3475 size_t key_len;
3476 unsigned int i;
3477 hashtab_t h = p->scope[symnum].table;
3478 int rc;
3479
3480 rc = next_entry(buf, fp, sizeof(uint32_t));
3481 if (rc < 0)
3482 goto cleanup;
3483 key_len = le32_to_cpu(buf[0]);
3484 key = malloc(key_len + 1);
3485 if (!key)
3486 goto cleanup;
3487 rc = next_entry(key, fp, key_len);
3488 if (rc < 0)
3489 goto cleanup;
3490 key[key_len] = '\0';
3491
3492 /* ensure that there already exists a symbol with this key */
3493 if (hashtab_search(p->symtab[symnum].table, key) == NULL) {
3494 goto cleanup;
3495 }
3496
3497 if ((scope = calloc(1, sizeof(*scope))) == NULL) {
3498 goto cleanup;
3499 }
3500 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3501 if (rc < 0)
3502 goto cleanup;
3503 scope->scope = le32_to_cpu(buf[0]);
3504 scope->decl_ids_len = le32_to_cpu(buf[1]);
3505 assert(scope->decl_ids_len > 0);
3506 if ((scope->decl_ids =
3507 malloc(scope->decl_ids_len * sizeof(uint32_t))) == NULL) {
3508 goto cleanup;
3509 }
3510 rc = next_entry(scope->decl_ids, fp, sizeof(uint32_t) * scope->decl_ids_len);
3511 if (rc < 0)
3512 goto cleanup;
3513 for (i = 0; i < scope->decl_ids_len; i++) {
3514 scope->decl_ids[i] = le32_to_cpu(scope->decl_ids[i]);
3515 }
3516
3517 if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) {
3518 /* object_r was already added to this table in roles_init() */
3519 scope_destroy(key, scope, NULL);
3520 } else {
3521 if (hashtab_insert(h, key, scope)) {
3522 goto cleanup;
3523 }
3524 }
3525
3526 return 0;
3527
3528 cleanup:
3529 scope_destroy(key, scope, NULL);
3530 return -1;
3531 }
3532
3533 /*
3534 * Read the configuration data from a policy database binary
3535 * representation file into a policy database structure.
3536 */
policydb_read(policydb_t * p,struct policy_file * fp,unsigned verbose)3537 int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
3538 {
3539
3540 unsigned int i, j, r_policyvers;
3541 uint32_t buf[5];
3542 size_t len, nprim, nel;
3543 char *policydb_str;
3544 struct policydb_compat_info *info;
3545 unsigned int policy_type, bufindex;
3546 ebitmap_node_t *tnode;
3547 int rc;
3548
3549 /* Read the magic number and string length. */
3550 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3551 if (rc < 0)
3552 return POLICYDB_ERROR;
3553 for (i = 0; i < 2; i++)
3554 buf[i] = le32_to_cpu(buf[i]);
3555
3556 if (buf[0] == POLICYDB_MAGIC) {
3557 policy_type = POLICY_KERN;
3558 } else if (buf[0] == POLICYDB_MOD_MAGIC) {
3559 policy_type = POLICY_MOD;
3560 } else {
3561 ERR(fp->handle, "policydb magic number %#08x does not "
3562 "match expected magic number %#08x or %#08x",
3563 buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC);
3564 return POLICYDB_ERROR;
3565 }
3566
3567 len = buf[1];
3568 if (len > POLICYDB_STRING_MAX_LENGTH) {
3569 ERR(fp->handle, "policydb string length too long ");
3570 return POLICYDB_ERROR;
3571 }
3572
3573 policydb_str = malloc(len + 1);
3574 if (!policydb_str) {
3575 ERR(fp->handle, "unable to allocate memory for policydb "
3576 "string of length %zu", len);
3577 return POLICYDB_ERROR;
3578 }
3579 rc = next_entry(policydb_str, fp, len);
3580 if (rc < 0) {
3581 ERR(fp->handle, "truncated policydb string identifier");
3582 free(policydb_str);
3583 return POLICYDB_ERROR;
3584 }
3585 policydb_str[len] = 0;
3586
3587 if (policy_type == POLICY_KERN) {
3588 for (i = 0; i < POLICYDB_TARGET_SZ; i++) {
3589 if ((strcmp(policydb_str, policydb_target_strings[i])
3590 == 0)) {
3591 policydb_set_target_platform(p, i);
3592 break;
3593 }
3594 }
3595
3596 if (i == POLICYDB_TARGET_SZ) {
3597 ERR(fp->handle, "cannot find a valid target for policy "
3598 "string %s", policydb_str);
3599 free(policydb_str);
3600 return POLICYDB_ERROR;
3601 }
3602 } else {
3603 if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
3604 ERR(fp->handle, "invalid string identifier %s",
3605 policydb_str);
3606 free(policydb_str);
3607 return POLICYDB_ERROR;
3608 }
3609 }
3610
3611 /* Done with policydb_str. */
3612 free(policydb_str);
3613 policydb_str = NULL;
3614
3615 /* Read the version, config, and table sizes (and policy type if it's a module). */
3616 if (policy_type == POLICY_KERN)
3617 nel = 4;
3618 else
3619 nel = 5;
3620
3621 rc = next_entry(buf, fp, sizeof(uint32_t) * nel);
3622 if (rc < 0)
3623 return POLICYDB_ERROR;
3624 for (i = 0; i < nel; i++)
3625 buf[i] = le32_to_cpu(buf[i]);
3626
3627 bufindex = 0;
3628
3629 if (policy_type == POLICY_MOD) {
3630 /* We know it's a module but not whether it's a base
3631 module or regular binary policy module. buf[0]
3632 tells us which. */
3633 policy_type = buf[bufindex];
3634 if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) {
3635 ERR(fp->handle, "unknown module type: %#08x",
3636 policy_type);
3637 return POLICYDB_ERROR;
3638 }
3639 bufindex++;
3640 }
3641
3642 r_policyvers = buf[bufindex];
3643 if (policy_type == POLICY_KERN) {
3644 if (r_policyvers < POLICYDB_VERSION_MIN ||
3645 r_policyvers > POLICYDB_VERSION_MAX) {
3646 ERR(fp->handle, "policydb version %d does not match "
3647 "my version range %d-%d", buf[bufindex],
3648 POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
3649 return POLICYDB_ERROR;
3650 }
3651 } else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) {
3652 if (r_policyvers < MOD_POLICYDB_VERSION_MIN ||
3653 r_policyvers > MOD_POLICYDB_VERSION_MAX) {
3654 ERR(fp->handle, "policydb module version %d does "
3655 "not match my version range %d-%d",
3656 buf[bufindex], MOD_POLICYDB_VERSION_MIN,
3657 MOD_POLICYDB_VERSION_MAX);
3658 return POLICYDB_ERROR;
3659 }
3660 } else {
3661 assert(0);
3662 }
3663 bufindex++;
3664
3665 /* Set the policy type and version from the read values. */
3666 p->policy_type = policy_type;
3667 p->policyvers = r_policyvers;
3668
3669 if (buf[bufindex] & POLICYDB_CONFIG_MLS) {
3670 p->mls = 1;
3671 } else {
3672 p->mls = 0;
3673 }
3674
3675 p->handle_unknown = buf[bufindex] & POLICYDB_CONFIG_UNKNOWN_MASK;
3676
3677 bufindex++;
3678
3679 info = policydb_lookup_compat(r_policyvers, policy_type,
3680 p->target_platform);
3681 if (!info) {
3682 ERR(fp->handle, "unable to find policy compat info "
3683 "for version %d", r_policyvers);
3684 goto bad;
3685 }
3686
3687 if (buf[bufindex] != info->sym_num
3688 || buf[bufindex + 1] != info->ocon_num) {
3689 ERR(fp->handle,
3690 "policydb table sizes (%d,%d) do not " "match mine (%d,%d)",
3691 buf[bufindex], buf[bufindex + 1], info->sym_num,
3692 info->ocon_num);
3693 goto bad;
3694 }
3695
3696 if (p->policy_type == POLICY_MOD) {
3697 /* Get the module name and version */
3698 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
3699 goto bad;
3700 }
3701 len = le32_to_cpu(buf[0]);
3702 if ((p->name = malloc(len + 1)) == NULL) {
3703 goto bad;
3704 }
3705 if ((rc = next_entry(p->name, fp, len)) < 0) {
3706 goto bad;
3707 }
3708 p->name[len] = '\0';
3709 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
3710 goto bad;
3711 }
3712 len = le32_to_cpu(buf[0]);
3713 if ((p->version = malloc(len + 1)) == NULL) {
3714 goto bad;
3715 }
3716 if ((rc = next_entry(p->version, fp, len)) < 0) {
3717 goto bad;
3718 }
3719 p->version[len] = '\0';
3720 }
3721
3722 if ((p->policyvers >= POLICYDB_VERSION_POLCAP &&
3723 p->policy_type == POLICY_KERN) ||
3724 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
3725 p->policy_type == POLICY_BASE) ||
3726 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
3727 p->policy_type == POLICY_MOD)) {
3728 if (ebitmap_read(&p->policycaps, fp))
3729 goto bad;
3730 }
3731
3732 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
3733 p->policy_type == POLICY_KERN) {
3734 if (ebitmap_read(&p->permissive_map, fp))
3735 goto bad;
3736 }
3737
3738 for (i = 0; i < info->sym_num; i++) {
3739 rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
3740 if (rc < 0)
3741 goto bad;
3742 nprim = le32_to_cpu(buf[0]);
3743 nel = le32_to_cpu(buf[1]);
3744 for (j = 0; j < nel; j++) {
3745 if (read_f[i] (p, p->symtab[i].table, fp))
3746 goto bad;
3747 }
3748
3749 p->symtab[i].nprim = nprim;
3750 }
3751
3752 if (policy_type == POLICY_KERN) {
3753 if (avtab_read(&p->te_avtab, fp, r_policyvers))
3754 goto bad;
3755 if (r_policyvers >= POLICYDB_VERSION_BOOL)
3756 if (cond_read_list(p, &p->cond_list, fp))
3757 goto bad;
3758 if (role_trans_read(p, fp))
3759 goto bad;
3760 if (role_allow_read(&p->role_allow, fp))
3761 goto bad;
3762 if (r_policyvers >= POLICYDB_VERSION_FILENAME_TRANS &&
3763 filename_trans_read(&p->filename_trans, fp))
3764 goto bad;
3765 } else {
3766 /* first read the AV rule blocks, then the scope tables */
3767 avrule_block_destroy(p->global);
3768 p->global = NULL;
3769 if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) {
3770 goto bad;
3771 }
3772 for (i = 0; i < info->sym_num; i++) {
3773 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
3774 goto bad;
3775 }
3776 nel = le32_to_cpu(buf[0]);
3777 for (j = 0; j < nel; j++) {
3778 if (scope_read(p, i, fp))
3779 goto bad;
3780 }
3781 }
3782
3783 }
3784
3785 if (policydb_index_decls(p))
3786 goto bad;
3787
3788 if (policydb_index_classes(p))
3789 goto bad;
3790
3791 if (policydb_index_others(fp->handle, p, verbose))
3792 goto bad;
3793
3794 if (ocontext_read(info, p, fp) == -1) {
3795 goto bad;
3796 }
3797
3798 if (genfs_read(p, fp) == -1) {
3799 goto bad;
3800 }
3801
3802 if ((p->policy_type == POLICY_KERN
3803 && p->policyvers >= POLICYDB_VERSION_MLS)
3804 || (p->policy_type == POLICY_BASE
3805 && p->policyvers >= MOD_POLICYDB_VERSION_MLS
3806 && p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) {
3807 if (range_read(p, fp)) {
3808 goto bad;
3809 }
3810 }
3811
3812 if (policy_type == POLICY_KERN) {
3813 p->type_attr_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
3814 p->attr_type_map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
3815 if (!p->type_attr_map || !p->attr_type_map)
3816 goto bad;
3817 for (i = 0; i < p->p_types.nprim; i++) {
3818 ebitmap_init(&p->type_attr_map[i]);
3819 ebitmap_init(&p->attr_type_map[i]);
3820 }
3821 for (i = 0; i < p->p_types.nprim; i++) {
3822 if (r_policyvers >= POLICYDB_VERSION_AVTAB) {
3823 if (ebitmap_read(&p->type_attr_map[i], fp))
3824 goto bad;
3825 ebitmap_for_each_bit(&p->type_attr_map[i],
3826 tnode, j) {
3827 if (!ebitmap_node_get_bit(tnode, j)
3828 || i == j)
3829 continue;
3830 if (ebitmap_set_bit
3831 (&p->attr_type_map[j], i, 1))
3832 goto bad;
3833 }
3834 }
3835 /* add the type itself as the degenerate case */
3836 if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
3837 goto bad;
3838 }
3839 }
3840
3841 return POLICYDB_SUCCESS;
3842 bad:
3843 return POLICYDB_ERROR;
3844 }
3845
policydb_reindex_users(policydb_t * p)3846 int policydb_reindex_users(policydb_t * p)
3847 {
3848 unsigned int i = SYM_USERS;
3849
3850 if (p->user_val_to_struct)
3851 free(p->user_val_to_struct);
3852 if (p->sym_val_to_name[i])
3853 free(p->sym_val_to_name[i]);
3854
3855 p->user_val_to_struct = (user_datum_t **)
3856 malloc(p->p_users.nprim * sizeof(user_datum_t *));
3857 if (!p->user_val_to_struct)
3858 return -1;
3859
3860 p->sym_val_to_name[i] = (char **)
3861 malloc(p->symtab[i].nprim * sizeof(char *));
3862 if (!p->sym_val_to_name[i])
3863 return -1;
3864
3865 if (hashtab_map(p->symtab[i].table, index_f[i], p))
3866 return -1;
3867
3868 /* Expand user roles for context validity checking */
3869 if (hashtab_map(p->p_users.table, policydb_user_cache, p))
3870 return -1;
3871
3872 return 0;
3873 }
3874
policy_file_init(policy_file_t * pf)3875 void policy_file_init(policy_file_t *pf)
3876 {
3877 memset(pf, 0, sizeof(policy_file_t));
3878 }
3879
policydb_set_target_platform(policydb_t * p,int platform)3880 int policydb_set_target_platform(policydb_t *p, int platform)
3881 {
3882 if (platform == SEPOL_TARGET_SELINUX)
3883 p->target_platform = SEPOL_TARGET_SELINUX;
3884 else if (platform == SEPOL_TARGET_XEN)
3885 p->target_platform = SEPOL_TARGET_XEN;
3886 else
3887 return -1;
3888
3889 return 0;
3890 }
3891
3892