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