• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 		break;
925 	default:
926 		goto bad;
927 	}
928 
929 	return 0;
930 
931 bad:
932 	return -1;
933 }
934 
validate_access_vector(sepol_handle_t * handle,const policydb_t * p,sepol_security_class_t tclass,sepol_access_vector_t av)935 static int validate_access_vector(sepol_handle_t *handle, const policydb_t *p, sepol_security_class_t tclass,
936 				  sepol_access_vector_t av)
937 {
938 	const class_datum_t *cladatum = p->class_val_to_struct[tclass - 1];
939 
940 	/*
941 	 * Check that at least one permission bit is valid.
942 	 * Older compilers might set invalid bits for the wildcard permission.
943 	 */
944 	if (!(av & PERMISSION_MASK(cladatum->permissions.nprim)))
945 		goto bad;
946 
947 	return 0;
948 
949 bad:
950 	ERR(handle, "Invalid access vector");
951 	return -1;
952 }
953 
validate_avtab_key_and_datum(avtab_key_t * k,avtab_datum_t * d,void * args)954 static int validate_avtab_key_and_datum(avtab_key_t *k, avtab_datum_t *d, void *args)
955 {
956 	map_arg_t *margs = args;
957 
958 	if (validate_avtab_key(k, 0, margs->policy, margs->flavors))
959 		return -1;
960 
961 	if (k->specified & AVTAB_AV) {
962 		uint32_t data = d->data;
963 
964 		if ((0xFFF & k->specified) == AVTAB_AUDITDENY)
965 			data = ~data;
966 
967 		if (validate_access_vector(margs->handle, margs->policy, k->target_class, data))
968 			return -1;
969 	}
970 
971 	if ((k->specified & AVTAB_TYPE) && validate_simpletype(d->data, margs->policy, margs->flavors))
972 		return -1;
973 
974 	if ((k->specified & AVTAB_XPERMS) && validate_xperms(d->xperms))
975 		return -1;
976 
977 	return 0;
978 }
979 
validate_avtab(sepol_handle_t * handle,const avtab_t * avtab,const policydb_t * p,validate_t flavors[])980 static int validate_avtab(sepol_handle_t *handle, const avtab_t *avtab, const policydb_t *p, validate_t flavors[])
981 {
982 	map_arg_t margs = { flavors, handle, p };
983 
984 	if (avtab_map(avtab, validate_avtab_key_and_datum, &margs)) {
985 		ERR(handle, "Invalid avtab");
986 		return -1;
987 	}
988 
989 	return 0;
990 }
991 
validate_cond_av_list(sepol_handle_t * handle,const cond_av_list_t * cond_av,const policydb_t * p,validate_t flavors[])992 static int validate_cond_av_list(sepol_handle_t *handle, const cond_av_list_t *cond_av, const policydb_t *p, validate_t flavors[])
993 {
994 	const struct avtab_node *avtab_ptr;
995 
996 	for (; cond_av; cond_av = cond_av->next) {
997 		for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) {
998 			const avtab_key_t *key = &avtab_ptr->key;
999 			const avtab_datum_t *datum = &avtab_ptr->datum;
1000 
1001 			if (validate_avtab_key(key, 1, p, flavors))
1002 				goto bad;
1003 			if (key->specified & AVTAB_AV) {
1004 				uint32_t data = datum->data;
1005 
1006 				if ((0xFFF & key->specified) == AVTAB_AUDITDENY)
1007 					data = ~data;
1008 
1009 				if (validate_access_vector(handle, p, key->target_class, data))
1010 					goto bad;
1011 			}
1012 			if ((key->specified & AVTAB_TYPE) && validate_simpletype(datum->data, p, flavors))
1013 				goto bad;
1014 		}
1015 	}
1016 
1017 	return 0;
1018 
1019 bad:
1020 	ERR(handle, "Invalid cond av list");
1021 	return -1;
1022 }
1023 
validate_avrules(sepol_handle_t * handle,const avrule_t * avrule,int conditional,const policydb_t * p,validate_t flavors[])1024 static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int conditional, const policydb_t *p, validate_t flavors[])
1025 {
1026 	const class_perm_node_t *classperm;
1027 
1028 	for (; avrule; avrule = avrule->next) {
1029 		if (validate_type_set(&avrule->stypes, &flavors[SYM_TYPES]))
1030 			goto bad;
1031 		if (validate_type_set(&avrule->ttypes, &flavors[SYM_TYPES]))
1032 			goto bad;
1033 
1034 		switch(avrule->specified) {
1035 		case AVRULE_ALLOWED:
1036 		case AVRULE_AUDITALLOW:
1037 		case AVRULE_AUDITDENY:
1038 		case AVRULE_DONTAUDIT:
1039 		case AVRULE_TRANSITION:
1040 		case AVRULE_MEMBER:
1041 		case AVRULE_CHANGE:
1042 			break;
1043 		case AVRULE_NEVERALLOW:
1044 		case AVRULE_XPERMS_ALLOWED:
1045 		case AVRULE_XPERMS_AUDITALLOW:
1046 		case AVRULE_XPERMS_DONTAUDIT:
1047 		case AVRULE_XPERMS_NEVERALLOW:
1048 			if (conditional)
1049 				goto bad;
1050 			break;
1051 		default:
1052 			goto bad;
1053 		}
1054 
1055 		for (classperm = avrule->perms; classperm; classperm = classperm->next) {
1056 			if (validate_value(classperm->tclass, &flavors[SYM_CLASSES]))
1057 				goto bad;
1058 			if ((avrule->specified & AVRULE_TYPE) && validate_simpletype(classperm->data, p, flavors))
1059 				goto bad;
1060 		}
1061 
1062 		if (avrule->specified & AVRULE_XPERMS) {
1063 			if (p->target_platform != SEPOL_TARGET_SELINUX)
1064 				goto bad;
1065 			if (!avrule->xperms)
1066 				goto bad;
1067 			switch (avrule->xperms->specified) {
1068 			case AVRULE_XPERMS_IOCTLFUNCTION:
1069 			case AVRULE_XPERMS_IOCTLDRIVER:
1070 				break;
1071 			default:
1072 				goto bad;
1073 			}
1074 		} else if (avrule->xperms)
1075 			goto bad;
1076 
1077 		switch(avrule->flags) {
1078 		case 0:
1079 			break;
1080 		case RULE_SELF:
1081 			if (p->policyvers != POLICY_KERN &&
1082 			    p->policyvers < MOD_POLICYDB_VERSION_SELF_TYPETRANS &&
1083 			    (avrule->specified & AVRULE_TYPE))
1084 				goto bad;
1085 			break;
1086 		case RULE_NOTSELF:
1087 			switch(avrule->specified) {
1088 			case AVRULE_NEVERALLOW:
1089 			case AVRULE_XPERMS_NEVERALLOW:
1090 				break;
1091 			default:
1092 				goto bad;
1093 			}
1094 			break;
1095 		default:
1096 			goto bad;
1097 		}
1098 	}
1099 
1100 	return 0;
1101 
1102 bad:
1103 	ERR(handle, "Invalid avrule");
1104 	return -1;
1105 }
1106 
validate_bool_id_array(sepol_handle_t * handle,const uint32_t bool_ids[],unsigned int nbools,const validate_t * boolean)1107 static int validate_bool_id_array(sepol_handle_t *handle, const uint32_t bool_ids[], unsigned int nbools, const validate_t *boolean)
1108 {
1109 	unsigned int i;
1110 
1111 	if (nbools >= COND_MAX_BOOLS)
1112 		goto bad;
1113 
1114 	for (i=0; i < nbools; i++) {
1115 		if (validate_value(bool_ids[i], boolean))
1116 			goto bad;
1117 	}
1118 
1119 	return 0;
1120 
1121 bad:
1122 	ERR(handle, "Invalid bool id array");
1123 	return -1;
1124 }
1125 
validate_cond_expr(sepol_handle_t * handle,const struct cond_expr * expr,const validate_t * boolean)1126 static int validate_cond_expr(sepol_handle_t *handle, const struct cond_expr *expr, const validate_t *boolean)
1127 {
1128 	int depth = -1;
1129 
1130 	if (!expr)
1131 		goto bad;
1132 
1133 	for (; expr; expr = expr->next) {
1134 		switch(expr->expr_type) {
1135 		case COND_BOOL:
1136 			if (validate_value(expr->boolean, boolean))
1137 				goto bad;
1138 			if (depth >= (COND_EXPR_MAXDEPTH - 1))
1139 				goto bad;
1140 			depth++;
1141 			break;
1142 		case COND_NOT:
1143 			if (depth < 0)
1144 				goto bad;
1145 			if (expr->boolean != 0)
1146 				goto bad;
1147 			break;
1148 		case COND_OR:
1149 		case COND_AND:
1150 		case COND_XOR:
1151 		case COND_EQ:
1152 		case COND_NEQ:
1153 			if (depth < 1)
1154 				goto bad;
1155 			if (expr->boolean != 0)
1156 				goto bad;
1157 			depth--;
1158 			break;
1159 		default:
1160 			goto bad;
1161 		}
1162 	}
1163 
1164 	if (depth != 0)
1165 		goto bad;
1166 
1167 	return 0;
1168 
1169 bad:
1170 	ERR(handle, "Invalid cond expression");
1171 	return -1;
1172 }
1173 
validate_cond_list(sepol_handle_t * handle,const cond_list_t * cond,const policydb_t * p,validate_t flavors[])1174 static int validate_cond_list(sepol_handle_t *handle, const cond_list_t *cond, const policydb_t *p, validate_t flavors[])
1175 {
1176 	for (; cond; cond = cond->next) {
1177 		if (validate_cond_expr(handle, cond->expr, &flavors[SYM_BOOLS]))
1178 			goto bad;
1179 		if (validate_cond_av_list(handle, cond->true_list, p, flavors))
1180 			goto bad;
1181 		if (validate_cond_av_list(handle, cond->false_list, p, flavors))
1182 			goto bad;
1183 		if (validate_avrules(handle, cond->avtrue_list, 1, p, flavors))
1184 			goto bad;
1185 		if (validate_avrules(handle, cond->avfalse_list, 1, p, flavors))
1186 			goto bad;
1187 		if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS]))
1188 			goto bad;
1189 
1190 		switch (cond->cur_state) {
1191 		case 0:
1192 		case 1:
1193 			break;
1194 		default:
1195 			goto bad;
1196 		}
1197 
1198 		switch (cond->flags) {
1199 		case 0:
1200 		case COND_NODE_FLAGS_TUNABLE:
1201 			break;
1202 		default:
1203 			goto bad;
1204 		}
1205 	}
1206 
1207 	return 0;
1208 
1209 bad:
1210 	ERR(handle, "Invalid cond list");
1211 	return -1;
1212 }
1213 
validate_role_transes(sepol_handle_t * handle,const role_trans_t * role_trans,validate_t flavors[])1214 static int validate_role_transes(sepol_handle_t *handle, const role_trans_t *role_trans, validate_t flavors[])
1215 {
1216 	for (; role_trans; role_trans = role_trans->next) {
1217 		if (validate_value(role_trans->role, &flavors[SYM_ROLES]))
1218 			goto bad;
1219 		if (validate_value(role_trans->type, &flavors[SYM_TYPES]))
1220 			goto bad;
1221 		if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES]))
1222 			goto bad;
1223 		if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
1224 			goto bad;
1225 	}
1226 
1227 	return 0;
1228 
1229 bad:
1230 	ERR(handle, "Invalid role trans");
1231 	return -1;
1232 }
1233 
validate_role_allows(sepol_handle_t * handle,const role_allow_t * role_allow,validate_t flavors[])1234 static int validate_role_allows(sepol_handle_t *handle, const role_allow_t *role_allow, validate_t flavors[])
1235 {
1236 	for (; role_allow; role_allow = role_allow->next) {
1237 		if (validate_value(role_allow->role, &flavors[SYM_ROLES]))
1238 			goto bad;
1239 		if (validate_value(role_allow->new_role, &flavors[SYM_ROLES]))
1240 			goto bad;
1241 	}
1242 
1243 	return 0;
1244 
1245 bad:
1246 	ERR(handle, "Invalid role allow");
1247 	return -1;
1248 }
1249 
validate_filename_trans(hashtab_key_t k,hashtab_datum_t d,void * args)1250 static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args)
1251 {
1252 	const filename_trans_key_t *ftk = (filename_trans_key_t *)k;
1253 	const filename_trans_datum_t *ftd = d;
1254 	const map_arg_t *margs = args;
1255 	const validate_t *flavors = margs->flavors;
1256 	const policydb_t *p = margs->policy;
1257 
1258 	if (validate_value(ftk->ttype, &flavors[SYM_TYPES]))
1259 		goto bad;
1260 	if (validate_value(ftk->tclass, &flavors[SYM_CLASSES]))
1261 		goto bad;
1262 	if (!ftd)
1263 		goto bad;
1264 	for (; ftd; ftd = ftd->next) {
1265 		if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES]))
1266 			goto bad;
1267 		if (validate_simpletype(ftd->otype, p, flavors))
1268 			goto bad;
1269 	}
1270 
1271 	return 0;
1272 
1273 bad:
1274 	return -1;
1275 }
1276 
validate_filename_trans_hashtab(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1277 static int validate_filename_trans_hashtab(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1278 {
1279 	map_arg_t margs = { flavors, handle, p };
1280 
1281 	if (hashtab_map(p->filename_trans, validate_filename_trans, &margs)) {
1282 		ERR(handle, "Invalid filename trans");
1283 		return -1;
1284 	}
1285 
1286 	return 0;
1287 }
1288 
validate_context(const context_struct_t * con,validate_t flavors[],int mls)1289 static int validate_context(const context_struct_t *con, validate_t flavors[], int mls)
1290 {
1291 	if (validate_value(con->user, &flavors[SYM_USERS]))
1292 		return -1;
1293 	if (validate_value(con->role, &flavors[SYM_ROLES]))
1294 		return -1;
1295 	if (validate_value(con->type, &flavors[SYM_TYPES]))
1296 		return -1;
1297 	if (mls && validate_mls_range(&con->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1298 		return -1;
1299 
1300 	return 0;
1301 }
1302 
validate_ocontexts(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1303 static int validate_ocontexts(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1304 {
1305 	const ocontext_t *octx;
1306 	unsigned int i;
1307 
1308 	for (i = 0; i < OCON_NUM; i++) {
1309 		for (octx = p->ocontexts[i]; octx; octx = octx->next) {
1310 			if (validate_context(&octx->context[0], flavors, p->mls))
1311 				goto bad;
1312 
1313 			if (p->target_platform == SEPOL_TARGET_SELINUX) {
1314 				switch (i) {
1315 				case OCON_ISID:
1316 					if (octx->sid[0] == SEPOL_SECSID_NULL || octx->sid[0] >= SELINUX_SID_SZ)
1317 						goto bad;
1318 					break;
1319 				case OCON_FS:
1320 				case OCON_NETIF:
1321 					if (validate_context(&octx->context[1], flavors, p->mls))
1322 						goto bad;
1323 					if (!octx->u.name)
1324 						goto bad;
1325 					break;
1326 				case OCON_PORT:
1327 					if (octx->u.port.low_port > octx->u.port.high_port)
1328 						goto bad;
1329 					break;
1330 				case OCON_FSUSE:
1331 					switch (octx->v.behavior) {
1332 					case SECURITY_FS_USE_XATTR:
1333 					case SECURITY_FS_USE_TRANS:
1334 					case SECURITY_FS_USE_TASK:
1335 						break;
1336 					default:
1337 						goto bad;
1338 					}
1339 					if (!octx->u.name)
1340 						goto bad;
1341 					break;
1342 				case OCON_IBPKEY:
1343 					if (octx->u.ibpkey.low_pkey > octx->u.ibpkey.high_pkey)
1344 						goto bad;
1345 					break;
1346 				case OCON_IBENDPORT:
1347 					if (octx->u.ibendport.port == 0)
1348 						goto bad;
1349 					if (!octx->u.ibendport.dev_name)
1350 						goto bad;
1351 					break;
1352 				}
1353 			} else if (p->target_platform == SEPOL_TARGET_XEN) {
1354 				switch(i) {
1355 				case OCON_XEN_ISID:
1356 					if (octx->sid[0] == SEPOL_SECSID_NULL || octx->sid[0] >= XEN_SID_SZ)
1357 						goto bad;
1358 					break;
1359 				case OCON_XEN_IOPORT:
1360 					if (octx->u.ioport.low_ioport > octx->u.ioport.high_ioport)
1361 						goto bad;
1362 					break;
1363 				case OCON_XEN_IOMEM:
1364 					if (octx->u.iomem.low_iomem > octx->u.iomem.high_iomem)
1365 						goto bad;
1366 					if (p->policyvers < POLICYDB_VERSION_XEN_DEVICETREE && octx->u.iomem.high_iomem > 0xFFFFFFFFULL)
1367 						goto bad;
1368 					break;
1369 				case OCON_XEN_DEVICETREE:
1370 					if (!octx->u.name)
1371 						goto bad;
1372 					break;
1373 				}
1374 			}
1375 		}
1376 	}
1377 
1378 	return 0;
1379 
1380 bad:
1381 	ERR(handle, "Invalid ocontext");
1382 	return -1;
1383 }
1384 
validate_genfs(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1385 static int validate_genfs(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1386 {
1387 	const genfs_t *genfs;
1388 	const ocontext_t *octx;
1389 
1390 	for (genfs = p->genfs; genfs; genfs = genfs->next) {
1391 		for (octx = genfs->head; octx; octx = octx->next) {
1392 			if (validate_context(&octx->context[0], flavors, p->mls))
1393 				goto bad;
1394 			if (octx->v.sclass && validate_value(octx->v.sclass, &flavors[SYM_CLASSES]))
1395 				goto bad;
1396 		}
1397 
1398 		if (!genfs->fstype)
1399 			goto bad;
1400 	}
1401 
1402 	return 0;
1403 
1404 bad:
1405 	ERR(handle, "Invalid genfs");
1406 	return -1;
1407 }
1408 
1409 /*
1410  * Functions to validate a module policydb
1411  */
1412 
validate_role_trans_rules(sepol_handle_t * handle,const role_trans_rule_t * role_trans,validate_t flavors[])1413 static int validate_role_trans_rules(sepol_handle_t *handle, const role_trans_rule_t *role_trans, validate_t flavors[])
1414 {
1415 	for (; role_trans; role_trans = role_trans->next) {
1416 		if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES]))
1417 			goto bad;
1418 		if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES]))
1419 			goto bad;
1420 		if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES]))
1421 			goto bad;
1422 		if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
1423 			goto bad;
1424 	}
1425 
1426 	return 0;
1427 
1428 bad:
1429 	ERR(handle, "Invalid role trans rule");
1430 	return -1;
1431 }
1432 
validate_role_allow_rules(sepol_handle_t * handle,const role_allow_rule_t * role_allow,validate_t flavors[])1433 static int validate_role_allow_rules(sepol_handle_t *handle, const role_allow_rule_t *role_allow, validate_t flavors[])
1434 {
1435 	for (; role_allow; role_allow = role_allow->next) {
1436 		if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES]))
1437 			goto bad;
1438 		if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES]))
1439 			goto bad;
1440 	}
1441 
1442 	return 0;
1443 
1444 bad:
1445 	ERR(handle, "Invalid role allow rule");
1446 	return -1;
1447 }
1448 
validate_range_trans_rules(sepol_handle_t * handle,const range_trans_rule_t * range_trans,validate_t flavors[])1449 static int validate_range_trans_rules(sepol_handle_t *handle, const range_trans_rule_t *range_trans, validate_t flavors[])
1450 {
1451 	for (; range_trans; range_trans = range_trans->next) {
1452 		if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES]))
1453 			goto bad;
1454 		if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES]))
1455 			goto bad;
1456 		if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES]))
1457 			goto bad;
1458 		if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1459 			goto bad;
1460 	}
1461 
1462 	return 0;
1463 
1464 bad:
1465 	ERR(handle, "Invalid range trans rule");
1466 	return -1;
1467 }
1468 
validate_scope_index(sepol_handle_t * handle,const scope_index_t * scope_index,validate_t flavors[])1469 static int validate_scope_index(sepol_handle_t *handle, const scope_index_t *scope_index, validate_t flavors[])
1470 {
1471 	uint32_t i;
1472 
1473 	if (!ebitmap_is_empty(&scope_index->scope[SYM_COMMONS]))
1474 		goto bad;
1475 	if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES]))
1476 		goto bad;
1477 	if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES]))
1478 		goto bad;
1479 	if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES]))
1480 		goto bad;
1481 	if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS]))
1482 		goto bad;
1483 	if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS]))
1484 		goto bad;
1485 	if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS]))
1486 		goto bad;
1487 	if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS]))
1488 		goto bad;
1489 
1490 	for (i = 0; i < scope_index->class_perms_len; i++)
1491 		if (validate_value(i + 1, &flavors[SYM_CLASSES]))
1492 			goto bad;
1493 
1494 	return 0;
1495 
1496 bad:
1497 	ERR(handle, "Invalid scope");
1498 	return -1;
1499 }
1500 
1501 
validate_filename_trans_rules(sepol_handle_t * handle,const filename_trans_rule_t * filename_trans,const policydb_t * p,validate_t flavors[])1502 static int validate_filename_trans_rules(sepol_handle_t *handle, const filename_trans_rule_t *filename_trans, const policydb_t *p, validate_t flavors[])
1503 {
1504 	for (; filename_trans; filename_trans = filename_trans->next) {
1505 		if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES]))
1506 			goto bad;
1507 		if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES]))
1508 			goto bad;
1509 		if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] ))
1510 			goto bad;
1511 		if (validate_simpletype(filename_trans->otype, p, flavors))
1512 			goto bad;
1513 
1514 		/* currently only the RULE_SELF flag can be set */
1515 		switch (filename_trans->flags) {
1516 		case 0:
1517 			break;
1518 		case RULE_SELF:
1519 			if (p->policyvers != POLICY_KERN && p->policyvers < MOD_POLICYDB_VERSION_SELF_TYPETRANS)
1520 				goto bad;
1521 			break;
1522 		default:
1523 			goto bad;
1524 		}
1525 	}
1526 
1527 	return 0;
1528 
1529 bad:
1530 	ERR(handle, "Invalid filename trans rule list");
1531 	return -1;
1532 }
1533 
validate_symtabs(sepol_handle_t * handle,const symtab_t symtabs[],validate_t flavors[])1534 static int validate_symtabs(sepol_handle_t *handle, const symtab_t symtabs[], validate_t flavors[])
1535 {
1536 	unsigned int i;
1537 
1538 	for (i = 0; i < SYM_NUM; i++) {
1539 		if (hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) {
1540 			ERR(handle, "Invalid symtab");
1541 			return -1;
1542 		}
1543 	}
1544 
1545 	return 0;
1546 }
1547 
validate_avrule_blocks(sepol_handle_t * handle,const avrule_block_t * avrule_block,const policydb_t * p,validate_t flavors[])1548 static int validate_avrule_blocks(sepol_handle_t *handle, const avrule_block_t *avrule_block, const policydb_t *p, validate_t flavors[])
1549 {
1550 	const avrule_decl_t *decl;
1551 
1552 	for (; avrule_block; avrule_block = avrule_block->next) {
1553 		for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) {
1554 			if (validate_cond_list(handle, decl->cond_list, p, flavors))
1555 				goto bad;
1556 			if (validate_avrules(handle, decl->avrules, 0, p, flavors))
1557 				goto bad;
1558 			if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors))
1559 				goto bad;
1560 			if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors))
1561 				goto bad;
1562 			if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors))
1563 				goto bad;
1564 			if (validate_scope_index(handle, &decl->required, flavors))
1565 				goto bad;
1566 			if (validate_scope_index(handle, &decl->declared, flavors))
1567 				goto bad;
1568 			if (validate_filename_trans_rules(handle, decl->filename_trans_rules, p, flavors))
1569 				goto bad;
1570 			if (validate_symtabs(handle, decl->symtab, flavors))
1571 				goto bad;
1572 		}
1573 
1574 		switch (avrule_block->flags) {
1575 		case 0:
1576 		case AVRULE_OPTIONAL:
1577 			break;
1578 		default:
1579 			goto bad;
1580 		}
1581 	}
1582 
1583 	return 0;
1584 
1585 bad:
1586 	ERR(handle, "Invalid avrule block");
1587 	return -1;
1588 }
1589 
validate_permissives(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1590 static int validate_permissives(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1591 {
1592 	ebitmap_node_t *node;
1593 	uint32_t i;
1594 
1595 	ebitmap_for_each_positive_bit(&p->permissive_map, node, i) {
1596 		if (validate_simpletype(i, p, flavors))
1597 			goto bad;
1598 	}
1599 
1600 	return 0;
1601 
1602 bad:
1603 	ERR(handle, "Invalid permissive type");
1604 	return -1;
1605 }
1606 
validate_range_transition(hashtab_key_t key,hashtab_datum_t data,void * args)1607 static int validate_range_transition(hashtab_key_t key, hashtab_datum_t data, void *args)
1608 {
1609 	const range_trans_t *rt = (const range_trans_t *)key;
1610 	const mls_range_t *r = data;
1611 	const map_arg_t *margs = args;
1612 	const validate_t *flavors = margs->flavors;
1613 
1614 	if (validate_value(rt->source_type, &flavors[SYM_TYPES]))
1615 		goto bad;
1616 	if (validate_value(rt->target_type, &flavors[SYM_TYPES]))
1617 		goto bad;
1618 	if (validate_value(rt->target_class, &flavors[SYM_CLASSES]))
1619 		goto bad;
1620 
1621 	if (validate_mls_range(r, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1622 		goto bad;
1623 
1624 	return 0;
1625 
1626 bad:
1627 	return -1;
1628 }
1629 
validate_range_transitions(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1630 static int validate_range_transitions(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1631 {
1632 	map_arg_t margs = { flavors, handle, p };
1633 
1634 	if (hashtab_map(p->range_tr, validate_range_transition, &margs)) {
1635 		ERR(handle, "Invalid range transition");
1636 			return -1;
1637 	}
1638 
1639 	return 0;
1640 }
1641 
validate_typeattr_map(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1642 static int validate_typeattr_map(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1643 {
1644 	const ebitmap_t *maps = p->type_attr_map;
1645 	uint32_t i;
1646 
1647 	if (p->policy_type == POLICY_KERN) {
1648 		for (i = 0; i < p->p_types.nprim; i++) {
1649 			if (validate_ebitmap(&maps[i], &flavors[SYM_TYPES]))
1650 				goto bad;
1651 		}
1652 	} else if (maps)
1653 		goto bad;
1654 
1655 	return 0;
1656 
1657 bad:
1658 	ERR(handle, "Invalid type attr map");
1659 	return -1;
1660 }
1661 
validate_attrtype_map(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1662 static int validate_attrtype_map(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1663 {
1664 	const ebitmap_t *maps = p->attr_type_map;
1665 	uint32_t i;
1666 
1667 	if (p->policy_type == POLICY_KERN) {
1668 		for (i = 0; i < p->p_types.nprim; i++) {
1669 			if (validate_ebitmap(&maps[i], &flavors[SYM_TYPES]))
1670 				goto bad;
1671 		}
1672 	} else if (maps)
1673 		goto bad;
1674 
1675 	return 0;
1676 
1677 bad:
1678 	ERR(handle, "Invalid attr type map");
1679 	return -1;
1680 }
1681 
validate_properties(sepol_handle_t * handle,const policydb_t * p)1682 static int validate_properties(sepol_handle_t *handle, const policydb_t *p)
1683 {
1684 	switch (p->policy_type) {
1685 	case POLICY_KERN:
1686 		if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX)
1687 			goto bad;
1688 		if (p->mls && p->policyvers < POLICYDB_VERSION_MLS)
1689 			goto bad;
1690 		break;
1691 	case POLICY_BASE:
1692 	case POLICY_MOD:
1693 		if (p->policyvers < MOD_POLICYDB_VERSION_MIN || p->policyvers > MOD_POLICYDB_VERSION_MAX)
1694 			goto bad;
1695 		if (p->mls && p->policyvers < MOD_POLICYDB_VERSION_MLS)
1696 			goto bad;
1697 		break;
1698 	default:
1699 		goto bad;
1700 	}
1701 
1702 	switch (p->target_platform) {
1703 	case SEPOL_TARGET_SELINUX:
1704 	case SEPOL_TARGET_XEN:
1705 		break;
1706 	default:
1707 		goto bad;
1708 	}
1709 
1710 	switch (p->mls) {
1711 	case 0:
1712 	case 1:
1713 		break;
1714 	default:
1715 		goto bad;
1716 	}
1717 
1718 	switch (p->handle_unknown) {
1719 	case SEPOL_DENY_UNKNOWN:
1720 	case SEPOL_REJECT_UNKNOWN:
1721 	case SEPOL_ALLOW_UNKNOWN:
1722 		break;
1723 	default:
1724 		goto bad;
1725 	}
1726 
1727 	return 0;
1728 
1729 bad:
1730 	ERR(handle, "Invalid policy property");
1731 	return -1;
1732 }
1733 
validate_policycaps(sepol_handle_t * handle,const policydb_t * p)1734 static int validate_policycaps(sepol_handle_t *handle, const policydb_t *p)
1735 {
1736 	ebitmap_node_t *node;
1737 	uint32_t i;
1738 
1739 	ebitmap_for_each_positive_bit(&p->policycaps, node, i) {
1740 		if (!sepol_polcap_getname(i))
1741 			goto bad;
1742 	}
1743 
1744 	return 0;
1745 
1746 bad:
1747 	ERR(handle, "Invalid policy capability");
1748 	return -1;
1749 }
1750 
validate_array_destroy(validate_t flavors[])1751 static void validate_array_destroy(validate_t flavors[])
1752 {
1753 	unsigned int i;
1754 
1755 	for (i = 0; i < SYM_NUM; i++) {
1756 		ebitmap_destroy(&flavors[i].gaps);
1757 	}
1758 }
1759 
1760 /*
1761  * Validate policydb
1762  */
policydb_validate(sepol_handle_t * handle,const policydb_t * p)1763 int policydb_validate(sepol_handle_t *handle, const policydb_t *p)
1764 {
1765 	validate_t flavors[SYM_NUM] = {};
1766 
1767 	if (validate_array_init(p, flavors))
1768 		goto bad;
1769 
1770 	if (validate_properties(handle, p))
1771 		goto bad;
1772 
1773 	if (validate_policycaps(handle, p))
1774 		goto bad;
1775 
1776 	if (p->policy_type == POLICY_KERN) {
1777 		if (validate_avtab(handle, &p->te_avtab, p, flavors))
1778 			goto bad;
1779 		if (p->policyvers >= POLICYDB_VERSION_BOOL)
1780 			if (validate_cond_list(handle, p->cond_list, p, flavors))
1781 				goto bad;
1782 		if (validate_role_transes(handle, p->role_tr, flavors))
1783 			goto bad;
1784 		if (validate_role_allows(handle, p->role_allow, flavors))
1785 			goto bad;
1786 		if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS)
1787 			if (validate_filename_trans_hashtab(handle, p, flavors))
1788 				goto bad;
1789 	} else {
1790 		if (validate_avrule_blocks(handle, p->global, p, flavors))
1791 			goto bad;
1792 	}
1793 
1794 	if (validate_ocontexts(handle, p, flavors))
1795 		goto bad;
1796 
1797 	if (validate_genfs(handle, p, flavors))
1798 		goto bad;
1799 
1800 	if (validate_scopes(handle, p->scope, p->global))
1801 		goto bad;
1802 
1803 	if (validate_datum_array_gaps(handle, p, flavors))
1804 		goto bad;
1805 
1806 	if (validate_datum_array_entries(handle, p, flavors))
1807 		goto bad;
1808 
1809 	if (validate_permissives(handle, p, flavors))
1810 		goto bad;
1811 
1812 	if (validate_range_transitions(handle, p, flavors))
1813 		goto bad;
1814 
1815 	if (validate_typeattr_map(handle, p, flavors))
1816 		goto bad;
1817 
1818 	if (validate_attrtype_map(handle, p, flavors))
1819 		goto bad;
1820 
1821 	validate_array_destroy(flavors);
1822 
1823 	return 0;
1824 
1825 bad:
1826 	ERR(handle, "Invalid policydb");
1827 	validate_array_destroy(flavors);
1828 	return -1;
1829 }
1830