• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_list(sepol_handle_t * handle,cond_list_t * cond,validate_t flavors[])884 static int validate_cond_list(sepol_handle_t *handle, cond_list_t *cond, validate_t flavors[])
885 {
886 	for (; cond; cond = cond->next) {
887 		if (validate_cond_av_list(handle, cond->true_list, flavors))
888 			goto bad;
889 		if (validate_cond_av_list(handle, cond->false_list, flavors))
890 			goto bad;
891 		if (validate_avrules(handle, cond->avtrue_list, 1, flavors))
892 			goto bad;
893 		if (validate_avrules(handle, cond->avfalse_list, 1, flavors))
894 			goto bad;
895 		if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS]))
896 			goto bad;
897 	}
898 
899 	return 0;
900 
901 bad:
902 	ERR(handle, "Invalid cond list");
903 	return -1;
904 }
905 
validate_role_transes(sepol_handle_t * handle,role_trans_t * role_trans,validate_t flavors[])906 static int validate_role_transes(sepol_handle_t *handle, role_trans_t *role_trans, validate_t flavors[])
907 {
908 	for (; role_trans; role_trans = role_trans->next) {
909 		if (validate_value(role_trans->role, &flavors[SYM_ROLES]))
910 			goto bad;
911 		if (validate_value(role_trans->type, &flavors[SYM_TYPES]))
912 			goto bad;
913 		if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES]))
914 			goto bad;
915 		if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
916 			goto bad;
917 	}
918 
919 	return 0;
920 
921 bad:
922 	ERR(handle, "Invalid role trans");
923 	return -1;
924 }
925 
validate_role_allows(sepol_handle_t * handle,role_allow_t * role_allow,validate_t flavors[])926 static int validate_role_allows(sepol_handle_t *handle, role_allow_t *role_allow, validate_t flavors[])
927 {
928 	for (; role_allow; role_allow = role_allow->next) {
929 		if (validate_value(role_allow->role, &flavors[SYM_ROLES]))
930 			goto bad;
931 		if (validate_value(role_allow->new_role, &flavors[SYM_ROLES]))
932 			goto bad;
933 	}
934 
935 	return 0;
936 
937 bad:
938 	ERR(handle, "Invalid role allow");
939 	return -1;
940 }
941 
validate_filename_trans(hashtab_key_t k,hashtab_datum_t d,void * args)942 static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args)
943 {
944 	filename_trans_key_t *ftk = (filename_trans_key_t *)k;
945 	filename_trans_datum_t *ftd = d;
946 	validate_t *flavors = (validate_t *)args;
947 
948 	if (validate_value(ftk->ttype, &flavors[SYM_TYPES]))
949 		goto bad;
950 	if (validate_value(ftk->tclass, &flavors[SYM_CLASSES]))
951 		goto bad;
952 	for (; ftd; ftd = ftd->next) {
953 		if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES]))
954 			goto bad;
955 		if (validate_value(ftd->otype, &flavors[SYM_TYPES]))
956 			goto bad;
957 	}
958 
959 	return 0;
960 
961 bad:
962 	return -1;
963 }
964 
validate_filename_trans_hashtab(sepol_handle_t * handle,hashtab_t filename_trans,validate_t flavors[])965 static int validate_filename_trans_hashtab(sepol_handle_t *handle, hashtab_t filename_trans, validate_t flavors[])
966 {
967 	if (hashtab_map(filename_trans, validate_filename_trans, flavors)) {
968 		ERR(handle, "Invalid filename trans");
969 		return -1;
970 	}
971 
972 	return 0;
973 }
974 
validate_context(context_struct_t * con,validate_t flavors[],int mls)975 static int validate_context(context_struct_t *con, validate_t flavors[], int mls)
976 {
977 	if (validate_value(con->user, &flavors[SYM_USERS]))
978 		return -1;
979 	if (validate_value(con->role, &flavors[SYM_ROLES]))
980 		return -1;
981 	if (validate_value(con->type, &flavors[SYM_TYPES]))
982 		return -1;
983 	if (mls && validate_mls_range(&con->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
984 		return -1;
985 
986 	return 0;
987 }
988 
validate_ocontexts(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])989 static int validate_ocontexts(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
990 {
991 	ocontext_t *octx;
992 	unsigned int i;
993 
994 	for (i = 0; i < OCON_NUM; i++) {
995 		for (octx = p->ocontexts[i]; octx; octx = octx->next) {
996 			if (validate_context(&octx->context[0], flavors, p->mls))
997 				goto bad;
998 
999 			if (p->target_platform == SEPOL_TARGET_SELINUX) {
1000 				switch (i) {
1001 				case OCON_FS:
1002 				case OCON_NETIF:
1003 					if (validate_context(&octx->context[1], flavors, p->mls))
1004 						goto bad;
1005 					break;
1006 				case OCON_FSUSE:
1007 					switch (octx->v.behavior) {
1008 					case SECURITY_FS_USE_XATTR:
1009 					case SECURITY_FS_USE_TRANS:
1010 					case SECURITY_FS_USE_TASK:
1011 						break;
1012 					default:
1013 						goto bad;
1014 					}
1015 				}
1016 			}
1017 		}
1018 	}
1019 
1020 	return 0;
1021 
1022 bad:
1023 	ERR(handle, "Invalid ocontext");
1024 	return -1;
1025 }
1026 
validate_genfs(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])1027 static int validate_genfs(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
1028 {
1029 	genfs_t *genfs;
1030 	ocontext_t *octx;
1031 
1032 	for (genfs = p->genfs; genfs; genfs = genfs->next) {
1033 		for (octx = genfs->head; octx; octx = octx->next) {
1034 			if (validate_context(&octx->context[0], flavors, p->mls))
1035 				goto bad;
1036 		}
1037 	}
1038 
1039 	return 0;
1040 
1041 bad:
1042 	ERR(handle, "Invalid genfs");
1043 	return -1;
1044 }
1045 
1046 /*
1047  * Functions to validate a module policydb
1048  */
1049 
validate_role_trans_rules(sepol_handle_t * handle,role_trans_rule_t * role_trans,validate_t flavors[])1050 static int validate_role_trans_rules(sepol_handle_t *handle, role_trans_rule_t *role_trans, validate_t flavors[])
1051 {
1052 	for (; role_trans; role_trans = role_trans->next) {
1053 		if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES]))
1054 			goto bad;
1055 		if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES]))
1056 			goto bad;
1057 		if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES]))
1058 			goto bad;
1059 		if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
1060 			goto bad;
1061 	}
1062 
1063 	return 0;
1064 
1065 bad:
1066 	ERR(handle, "Invalid role trans rule");
1067 	return -1;
1068 }
1069 
validate_role_allow_rules(sepol_handle_t * handle,role_allow_rule_t * role_allow,validate_t flavors[])1070 static int validate_role_allow_rules(sepol_handle_t *handle, role_allow_rule_t *role_allow, validate_t flavors[])
1071 {
1072 	for (; role_allow; role_allow = role_allow->next) {
1073 		if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES]))
1074 			goto bad;
1075 		if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES]))
1076 			goto bad;
1077 	}
1078 
1079 	return 0;
1080 
1081 bad:
1082 	ERR(handle, "Invalid role allow rule");
1083 	return -1;
1084 }
1085 
validate_range_trans_rules(sepol_handle_t * handle,range_trans_rule_t * range_trans,validate_t flavors[])1086 static int validate_range_trans_rules(sepol_handle_t *handle, range_trans_rule_t *range_trans, validate_t flavors[])
1087 {
1088 	for (; range_trans; range_trans = range_trans->next) {
1089 		if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES]))
1090 			goto bad;
1091 		if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES]))
1092 			goto bad;
1093 		if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES]))
1094 			goto bad;
1095 		if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1096 			goto bad;
1097 	}
1098 
1099 	return 0;
1100 
1101 bad:
1102 	ERR(handle, "Invalid range trans rule");
1103 	return -1;
1104 }
1105 
validate_scope_index(sepol_handle_t * handle,scope_index_t * scope_index,validate_t flavors[])1106 static int validate_scope_index(sepol_handle_t *handle, scope_index_t *scope_index, validate_t flavors[])
1107 {
1108 	if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES]))
1109 		goto bad;
1110 	if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES]))
1111 		goto bad;
1112 	if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES]))
1113 		goto bad;
1114 	if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS]))
1115 		goto bad;
1116 	if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS]))
1117 		goto bad;
1118 	if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS]))
1119 		goto bad;
1120 	if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS]))
1121 		goto bad;
1122 	if (scope_index->class_perms_len > flavors[SYM_CLASSES].nprim)
1123 		goto bad;
1124 
1125 	return 0;
1126 
1127 bad:
1128 	ERR(handle, "Invalid scope");
1129 	return -1;
1130 }
1131 
1132 
validate_filename_trans_rules(sepol_handle_t * handle,filename_trans_rule_t * filename_trans,validate_t flavors[])1133 static int validate_filename_trans_rules(sepol_handle_t *handle, filename_trans_rule_t *filename_trans, validate_t flavors[])
1134 {
1135 	for (; filename_trans; filename_trans = filename_trans->next) {
1136 		if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES]))
1137 			goto bad;
1138 		if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES]))
1139 			goto bad;
1140 		if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] ))
1141 			goto bad;
1142 		if (validate_value(filename_trans->otype, &flavors[SYM_TYPES]))
1143 			goto bad;
1144 	}
1145 
1146 	return 0;
1147 
1148 bad:
1149 	ERR(handle, "Invalid filename trans rule list");
1150 	return -1;
1151 }
1152 
validate_symtabs(sepol_handle_t * handle,symtab_t symtabs[],validate_t flavors[])1153 static int validate_symtabs(sepol_handle_t *handle, symtab_t symtabs[], validate_t flavors[])
1154 {
1155 	unsigned int i;
1156 
1157 	for (i = 0; i < SYM_NUM; i++) {
1158 		if (hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) {
1159 			ERR(handle, "Invalid symtab");
1160 			return -1;
1161 		}
1162 	}
1163 
1164 	return 0;
1165 }
1166 
validate_avrule_blocks(sepol_handle_t * handle,avrule_block_t * avrule_block,validate_t flavors[])1167 static int validate_avrule_blocks(sepol_handle_t *handle, avrule_block_t *avrule_block, validate_t flavors[])
1168 {
1169 	avrule_decl_t *decl;
1170 
1171 	for (; avrule_block; avrule_block = avrule_block->next) {
1172 		for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) {
1173 			if (validate_cond_list(handle, decl->cond_list, flavors))
1174 				goto bad;
1175 			if (validate_avrules(handle, decl->avrules, 0, flavors))
1176 				goto bad;
1177 			if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors))
1178 				goto bad;
1179 			if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors))
1180 				goto bad;
1181 			if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors))
1182 				goto bad;
1183 			if (validate_scope_index(handle, &decl->required, flavors))
1184 				goto bad;
1185 			if (validate_scope_index(handle, &decl->declared, flavors))
1186 				goto bad;
1187 			if (validate_filename_trans_rules(handle, decl->filename_trans_rules, flavors))
1188 				goto bad;
1189 			if (validate_symtabs(handle, decl->symtab, flavors))
1190 				goto bad;
1191 		}
1192 
1193 		switch (avrule_block->flags) {
1194 		case 0:
1195 		case AVRULE_OPTIONAL:
1196 			break;
1197 		default:
1198 			goto bad;
1199 		}
1200 	}
1201 
1202 	return 0;
1203 
1204 bad:
1205 	ERR(handle, "Invalid avrule block");
1206 	return -1;
1207 }
1208 
validate_permissives(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])1209 static int validate_permissives(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
1210 {
1211 	ebitmap_node_t *node;
1212 	unsigned i;
1213 
1214 	ebitmap_for_each_positive_bit(&p->permissive_map, node, i) {
1215 		if (validate_value(i, &flavors[SYM_TYPES]))
1216 			goto bad;
1217 	}
1218 
1219 	return 0;
1220 
1221 bad:
1222 	ERR(handle, "Invalid permissive type");
1223 	return -1;
1224 }
1225 
validate_properties(sepol_handle_t * handle,policydb_t * p)1226 static int validate_properties(sepol_handle_t *handle, policydb_t *p)
1227 {
1228 	switch (p->policy_type) {
1229 	case POLICY_KERN:
1230 		if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX)
1231 			goto bad;
1232 		break;
1233 	case POLICY_BASE:
1234 	case POLICY_MOD:
1235 		if (p->policyvers < MOD_POLICYDB_VERSION_MIN || p->policyvers > MOD_POLICYDB_VERSION_MAX)
1236 			goto bad;
1237 		break;
1238 	default:
1239 		goto bad;
1240 	}
1241 
1242 	switch (p->target_platform) {
1243 	case SEPOL_TARGET_SELINUX:
1244 	case SEPOL_TARGET_XEN:
1245 		break;
1246 	default:
1247 		goto bad;
1248 	}
1249 
1250 	switch (p->mls) {
1251 	case 0:
1252 	case 1:
1253 		break;
1254 	default:
1255 		goto bad;
1256 	}
1257 
1258 	switch (p->handle_unknown) {
1259 	case SEPOL_DENY_UNKNOWN:
1260 	case SEPOL_REJECT_UNKNOWN:
1261 	case SEPOL_ALLOW_UNKNOWN:
1262 		break;
1263 	default:
1264 		goto bad;
1265 	}
1266 
1267 	return 0;
1268 
1269 bad:
1270 	ERR(handle, "Invalid policy property");
1271 	return -1;
1272 }
1273 
validate_array_destroy(validate_t flavors[])1274 static void validate_array_destroy(validate_t flavors[])
1275 {
1276 	unsigned int i;
1277 
1278 	for (i = 0; i < SYM_NUM; i++) {
1279 		ebitmap_destroy(&flavors[i].gaps);
1280 	}
1281 }
1282 
1283 /*
1284  * Validate policydb
1285  */
validate_policydb(sepol_handle_t * handle,policydb_t * p)1286 int validate_policydb(sepol_handle_t *handle, policydb_t *p)
1287 {
1288 	validate_t flavors[SYM_NUM] = {};
1289 
1290 	if (validate_array_init(p, flavors))
1291 		goto bad;
1292 
1293 	if (validate_properties(handle, p))
1294 		goto bad;
1295 
1296 	if (p->policy_type == POLICY_KERN) {
1297 		if (validate_avtab(handle, &p->te_avtab, flavors))
1298 			goto bad;
1299 		if (p->policyvers >= POLICYDB_VERSION_BOOL)
1300 			if (validate_cond_list(handle, p->cond_list, flavors))
1301 				goto bad;
1302 		if (validate_role_transes(handle, p->role_tr, flavors))
1303 			goto bad;
1304 		if (validate_role_allows(handle, p->role_allow, flavors))
1305 			goto bad;
1306 		if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS)
1307 			if (validate_filename_trans_hashtab(handle, p->filename_trans, flavors))
1308 				goto bad;
1309 	} else {
1310 		if (validate_avrule_blocks(handle, p->global, flavors))
1311 			goto bad;
1312 	}
1313 
1314 	if (validate_ocontexts(handle, p, flavors))
1315 		goto bad;
1316 
1317 	if (validate_genfs(handle, p, flavors))
1318 		goto bad;
1319 
1320 	if (validate_scopes(handle, p->scope, p->global))
1321 		goto bad;
1322 
1323 	if (validate_datum_array_gaps(handle, p, flavors))
1324 		goto bad;
1325 
1326 	if (validate_datum_array_entries(handle, p, flavors))
1327 		goto bad;
1328 
1329 	if (validate_permissives(handle, p, flavors))
1330 		goto bad;
1331 
1332 	validate_array_destroy(flavors);
1333 
1334 	return 0;
1335 
1336 bad:
1337 	ERR(handle, "Invalid policydb");
1338 	validate_array_destroy(flavors);
1339 	return -1;
1340 }
1341