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