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