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