1
2 #include <sepol/policydb/conditional.h>
3 #include <sepol/policydb/ebitmap.h>
4 #include <sepol/policydb/policydb.h>
5 #include <sepol/policydb/services.h>
6
7 #include "debug.h"
8 #include "policydb_validate.h"
9
10 #define bool_xor(a, b) (!(a) != !(b))
11 #define bool_xnor(a, b) !bool_xor(a, b)
12
13 typedef struct validate {
14 uint32_t nprim;
15 ebitmap_t gaps;
16 } validate_t;
17
18 typedef struct map_arg {
19 validate_t *flavors;
20 sepol_handle_t *handle;
21 int mls;
22 } map_arg_t;
23
create_gap_ebitmap(char ** val_to_name,uint32_t nprim,ebitmap_t * gaps)24 static int create_gap_ebitmap(char **val_to_name, uint32_t nprim, ebitmap_t *gaps)
25 {
26 unsigned int i;
27
28 ebitmap_init(gaps);
29
30 for (i = 0; i < nprim; i++) {
31 if (!val_to_name[i]) {
32 if (ebitmap_set_bit(gaps, i, 1))
33 return -1;
34 }
35 }
36
37 return 0;
38 }
39
validate_init(validate_t * flavor,char ** val_to_name,uint32_t nprim)40 static int validate_init(validate_t *flavor, char **val_to_name, uint32_t nprim)
41 {
42 flavor->nprim = nprim;
43 if (create_gap_ebitmap(val_to_name, nprim, &flavor->gaps))
44 return -1;
45
46 return 0;
47 }
48
validate_array_init(policydb_t * p,validate_t flavors[])49 static int validate_array_init(policydb_t *p, validate_t flavors[])
50 {
51 if (validate_init(&flavors[SYM_CLASSES], p->p_class_val_to_name, p->p_classes.nprim))
52 goto bad;
53 if (validate_init(&flavors[SYM_ROLES], p->p_role_val_to_name, p->p_roles.nprim))
54 goto bad;
55 if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) {
56 if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, p->p_types.nprim))
57 goto bad;
58 } else {
59 /*
60 * For policy versions between 20 and 23, attributes exist in the policy,
61 * but they only exist in the type_attr_map, so there will be references
62 * to gaps and we just have to treat this case as if there were no gaps.
63 */
64 flavors[SYM_TYPES].nprim = p->p_types.nprim;
65 ebitmap_init(&flavors[SYM_TYPES].gaps);
66 }
67 if (validate_init(&flavors[SYM_USERS], p->p_user_val_to_name, p->p_users.nprim))
68 goto bad;
69 if (validate_init(&flavors[SYM_BOOLS], p->p_bool_val_to_name, p->p_bools.nprim))
70 goto bad;
71 if (validate_init(&flavors[SYM_LEVELS], p->p_sens_val_to_name, p->p_levels.nprim))
72 goto bad;
73 if (validate_init(&flavors[SYM_CATS], p->p_cat_val_to_name, p->p_cats.nprim))
74 goto bad;
75
76 return 0;
77
78 bad:
79 return -1;
80 }
81
82 /*
83 * Functions to validate both kernel and module policydbs
84 */
85
value_isvalid(uint32_t value,uint32_t nprim)86 int value_isvalid(uint32_t value, uint32_t nprim)
87 {
88 if (!value || value > nprim)
89 return 0;
90
91 return 1;
92 }
93
validate_value(uint32_t value,validate_t * flavor)94 static int validate_value(uint32_t value, validate_t *flavor)
95 {
96 if (!value || value > flavor->nprim)
97 goto bad;
98 if (ebitmap_get_bit(&flavor->gaps, value-1))
99 goto bad;
100
101 return 0;
102
103 bad:
104 return -1;
105 }
106
validate_ebitmap(ebitmap_t * map,validate_t * flavor)107 static int validate_ebitmap(ebitmap_t *map, validate_t *flavor)
108 {
109 if (ebitmap_length(map) > 0 && ebitmap_highest_set_bit(map) >= flavor->nprim)
110 goto bad;
111 if (ebitmap_match_any(map, &flavor->gaps))
112 goto bad;
113
114 return 0;
115
116 bad:
117 return -1;
118 }
119
validate_type_set(type_set_t * type_set,validate_t * type)120 static int validate_type_set(type_set_t *type_set, validate_t *type)
121 {
122 if (validate_ebitmap(&type_set->types, type))
123 goto bad;
124 if (validate_ebitmap(&type_set->negset, type))
125 goto bad;
126
127 switch (type_set->flags) {
128 case 0:
129 case TYPE_STAR:
130 case TYPE_COMP:
131 break;
132 default:
133 goto bad;
134 }
135
136 return 0;
137
138 bad:
139 return -1;
140 }
141
validate_empty_type_set(type_set_t * type_set)142 static int validate_empty_type_set(type_set_t *type_set)
143 {
144 if (!ebitmap_is_empty(&type_set->types))
145 goto bad;
146 if (!ebitmap_is_empty(&type_set->negset))
147 goto bad;
148 if (type_set->flags != 0)
149 goto bad;
150
151 return 0;
152
153 bad:
154 return -1;
155 }
156
validate_role_set(role_set_t * role_set,validate_t * role)157 static int validate_role_set(role_set_t *role_set, validate_t *role)
158 {
159 if (validate_ebitmap(&role_set->roles, role))
160 goto bad;
161
162 switch (role_set->flags) {
163 case 0:
164 case ROLE_STAR:
165 case ROLE_COMP:
166 break;
167 default:
168 goto bad;
169 }
170
171 return 0;
172
173 bad:
174 return -1;
175 }
176
validate_scope(hashtab_key_t k,hashtab_datum_t d,void * args)177 static int validate_scope(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
178 {
179 scope_datum_t *scope_datum = (scope_datum_t *)d;
180 uint32_t *nprim = (uint32_t *)args;
181 unsigned int i;
182
183 switch (scope_datum->scope) {
184 case SCOPE_REQ:
185 case SCOPE_DECL:
186 break;
187 default:
188 goto bad;
189 }
190
191 for (i = 0; i < scope_datum->decl_ids_len; i++) {
192 if (!value_isvalid(scope_datum->decl_ids[i], *nprim))
193 goto bad;
194 }
195
196 return 0;
197
198 bad:
199 return -1;
200 }
201
validate_scopes(sepol_handle_t * handle,symtab_t scopes[],avrule_block_t * block)202 static int validate_scopes(sepol_handle_t *handle, symtab_t scopes[], avrule_block_t *block)
203 {
204 avrule_decl_t *decl;
205 unsigned int i;
206 unsigned int num_decls = 0;
207
208 for (; block != NULL; block = block->next) {
209 for (decl = block->branch_list; decl; decl = decl->next) {
210 num_decls++;
211 }
212 }
213
214 for (i = 0; i < SYM_NUM; i++) {
215 if (hashtab_map(scopes[i].table, validate_scope, &num_decls))
216 goto bad;
217 }
218
219 return 0;
220
221 bad:
222 ERR(handle, "Invalid scope");
223 return -1;
224 }
225
validate_constraint_nodes(sepol_handle_t * handle,unsigned int nperms,constraint_node_t * cons,validate_t flavors[])226 static int validate_constraint_nodes(sepol_handle_t *handle, unsigned int nperms, constraint_node_t *cons, validate_t flavors[])
227 {
228 constraint_expr_t *cexp;
229
230 for (; cons; cons = cons->next) {
231 if (nperms == 0 && cons->permissions != 0)
232 goto bad;
233 if (nperms > 0 && cons->permissions == 0)
234 goto bad;
235 if (nperms > 0 && nperms != PERM_SYMTAB_SIZE && cons->permissions >= (UINT32_C(1) << nperms))
236 goto bad;
237
238 for (cexp = cons->expr; cexp; cexp = cexp->next) {
239 if (cexp->expr_type == CEXPR_NAMES) {
240 if (cexp->attr & CEXPR_XTARGET && nperms != 0)
241 goto bad;
242 if (!(cexp->attr & CEXPR_TYPE)) {
243 if (validate_empty_type_set(cexp->type_names))
244 goto bad;
245 }
246
247 switch (cexp->op) {
248 case CEXPR_EQ:
249 case CEXPR_NEQ:
250 break;
251 default:
252 goto bad;
253 }
254
255 switch (cexp->attr) {
256 case CEXPR_USER:
257 case CEXPR_USER | CEXPR_TARGET:
258 case CEXPR_USER | CEXPR_XTARGET:
259 if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS]))
260 goto bad;
261 break;
262 case CEXPR_ROLE:
263 case CEXPR_ROLE | CEXPR_TARGET:
264 case CEXPR_ROLE | CEXPR_XTARGET:
265 if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES]))
266 goto bad;
267 break;
268 case CEXPR_TYPE:
269 case CEXPR_TYPE | CEXPR_TARGET:
270 case CEXPR_TYPE | CEXPR_XTARGET:
271 if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES]))
272 goto bad;
273 if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES]))
274 goto bad;
275 break;
276 default:
277 goto bad;
278 }
279 } else if (cexp->expr_type == CEXPR_ATTR) {
280 if (!ebitmap_is_empty(&cexp->names))
281 goto bad;
282 if (validate_empty_type_set(cexp->type_names))
283 goto bad;
284
285 switch (cexp->op) {
286 case CEXPR_EQ:
287 case CEXPR_NEQ:
288 break;
289 case CEXPR_DOM:
290 case CEXPR_DOMBY:
291 case CEXPR_INCOMP:
292 if ((cexp->attr & CEXPR_USER) || (cexp->attr & CEXPR_TYPE))
293 goto bad;
294 break;
295 default:
296 goto bad;
297 }
298
299 switch (cexp->attr) {
300 case CEXPR_USER:
301 case CEXPR_ROLE:
302 case CEXPR_TYPE:
303 case CEXPR_L1L2:
304 case CEXPR_L1H2:
305 case CEXPR_H1L2:
306 case CEXPR_H1H2:
307 case CEXPR_L1H1:
308 case CEXPR_L2H2:
309 break;
310 default:
311 goto bad;
312 }
313 } else {
314 switch (cexp->expr_type) {
315 case CEXPR_NOT:
316 case CEXPR_AND:
317 case CEXPR_OR:
318 break;
319 default:
320 goto bad;
321 }
322
323 if (cexp->op != 0)
324 goto bad;
325 if (cexp->attr != 0)
326 goto bad;
327 if (!ebitmap_is_empty(&cexp->names))
328 goto bad;
329 if (validate_empty_type_set(cexp->type_names))
330 goto bad;
331 }
332 }
333 }
334
335 return 0;
336
337 bad:
338 ERR(handle, "Invalid constraint expr");
339 return -1;
340 }
341
validate_class_datum(sepol_handle_t * handle,class_datum_t * class,validate_t flavors[])342 static int validate_class_datum(sepol_handle_t *handle, class_datum_t *class, validate_t flavors[])
343 {
344 if (validate_value(class->s.value, &flavors[SYM_CLASSES]))
345 goto bad;
346 if (class->permissions.nprim > PERM_SYMTAB_SIZE)
347 goto bad;
348 if (validate_constraint_nodes(handle, class->permissions.nprim, class->constraints, flavors))
349 goto bad;
350 if (validate_constraint_nodes(handle, 0, class->validatetrans, flavors))
351 goto bad;
352
353 switch (class->default_user) {
354 case 0:
355 case DEFAULT_SOURCE:
356 case DEFAULT_TARGET:
357 break;
358 default:
359 goto bad;
360 }
361
362 switch (class->default_role) {
363 case 0:
364 case DEFAULT_SOURCE:
365 case DEFAULT_TARGET:
366 break;
367 default:
368 goto bad;
369 }
370
371 switch (class->default_type) {
372 case 0:
373 case DEFAULT_SOURCE:
374 case DEFAULT_TARGET:
375 break;
376 default:
377 goto bad;
378 }
379
380 switch (class->default_range) {
381 case 0:
382 case DEFAULT_SOURCE_LOW:
383 case DEFAULT_SOURCE_HIGH:
384 case DEFAULT_SOURCE_LOW_HIGH:
385 case DEFAULT_TARGET_LOW:
386 case DEFAULT_TARGET_HIGH:
387 case DEFAULT_TARGET_LOW_HIGH:
388 case DEFAULT_GLBLUB:
389 break;
390 default:
391 goto bad;
392 }
393
394 return 0;
395
396 bad:
397 ERR(handle, "Invalid class datum");
398 return -1;
399 }
400
validate_class_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)401 static int validate_class_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
402 {
403 map_arg_t *margs = args;
404
405 return validate_class_datum(margs->handle, d, margs->flavors);
406 }
407
validate_common_datum(sepol_handle_t * handle,common_datum_t * common)408 static int validate_common_datum(sepol_handle_t *handle, common_datum_t *common)
409 {
410 if (common->permissions.nprim > PERM_SYMTAB_SIZE)
411 goto bad;
412
413 return 0;
414
415 bad:
416 ERR(handle, "Invalid common class datum");
417 return -1;
418 }
419
validate_common_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)420 static int validate_common_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
421 {
422 map_arg_t *margs = args;
423
424 return validate_common_datum(margs->handle, d);
425 }
426
validate_role_datum(sepol_handle_t * handle,role_datum_t * role,validate_t flavors[])427 static int validate_role_datum(sepol_handle_t *handle, role_datum_t *role, validate_t flavors[])
428 {
429 if (validate_value(role->s.value, &flavors[SYM_ROLES]))
430 goto bad;
431 if (validate_ebitmap(&role->dominates, &flavors[SYM_ROLES]))
432 goto bad;
433 if (validate_type_set(&role->types, &flavors[SYM_TYPES]))
434 goto bad;
435 if (role->bounds && validate_value(role->bounds, &flavors[SYM_ROLES]))
436 goto bad;
437 if (validate_ebitmap(&role->roles, &flavors[SYM_ROLES]))
438 goto bad;
439
440 return 0;
441
442 bad:
443 ERR(handle, "Invalid role datum");
444 return -1;
445 }
446
validate_role_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)447 static int validate_role_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
448 {
449 map_arg_t *margs = args;
450
451 return validate_role_datum(margs->handle, d, margs->flavors);
452 }
453
validate_type_datum(sepol_handle_t * handle,type_datum_t * type,validate_t flavors[])454 static int validate_type_datum(sepol_handle_t *handle, type_datum_t *type, validate_t flavors[])
455 {
456 if (validate_value(type->s.value, &flavors[SYM_TYPES]))
457 goto bad;
458 if (validate_ebitmap(&type->types, &flavors[SYM_TYPES]))
459 goto bad;
460 if (type->bounds && validate_value(type->bounds, &flavors[SYM_TYPES]))
461 goto bad;
462
463 switch (type->flavor) {
464 case TYPE_TYPE:
465 case TYPE_ATTRIB:
466 case TYPE_ALIAS:
467 break;
468 default:
469 goto bad;
470 }
471
472 switch (type->flags) {
473 case 0:
474 case TYPE_FLAGS_PERMISSIVE:
475 case TYPE_FLAGS_EXPAND_ATTR_TRUE:
476 case TYPE_FLAGS_EXPAND_ATTR_FALSE:
477 case TYPE_FLAGS_EXPAND_ATTR:
478 break;
479 default:
480 goto bad;
481 }
482
483 return 0;
484
485 bad:
486 ERR(handle, "Invalid type datum");
487 return -1;
488 }
489
validate_type_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)490 static int validate_type_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
491 {
492 map_arg_t *margs = args;
493
494 return validate_type_datum(margs->handle, d, margs->flavors);
495 }
496
validate_mls_semantic_cat(mls_semantic_cat_t * cat,validate_t * cats)497 static int validate_mls_semantic_cat(mls_semantic_cat_t *cat, validate_t *cats)
498 {
499 for (; cat; cat = cat->next) {
500 if (validate_value(cat->low, cats))
501 goto bad;
502 if (validate_value(cat->high, cats))
503 goto bad;
504 }
505
506 return 0;
507
508 bad:
509 return -1;
510 }
511
validate_mls_semantic_level(mls_semantic_level_t * level,validate_t * sens,validate_t * cats)512 static int validate_mls_semantic_level(mls_semantic_level_t *level, validate_t *sens, validate_t *cats)
513 {
514 if (level->sens == 0)
515 return 0;
516 if (validate_value(level->sens, sens))
517 goto bad;
518 if (validate_mls_semantic_cat(level->cat, cats))
519 goto bad;
520
521 return 0;
522
523 bad:
524 return -1;
525 }
526
validate_mls_semantic_range(mls_semantic_range_t * range,validate_t * sens,validate_t * cats)527 static int validate_mls_semantic_range(mls_semantic_range_t *range, validate_t *sens, validate_t *cats)
528 {
529 if (validate_mls_semantic_level(&range->level[0], sens, cats))
530 goto bad;
531 if (validate_mls_semantic_level(&range->level[1], sens, cats))
532 goto bad;
533
534 return 0;
535
536 bad:
537 return -1;
538 }
539
validate_mls_level(mls_level_t * level,validate_t * sens,validate_t * cats)540 static int validate_mls_level(mls_level_t *level, validate_t *sens, validate_t *cats)
541 {
542 if (validate_value(level->sens, sens))
543 goto bad;
544 if (validate_ebitmap(&level->cat, cats))
545 goto bad;
546
547 return 0;
548
549 bad:
550 return -1;
551 }
552
validate_level_datum(hashtab_key_t k,hashtab_datum_t d,void * args)553 static int validate_level_datum(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
554 {
555 level_datum_t *level = d;
556 validate_t *flavors = args;
557
558 return validate_mls_level(level->level, &flavors[SYM_LEVELS], &flavors[SYM_CATS]);
559 }
560
validate_mls_range(mls_range_t * range,validate_t * sens,validate_t * cats)561 static int validate_mls_range(mls_range_t *range, validate_t *sens, validate_t *cats)
562 {
563 if (validate_mls_level(&range->level[0], sens, cats))
564 goto bad;
565 if (validate_mls_level(&range->level[1], sens, cats))
566 goto bad;
567
568 return 0;
569
570 bad:
571 return -1;
572 }
573
validate_user_datum(sepol_handle_t * handle,user_datum_t * user,validate_t flavors[],int mls)574 static int validate_user_datum(sepol_handle_t *handle, user_datum_t *user, validate_t flavors[], int mls)
575 {
576 if (validate_value(user->s.value, &flavors[SYM_USERS]))
577 goto bad;
578 if (validate_role_set(&user->roles, &flavors[SYM_ROLES]))
579 goto bad;
580 if (validate_mls_semantic_range(&user->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
581 goto bad;
582 if (validate_mls_semantic_level(&user->dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
583 goto bad;
584 if (mls && validate_mls_range(&user->exp_range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
585 goto bad;
586 if (mls && validate_mls_level(&user->exp_dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
587 goto bad;
588 if (user->bounds && validate_value(user->bounds, &flavors[SYM_USERS]))
589 goto bad;
590
591 return 0;
592
593 bad:
594 ERR(handle, "Invalid user datum");
595 return -1;
596 }
597
validate_user_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)598 static int validate_user_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
599 {
600 map_arg_t *margs = args;
601
602 return validate_user_datum(margs->handle, d, margs->flavors, margs->mls);
603 }
604
validate_bool_datum(sepol_handle_t * handle,cond_bool_datum_t * boolean,validate_t flavors[])605 static int validate_bool_datum(sepol_handle_t *handle, cond_bool_datum_t *boolean, validate_t flavors[])
606 {
607 if (validate_value(boolean->s.value, &flavors[SYM_BOOLS]))
608 goto bad;
609
610 switch (boolean->state) {
611 case 0:
612 case 1:
613 break;
614 default:
615 goto bad;
616 }
617
618 switch (boolean->flags) {
619 case 0:
620 case COND_BOOL_FLAGS_TUNABLE:
621 break;
622 default:
623 goto bad;
624 }
625
626 return 0;
627
628 bad:
629 ERR(handle, "Invalid bool datum");
630 return -1;
631 }
632
validate_bool_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)633 static int validate_bool_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
634 {
635 map_arg_t *margs = args;
636
637 return validate_bool_datum(margs->handle, d, margs->flavors);
638 }
639
validate_datum_array_gaps(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])640 static int validate_datum_array_gaps(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
641 {
642 unsigned int i;
643
644 for (i = 0; i < p->p_classes.nprim; i++) {
645 if (bool_xnor(p->class_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i)))
646 goto bad;
647 }
648
649 for (i = 0; i < p->p_roles.nprim; i++) {
650 if (bool_xnor(p->role_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i)))
651 goto bad;
652 }
653
654 /*
655 * For policy versions between 20 and 23, attributes exist in the policy,
656 * but only in the type_attr_map, so all gaps must be assumed to be valid.
657 */
658 if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) {
659 for (i = 0; i < p->p_types.nprim; i++) {
660 if (bool_xnor(p->type_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i)))
661 goto bad;
662 }
663 }
664
665 for (i = 0; i < p->p_users.nprim; i++) {
666 if (bool_xnor(p->user_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_USERS].gaps, i)))
667 goto bad;
668 }
669
670 for (i = 0; i < p->p_bools.nprim; i++) {
671 if (bool_xnor(p->bool_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_BOOLS].gaps, i)))
672 goto bad;
673 }
674
675 return 0;
676
677 bad:
678 ERR(handle, "Invalid datum array gaps");
679 return -1;
680 }
681
validate_datum(hashtab_key_t k,hashtab_datum_t d,void * args)682 static int validate_datum(__attribute__ ((unused))hashtab_key_t k, hashtab_datum_t d, void *args)
683 {
684 symtab_datum_t *s = d;
685 uint32_t *nprim = (uint32_t *)args;
686
687 return !value_isvalid(s->value, *nprim);
688 }
689
validate_datum_array_entries(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])690 static int validate_datum_array_entries(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
691 {
692 map_arg_t margs = { flavors, handle, p->mls };
693
694 if (hashtab_map(p->p_commons.table, validate_common_datum_wrapper, &margs))
695 goto bad;
696
697 if (hashtab_map(p->p_classes.table, validate_class_datum_wrapper, &margs))
698 goto bad;
699
700 if (hashtab_map(p->p_roles.table, validate_role_datum_wrapper, &margs))
701 goto bad;
702
703 if (hashtab_map(p->p_types.table, validate_type_datum_wrapper, &margs))
704 goto bad;
705
706 if (hashtab_map(p->p_users.table, validate_user_datum_wrapper, &margs))
707 goto bad;
708
709 if (p->mls && hashtab_map(p->p_levels.table, validate_level_datum, flavors))
710 goto bad;
711
712 if (hashtab_map(p->p_cats.table, validate_datum, &flavors[SYM_CATS]))
713 goto bad;
714
715 if (hashtab_map(p->p_bools.table, validate_bool_datum_wrapper, &margs))
716 goto bad;
717
718 return 0;
719
720 bad:
721 ERR(handle, "Invalid datum array entries");
722 return -1;
723 }
724
725 /*
726 * Functions to validate a kernel policydb
727 */
728
validate_avtab_key(avtab_key_t * key,int conditional,validate_t flavors[])729 static int validate_avtab_key(avtab_key_t *key, int conditional, validate_t flavors[])
730 {
731 if (validate_value(key->source_type, &flavors[SYM_TYPES]))
732 goto bad;
733 if (validate_value(key->target_type, &flavors[SYM_TYPES]))
734 goto bad;
735 if (validate_value(key->target_class, &flavors[SYM_CLASSES]))
736 goto bad;
737 switch (0xFFF & key->specified) {
738 case AVTAB_ALLOWED:
739 case AVTAB_AUDITALLOW:
740 case AVTAB_AUDITDENY:
741 case AVTAB_TRANSITION:
742 case AVTAB_MEMBER:
743 case AVTAB_CHANGE:
744 break;
745 case AVTAB_XPERMS_ALLOWED:
746 case AVTAB_XPERMS_AUDITALLOW:
747 case AVTAB_XPERMS_DONTAUDIT:
748 if (conditional)
749 goto bad;
750 break;
751 default:
752 goto bad;
753 }
754
755 return 0;
756
757 bad:
758 return -1;
759 }
760
validate_avtab_key_and_datum(avtab_key_t * k,avtab_datum_t * d,void * args)761 static int validate_avtab_key_and_datum(avtab_key_t *k, avtab_datum_t *d, void *args)
762 {
763 validate_t *flavors = (validate_t *)args;
764
765 if (validate_avtab_key(k, 0, flavors))
766 return -1;
767
768 if ((k->specified & AVTAB_TYPE) && validate_value(d->data, &flavors[SYM_TYPES]))
769 return -1;
770
771 return 0;
772 }
773
validate_avtab(sepol_handle_t * handle,avtab_t * avtab,validate_t flavors[])774 static int validate_avtab(sepol_handle_t *handle, avtab_t *avtab, validate_t flavors[])
775 {
776 if (avtab_map(avtab, validate_avtab_key_and_datum, flavors)) {
777 ERR(handle, "Invalid avtab");
778 return -1;
779 }
780
781 return 0;
782 }
783
validate_cond_av_list(sepol_handle_t * handle,cond_av_list_t * cond_av,validate_t flavors[])784 static int validate_cond_av_list(sepol_handle_t *handle, cond_av_list_t *cond_av, validate_t flavors[])
785 {
786 avtab_ptr_t avtab_ptr;
787
788 for (; cond_av; cond_av = cond_av->next) {
789 for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) {
790 if (validate_avtab_key(&avtab_ptr->key, 1, flavors)) {
791 ERR(handle, "Invalid cond av list");
792 return -1;
793 }
794 }
795 }
796
797 return 0;
798 }
799
validate_avrules(sepol_handle_t * handle,avrule_t * avrule,int conditional,validate_t flavors[])800 static int validate_avrules(sepol_handle_t *handle, avrule_t *avrule, int conditional, validate_t flavors[])
801 {
802 class_perm_node_t *class;
803
804 for (; avrule; avrule = avrule->next) {
805 if (validate_type_set(&avrule->stypes, &flavors[SYM_TYPES]))
806 goto bad;
807 if (validate_type_set(&avrule->ttypes, &flavors[SYM_TYPES]))
808 goto bad;
809 class = avrule->perms;
810 for (; class; class = class->next) {
811 if (validate_value(class->tclass, &flavors[SYM_CLASSES]))
812 goto bad;
813 }
814
815 switch(avrule->specified) {
816 case AVRULE_ALLOWED:
817 case AVRULE_AUDITALLOW:
818 case AVRULE_AUDITDENY:
819 case AVRULE_DONTAUDIT:
820 case AVRULE_TRANSITION:
821 case AVRULE_MEMBER:
822 case AVRULE_CHANGE:
823 break;
824 case AVRULE_NEVERALLOW:
825 case AVRULE_XPERMS_ALLOWED:
826 case AVRULE_XPERMS_AUDITALLOW:
827 case AVRULE_XPERMS_DONTAUDIT:
828 case AVRULE_XPERMS_NEVERALLOW:
829 if (conditional)
830 goto bad;
831 break;
832 default:
833 goto bad;
834 }
835
836 if (avrule->specified & AVRULE_XPERMS) {
837 if (!avrule->xperms)
838 goto bad;
839 switch (avrule->xperms->specified) {
840 case AVRULE_XPERMS_IOCTLFUNCTION:
841 case AVRULE_XPERMS_IOCTLDRIVER:
842 break;
843 default:
844 goto bad;
845 }
846 } else if (avrule->xperms)
847 goto bad;
848
849 switch(avrule->flags) {
850 case 0:
851 case RULE_SELF:
852 break;
853 default:
854 goto bad;
855 }
856 }
857
858 return 0;
859
860 bad:
861 ERR(handle, "Invalid avrule");
862 return -1;
863 }
864
validate_bool_id_array(sepol_handle_t * handle,uint32_t bool_ids[],unsigned int nbools,validate_t * bool)865 static int validate_bool_id_array(sepol_handle_t *handle, uint32_t bool_ids[], unsigned int nbools, validate_t *bool)
866 {
867 unsigned int i;
868
869 if (nbools >= COND_MAX_BOOLS)
870 goto bad;
871
872 for (i=0; i < nbools; i++) {
873 if (validate_value(bool_ids[i], bool))
874 goto bad;
875 }
876
877 return 0;
878
879 bad:
880 ERR(handle, "Invalid bool id array");
881 return -1;
882 }
883
validate_cond_expr(sepol_handle_t * handle,struct cond_expr * expr,validate_t * bool)884 static int validate_cond_expr(sepol_handle_t *handle, struct cond_expr *expr, validate_t *bool)
885 {
886 int depth = -1;
887
888 for (; expr; expr = expr->next) {
889 switch(expr->expr_type) {
890 case COND_BOOL:
891 if (validate_value(expr->bool, bool))
892 goto bad;
893 if (depth == (COND_EXPR_MAXDEPTH - 1))
894 goto bad;
895 depth++;
896 break;
897 case COND_NOT:
898 if (depth < 0)
899 goto bad;
900 break;
901 case COND_OR:
902 case COND_AND:
903 case COND_XOR:
904 case COND_EQ:
905 case COND_NEQ:
906 if (depth < 1)
907 goto bad;
908 depth--;
909 break;
910 default:
911 goto bad;
912 }
913 }
914
915 if (depth != 0)
916 goto bad;
917
918 return 0;
919
920 bad:
921 ERR(handle, "Invalid cond expression");
922 return -1;
923 }
924
validate_cond_list(sepol_handle_t * handle,cond_list_t * cond,validate_t flavors[])925 static int validate_cond_list(sepol_handle_t *handle, cond_list_t *cond, validate_t flavors[])
926 {
927 for (; cond; cond = cond->next) {
928 if (validate_cond_expr(handle, cond->expr, &flavors[SYM_BOOLS]))
929 goto bad;
930 if (validate_cond_av_list(handle, cond->true_list, flavors))
931 goto bad;
932 if (validate_cond_av_list(handle, cond->false_list, flavors))
933 goto bad;
934 if (validate_avrules(handle, cond->avtrue_list, 1, flavors))
935 goto bad;
936 if (validate_avrules(handle, cond->avfalse_list, 1, flavors))
937 goto bad;
938 if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS]))
939 goto bad;
940 }
941
942 return 0;
943
944 bad:
945 ERR(handle, "Invalid cond list");
946 return -1;
947 }
948
validate_role_transes(sepol_handle_t * handle,role_trans_t * role_trans,validate_t flavors[])949 static int validate_role_transes(sepol_handle_t *handle, role_trans_t *role_trans, validate_t flavors[])
950 {
951 for (; role_trans; role_trans = role_trans->next) {
952 if (validate_value(role_trans->role, &flavors[SYM_ROLES]))
953 goto bad;
954 if (validate_value(role_trans->type, &flavors[SYM_TYPES]))
955 goto bad;
956 if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES]))
957 goto bad;
958 if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
959 goto bad;
960 }
961
962 return 0;
963
964 bad:
965 ERR(handle, "Invalid role trans");
966 return -1;
967 }
968
validate_role_allows(sepol_handle_t * handle,role_allow_t * role_allow,validate_t flavors[])969 static int validate_role_allows(sepol_handle_t *handle, role_allow_t *role_allow, validate_t flavors[])
970 {
971 for (; role_allow; role_allow = role_allow->next) {
972 if (validate_value(role_allow->role, &flavors[SYM_ROLES]))
973 goto bad;
974 if (validate_value(role_allow->new_role, &flavors[SYM_ROLES]))
975 goto bad;
976 }
977
978 return 0;
979
980 bad:
981 ERR(handle, "Invalid role allow");
982 return -1;
983 }
984
validate_filename_trans(hashtab_key_t k,hashtab_datum_t d,void * args)985 static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args)
986 {
987 filename_trans_key_t *ftk = (filename_trans_key_t *)k;
988 filename_trans_datum_t *ftd = d;
989 validate_t *flavors = (validate_t *)args;
990
991 if (validate_value(ftk->ttype, &flavors[SYM_TYPES]))
992 goto bad;
993 if (validate_value(ftk->tclass, &flavors[SYM_CLASSES]))
994 goto bad;
995 for (; ftd; ftd = ftd->next) {
996 if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES]))
997 goto bad;
998 if (validate_value(ftd->otype, &flavors[SYM_TYPES]))
999 goto bad;
1000 }
1001
1002 return 0;
1003
1004 bad:
1005 return -1;
1006 }
1007
validate_filename_trans_hashtab(sepol_handle_t * handle,hashtab_t filename_trans,validate_t flavors[])1008 static int validate_filename_trans_hashtab(sepol_handle_t *handle, hashtab_t filename_trans, validate_t flavors[])
1009 {
1010 if (hashtab_map(filename_trans, validate_filename_trans, flavors)) {
1011 ERR(handle, "Invalid filename trans");
1012 return -1;
1013 }
1014
1015 return 0;
1016 }
1017
validate_context(context_struct_t * con,validate_t flavors[],int mls)1018 static int validate_context(context_struct_t *con, validate_t flavors[], int mls)
1019 {
1020 if (validate_value(con->user, &flavors[SYM_USERS]))
1021 return -1;
1022 if (validate_value(con->role, &flavors[SYM_ROLES]))
1023 return -1;
1024 if (validate_value(con->type, &flavors[SYM_TYPES]))
1025 return -1;
1026 if (mls && validate_mls_range(&con->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1027 return -1;
1028
1029 return 0;
1030 }
1031
validate_ocontexts(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])1032 static int validate_ocontexts(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
1033 {
1034 ocontext_t *octx;
1035 unsigned int i;
1036
1037 for (i = 0; i < OCON_NUM; i++) {
1038 for (octx = p->ocontexts[i]; octx; octx = octx->next) {
1039 if (validate_context(&octx->context[0], flavors, p->mls))
1040 goto bad;
1041
1042 if (p->target_platform == SEPOL_TARGET_SELINUX) {
1043 switch (i) {
1044 case OCON_FS:
1045 case OCON_NETIF:
1046 if (validate_context(&octx->context[1], flavors, p->mls))
1047 goto bad;
1048 break;
1049 case OCON_FSUSE:
1050 switch (octx->v.behavior) {
1051 case SECURITY_FS_USE_XATTR:
1052 case SECURITY_FS_USE_TRANS:
1053 case SECURITY_FS_USE_TASK:
1054 break;
1055 default:
1056 goto bad;
1057 }
1058 }
1059 }
1060 }
1061 }
1062
1063 return 0;
1064
1065 bad:
1066 ERR(handle, "Invalid ocontext");
1067 return -1;
1068 }
1069
validate_genfs(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])1070 static int validate_genfs(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
1071 {
1072 genfs_t *genfs;
1073 ocontext_t *octx;
1074
1075 for (genfs = p->genfs; genfs; genfs = genfs->next) {
1076 for (octx = genfs->head; octx; octx = octx->next) {
1077 if (validate_context(&octx->context[0], flavors, p->mls))
1078 goto bad;
1079 }
1080 }
1081
1082 return 0;
1083
1084 bad:
1085 ERR(handle, "Invalid genfs");
1086 return -1;
1087 }
1088
1089 /*
1090 * Functions to validate a module policydb
1091 */
1092
validate_role_trans_rules(sepol_handle_t * handle,role_trans_rule_t * role_trans,validate_t flavors[])1093 static int validate_role_trans_rules(sepol_handle_t *handle, role_trans_rule_t *role_trans, validate_t flavors[])
1094 {
1095 for (; role_trans; role_trans = role_trans->next) {
1096 if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES]))
1097 goto bad;
1098 if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES]))
1099 goto bad;
1100 if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES]))
1101 goto bad;
1102 if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
1103 goto bad;
1104 }
1105
1106 return 0;
1107
1108 bad:
1109 ERR(handle, "Invalid role trans rule");
1110 return -1;
1111 }
1112
validate_role_allow_rules(sepol_handle_t * handle,role_allow_rule_t * role_allow,validate_t flavors[])1113 static int validate_role_allow_rules(sepol_handle_t *handle, role_allow_rule_t *role_allow, validate_t flavors[])
1114 {
1115 for (; role_allow; role_allow = role_allow->next) {
1116 if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES]))
1117 goto bad;
1118 if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES]))
1119 goto bad;
1120 }
1121
1122 return 0;
1123
1124 bad:
1125 ERR(handle, "Invalid role allow rule");
1126 return -1;
1127 }
1128
validate_range_trans_rules(sepol_handle_t * handle,range_trans_rule_t * range_trans,validate_t flavors[])1129 static int validate_range_trans_rules(sepol_handle_t *handle, range_trans_rule_t *range_trans, validate_t flavors[])
1130 {
1131 for (; range_trans; range_trans = range_trans->next) {
1132 if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES]))
1133 goto bad;
1134 if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES]))
1135 goto bad;
1136 if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES]))
1137 goto bad;
1138 if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1139 goto bad;
1140 }
1141
1142 return 0;
1143
1144 bad:
1145 ERR(handle, "Invalid range trans rule");
1146 return -1;
1147 }
1148
validate_scope_index(sepol_handle_t * handle,scope_index_t * scope_index,validate_t flavors[])1149 static int validate_scope_index(sepol_handle_t *handle, scope_index_t *scope_index, validate_t flavors[])
1150 {
1151 if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES]))
1152 goto bad;
1153 if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES]))
1154 goto bad;
1155 if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES]))
1156 goto bad;
1157 if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS]))
1158 goto bad;
1159 if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS]))
1160 goto bad;
1161 if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS]))
1162 goto bad;
1163 if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS]))
1164 goto bad;
1165 if (scope_index->class_perms_len > flavors[SYM_CLASSES].nprim)
1166 goto bad;
1167
1168 return 0;
1169
1170 bad:
1171 ERR(handle, "Invalid scope");
1172 return -1;
1173 }
1174
1175
validate_filename_trans_rules(sepol_handle_t * handle,filename_trans_rule_t * filename_trans,validate_t flavors[])1176 static int validate_filename_trans_rules(sepol_handle_t *handle, filename_trans_rule_t *filename_trans, validate_t flavors[])
1177 {
1178 for (; filename_trans; filename_trans = filename_trans->next) {
1179 if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES]))
1180 goto bad;
1181 if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES]))
1182 goto bad;
1183 if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] ))
1184 goto bad;
1185 if (validate_value(filename_trans->otype, &flavors[SYM_TYPES]))
1186 goto bad;
1187
1188 /* currently only the RULE_SELF flag can be set */
1189 if ((filename_trans->flags & ~RULE_SELF) != 0)
1190 goto bad;
1191 }
1192
1193 return 0;
1194
1195 bad:
1196 ERR(handle, "Invalid filename trans rule list");
1197 return -1;
1198 }
1199
validate_symtabs(sepol_handle_t * handle,symtab_t symtabs[],validate_t flavors[])1200 static int validate_symtabs(sepol_handle_t *handle, symtab_t symtabs[], validate_t flavors[])
1201 {
1202 unsigned int i;
1203
1204 for (i = 0; i < SYM_NUM; i++) {
1205 if (hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) {
1206 ERR(handle, "Invalid symtab");
1207 return -1;
1208 }
1209 }
1210
1211 return 0;
1212 }
1213
validate_avrule_blocks(sepol_handle_t * handle,avrule_block_t * avrule_block,validate_t flavors[])1214 static int validate_avrule_blocks(sepol_handle_t *handle, avrule_block_t *avrule_block, validate_t flavors[])
1215 {
1216 avrule_decl_t *decl;
1217
1218 for (; avrule_block; avrule_block = avrule_block->next) {
1219 for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) {
1220 if (validate_cond_list(handle, decl->cond_list, flavors))
1221 goto bad;
1222 if (validate_avrules(handle, decl->avrules, 0, flavors))
1223 goto bad;
1224 if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors))
1225 goto bad;
1226 if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors))
1227 goto bad;
1228 if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors))
1229 goto bad;
1230 if (validate_scope_index(handle, &decl->required, flavors))
1231 goto bad;
1232 if (validate_scope_index(handle, &decl->declared, flavors))
1233 goto bad;
1234 if (validate_filename_trans_rules(handle, decl->filename_trans_rules, flavors))
1235 goto bad;
1236 if (validate_symtabs(handle, decl->symtab, flavors))
1237 goto bad;
1238 }
1239
1240 switch (avrule_block->flags) {
1241 case 0:
1242 case AVRULE_OPTIONAL:
1243 break;
1244 default:
1245 goto bad;
1246 }
1247 }
1248
1249 return 0;
1250
1251 bad:
1252 ERR(handle, "Invalid avrule block");
1253 return -1;
1254 }
1255
validate_permissives(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])1256 static int validate_permissives(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
1257 {
1258 ebitmap_node_t *node;
1259 unsigned i;
1260
1261 ebitmap_for_each_positive_bit(&p->permissive_map, node, i) {
1262 if (validate_value(i, &flavors[SYM_TYPES]))
1263 goto bad;
1264 }
1265
1266 return 0;
1267
1268 bad:
1269 ERR(handle, "Invalid permissive type");
1270 return -1;
1271 }
1272
validate_properties(sepol_handle_t * handle,policydb_t * p)1273 static int validate_properties(sepol_handle_t *handle, policydb_t *p)
1274 {
1275 switch (p->policy_type) {
1276 case POLICY_KERN:
1277 if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX)
1278 goto bad;
1279 break;
1280 case POLICY_BASE:
1281 case POLICY_MOD:
1282 if (p->policyvers < MOD_POLICYDB_VERSION_MIN || p->policyvers > MOD_POLICYDB_VERSION_MAX)
1283 goto bad;
1284 break;
1285 default:
1286 goto bad;
1287 }
1288
1289 switch (p->target_platform) {
1290 case SEPOL_TARGET_SELINUX:
1291 case SEPOL_TARGET_XEN:
1292 break;
1293 default:
1294 goto bad;
1295 }
1296
1297 switch (p->mls) {
1298 case 0:
1299 case 1:
1300 break;
1301 default:
1302 goto bad;
1303 }
1304
1305 switch (p->handle_unknown) {
1306 case SEPOL_DENY_UNKNOWN:
1307 case SEPOL_REJECT_UNKNOWN:
1308 case SEPOL_ALLOW_UNKNOWN:
1309 break;
1310 default:
1311 goto bad;
1312 }
1313
1314 return 0;
1315
1316 bad:
1317 ERR(handle, "Invalid policy property");
1318 return -1;
1319 }
1320
validate_array_destroy(validate_t flavors[])1321 static void validate_array_destroy(validate_t flavors[])
1322 {
1323 unsigned int i;
1324
1325 for (i = 0; i < SYM_NUM; i++) {
1326 ebitmap_destroy(&flavors[i].gaps);
1327 }
1328 }
1329
1330 /*
1331 * Validate policydb
1332 */
validate_policydb(sepol_handle_t * handle,policydb_t * p)1333 int validate_policydb(sepol_handle_t *handle, policydb_t *p)
1334 {
1335 validate_t flavors[SYM_NUM] = {};
1336
1337 if (validate_array_init(p, flavors))
1338 goto bad;
1339
1340 if (validate_properties(handle, p))
1341 goto bad;
1342
1343 if (p->policy_type == POLICY_KERN) {
1344 if (validate_avtab(handle, &p->te_avtab, flavors))
1345 goto bad;
1346 if (p->policyvers >= POLICYDB_VERSION_BOOL)
1347 if (validate_cond_list(handle, p->cond_list, flavors))
1348 goto bad;
1349 if (validate_role_transes(handle, p->role_tr, flavors))
1350 goto bad;
1351 if (validate_role_allows(handle, p->role_allow, flavors))
1352 goto bad;
1353 if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS)
1354 if (validate_filename_trans_hashtab(handle, p->filename_trans, flavors))
1355 goto bad;
1356 } else {
1357 if (validate_avrule_blocks(handle, p->global, flavors))
1358 goto bad;
1359 }
1360
1361 if (validate_ocontexts(handle, p, flavors))
1362 goto bad;
1363
1364 if (validate_genfs(handle, p, flavors))
1365 goto bad;
1366
1367 if (validate_scopes(handle, p->scope, p->global))
1368 goto bad;
1369
1370 if (validate_datum_array_gaps(handle, p, flavors))
1371 goto bad;
1372
1373 if (validate_datum_array_entries(handle, p, flavors))
1374 goto bad;
1375
1376 if (validate_permissives(handle, p, flavors))
1377 goto bad;
1378
1379 validate_array_destroy(flavors);
1380
1381 return 0;
1382
1383 bad:
1384 ERR(handle, "Invalid policydb");
1385 validate_array_destroy(flavors);
1386 return -1;
1387 }
1388