• 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_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