• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include <sepol/policydb/conditional.h>
3 #include <sepol/policydb/ebitmap.h>
4 #include <sepol/policydb/policydb.h>
5 
6 #include "debug.h"
7 #include "policydb_validate.h"
8 
9 typedef struct validate {
10 	uint32_t nprim;
11 	ebitmap_t gaps;
12 } validate_t;
13 
14 
create_gap_ebitmap(char ** val_to_name,uint32_t nprim,ebitmap_t * gaps)15 static int create_gap_ebitmap(char **val_to_name, uint32_t nprim, ebitmap_t *gaps)
16 {
17 	unsigned int i;
18 
19 	ebitmap_init(gaps);
20 
21 	for (i = 0; i < nprim; i++) {
22 		if (!val_to_name[i]) {
23 			if (ebitmap_set_bit(gaps, i, 1))
24 				return -1;
25 		}
26 	}
27 
28 	return 0;
29 }
30 
validate_init(validate_t * flavor,char ** val_to_name,uint32_t nprim)31 static int validate_init(validate_t *flavor, char **val_to_name, uint32_t nprim)
32 {
33 	flavor->nprim = nprim;
34 	if (create_gap_ebitmap(val_to_name, nprim, &flavor->gaps))
35 		return -1;
36 
37 	return 0;
38 }
39 
validate_array_init(policydb_t * p,validate_t flavors[])40 static int validate_array_init(policydb_t *p, validate_t flavors[])
41 {
42 	if (validate_init(&flavors[SYM_CLASSES], p->p_class_val_to_name, p->p_classes.nprim))
43 		goto bad;
44 	if (validate_init(&flavors[SYM_ROLES], p->p_role_val_to_name, p->p_roles.nprim))
45 		goto bad;
46 	if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) {
47 		if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, p->p_types.nprim))
48 			goto bad;
49 	} else {
50 		/*
51 		 * For policy versions between 20 and 23, attributes exist in the policy,
52 		 * but they only exist in the type_attr_map, so there will be references
53 		 * to gaps and we just have to treat this case as if there were no gaps.
54 		 */
55 		flavors[SYM_TYPES].nprim = p->p_types.nprim;
56 		ebitmap_init(&flavors[SYM_TYPES].gaps);
57 	}
58 	if (validate_init(&flavors[SYM_USERS], p->p_user_val_to_name, p->p_users.nprim))
59 		goto bad;
60 	if (validate_init(&flavors[SYM_BOOLS], p->p_bool_val_to_name, p->p_bools.nprim))
61 		goto bad;
62 	if (validate_init(&flavors[SYM_LEVELS], p->p_sens_val_to_name, p->p_levels.nprim))
63 		goto bad;
64 	if (validate_init(&flavors[SYM_CATS], p->p_cat_val_to_name, p->p_cats.nprim))
65 		goto bad;
66 
67 	return 0;
68 
69 bad:
70 	return -1;
71 }
72 
73 /*
74  * Functions to validate both kernel and module policydbs
75  */
76 
value_isvalid(uint32_t value,uint32_t nprim)77 int value_isvalid(uint32_t value, uint32_t nprim)
78 {
79 	if (!value || value > nprim)
80 		return 0;
81 
82 	return 1;
83 }
84 
validate_value(uint32_t value,validate_t * flavor)85 static int validate_value(uint32_t value, validate_t *flavor)
86 {
87 	if (!value || value > flavor->nprim)
88 		goto bad;
89 	if (ebitmap_get_bit(&flavor->gaps, value-1))
90 		goto bad;
91 
92 	return 0;
93 
94 bad:
95 	return -1;
96 }
97 
validate_ebitmap(ebitmap_t * map,validate_t * flavor)98 static int validate_ebitmap(ebitmap_t *map, validate_t *flavor)
99 {
100 	if (ebitmap_length(map) > 0 && ebitmap_highest_set_bit(map) >= flavor->nprim)
101 		goto bad;
102 	if (ebitmap_match_any(map, &flavor->gaps))
103 		goto bad;
104 
105 	return 0;
106 
107 bad:
108 	return -1;
109 }
110 
validate_type_set(type_set_t * type_set,validate_t * type)111 static int validate_type_set(type_set_t *type_set, validate_t *type)
112 {
113 	if (validate_ebitmap(&type_set->types, type))
114 		goto bad;
115 	if (validate_ebitmap(&type_set->negset, type))
116 		goto bad;
117 
118 	return 0;
119 
120 bad:
121 	return -1;
122 }
123 
validate_role_set(role_set_t * role_set,validate_t * role)124 static int validate_role_set(role_set_t *role_set, validate_t *role)
125 {
126 	if (validate_ebitmap(&role_set->roles, role))
127 		return -1;
128 
129 	return 0;
130 }
131 
validate_scope(hashtab_key_t k,hashtab_datum_t d,void * args)132 static int validate_scope(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
133 {
134 	scope_datum_t *scope_datum = (scope_datum_t *)d;
135 	uint32_t *nprim = (uint32_t *)args;
136 	unsigned int i;
137 
138 	for (i = 0; i < scope_datum->decl_ids_len; i++) {
139 		if (!value_isvalid(scope_datum->decl_ids[i], *nprim))
140 			return -1;
141 	}
142 
143 	return 0;
144 }
145 
validate_scopes(sepol_handle_t * handle,symtab_t scopes[],avrule_block_t * block)146 static int validate_scopes(sepol_handle_t *handle, symtab_t scopes[], avrule_block_t *block)
147 {
148 	avrule_decl_t *decl;
149 	unsigned int i;
150 	unsigned int num_decls = 0;
151 
152 	for (; block != NULL; block = block->next) {
153 		for (decl = block->branch_list; decl; decl = decl->next) {
154 			num_decls++;
155 		}
156 	}
157 
158 	for (i = 0; i < SYM_NUM; i++) {
159 		if (hashtab_map(scopes[i].table, validate_scope, &num_decls))
160 			goto bad;
161 	}
162 
163 	return 0;
164 
165 bad:
166 	ERR(handle, "Invalid scope");
167 	return -1;
168 }
169 
validate_constraint_nodes(sepol_handle_t * handle,constraint_node_t * cons,validate_t flavors[])170 static int validate_constraint_nodes(sepol_handle_t *handle, constraint_node_t *cons, validate_t flavors[])
171 {
172 	constraint_expr_t *cexp;
173 
174 	for (; cons; cons = cons->next) {
175 		for (cexp = cons->expr; cexp; cexp = cexp->next) {
176 			if (cexp->attr & CEXPR_USER) {
177 				if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS]))
178 					goto bad;
179 			} else if (cexp->attr & CEXPR_ROLE) {
180 				if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES]))
181 					goto bad;
182 			} else if (cexp->attr & CEXPR_TYPE) {
183 				if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES]))
184 					goto bad;
185 				if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES]))
186 					goto bad;
187 			}
188 		}
189 	}
190 
191 	return 0;
192 
193 bad:
194 	ERR(handle, "Invalid constraint expr");
195 	return -1;
196 }
197 
validate_class_datum(sepol_handle_t * handle,class_datum_t * class,validate_t flavors[])198 static int validate_class_datum(sepol_handle_t *handle, class_datum_t *class, validate_t flavors[])
199 {
200 	if (validate_value(class->s.value, &flavors[SYM_CLASSES]))
201 		goto bad;
202 	if (validate_constraint_nodes(handle, class->constraints, flavors))
203 		goto bad;
204 	if (validate_constraint_nodes(handle, class->validatetrans, flavors))
205 		goto bad;
206 
207 	return 0;
208 
209 bad:
210 	ERR(handle, "Invalid class datum");
211 	return -1;
212 }
213 
validate_role_datum(sepol_handle_t * handle,role_datum_t * role,validate_t flavors[])214 static int validate_role_datum(sepol_handle_t *handle, role_datum_t *role, validate_t flavors[])
215 {
216 	if (validate_value(role->s.value, &flavors[SYM_ROLES]))
217 		goto bad;
218 	if (validate_ebitmap(&role->dominates, &flavors[SYM_ROLES]))
219 		goto bad;
220 	if (validate_type_set(&role->types, &flavors[SYM_TYPES]))
221 		goto bad;
222 	if (role->bounds && validate_value(role->bounds, &flavors[SYM_ROLES]))
223 		goto bad;
224 	if (validate_ebitmap(&role->roles, &flavors[SYM_ROLES]))
225 		goto bad;
226 
227 	return 0;
228 
229 bad:
230 	ERR(handle, "Invalid class datum");
231 	return -1;
232 }
233 
validate_type_datum(sepol_handle_t * handle,type_datum_t * type,validate_t flavors[])234 static int validate_type_datum(sepol_handle_t *handle, type_datum_t *type, validate_t flavors[])
235 {
236 	if (validate_value(type->s.value, &flavors[SYM_TYPES]))
237 		goto bad;
238 	if (validate_ebitmap(&type->types, &flavors[SYM_TYPES]))
239 		goto bad;
240 	if (type->bounds && validate_value(type->bounds, &flavors[SYM_TYPES]))
241 		goto bad;
242 
243 	return 0;
244 
245 bad:
246 	ERR(handle, "Invalid type datum");
247 	return -1;
248 }
249 
validate_mls_semantic_cat(mls_semantic_cat_t * cat,validate_t * cats)250 static int validate_mls_semantic_cat(mls_semantic_cat_t *cat, validate_t *cats)
251 {
252 	for (; cat; cat = cat->next) {
253 		if (validate_value(cat->low, cats))
254 			goto bad;
255 		if (validate_value(cat->high, cats))
256 			goto bad;
257 	}
258 
259 	return 0;
260 
261 bad:
262 	return -1;
263 }
264 
validate_mls_semantic_level(mls_semantic_level_t * level,validate_t * sens,validate_t * cats)265 static int validate_mls_semantic_level(mls_semantic_level_t *level, validate_t *sens, validate_t *cats)
266 {
267 	if (level->sens == 0)
268 		return 0;
269 	if (validate_value(level->sens, sens))
270 		goto bad;
271 	if (validate_mls_semantic_cat(level->cat, cats))
272 		goto bad;
273 
274 	return 0;
275 
276 bad:
277 	return -1;
278 }
279 
validate_mls_semantic_range(mls_semantic_range_t * range,validate_t * sens,validate_t * cats)280 static int validate_mls_semantic_range(mls_semantic_range_t *range, validate_t *sens, validate_t *cats)
281 {
282 	if (validate_mls_semantic_level(&range->level[0], sens, cats))
283 		goto bad;
284 	if (validate_mls_semantic_level(&range->level[1], sens, cats))
285 		goto bad;
286 
287 	return 0;
288 
289 bad:
290 	return -1;
291 }
292 
validate_user_datum(sepol_handle_t * handle,user_datum_t * user,validate_t flavors[])293 static int validate_user_datum(sepol_handle_t *handle, user_datum_t *user, validate_t flavors[])
294 {
295 	if (validate_value(user->s.value, &flavors[SYM_USERS]))
296 		goto bad;
297 	if (validate_role_set(&user->roles, &flavors[SYM_ROLES]))
298 		goto bad;
299 	if (validate_mls_semantic_range(&user->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
300 		goto bad;
301 	if (validate_mls_semantic_level(&user->dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
302 		goto bad;
303 	if (user->bounds && validate_value(user->bounds, &flavors[SYM_USERS]))
304 		goto bad;
305 
306 	return 0;
307 
308 bad:
309 	ERR(handle, "Invalid user datum");
310 	return -1;
311 }
312 
validate_datum_arrays(sepol_handle_t * handle,policydb_t * p,validate_t flavors[])313 static int validate_datum_arrays(sepol_handle_t *handle, policydb_t *p, validate_t flavors[])
314 {
315 	unsigned int i;
316 
317 	for (i = 0; i < p->p_classes.nprim; i++) {
318 		if (p->class_val_to_struct[i]) {
319 			if (ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i))
320 				goto bad;
321 			if (validate_class_datum(handle, p->class_val_to_struct[i], flavors))
322 				goto bad;
323 		} else {
324 			if (!ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i))
325 				goto bad;
326 		}
327 	}
328 
329 	for (i = 0; i < p->p_roles.nprim; i++) {
330 		if (p->role_val_to_struct[i]) {
331 			if (ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i))
332 				goto bad;
333 			if (validate_role_datum(handle, p->role_val_to_struct[i], flavors))
334 				goto bad;
335 		} else {
336 			if (!ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i))
337 				goto bad;
338 		}
339 	}
340 
341 	/*
342 	 * For policy versions between 20 and 23, attributes exist in the policy,
343 	 * but only in the type_attr_map, so all gaps must be assumed to be valid.
344 	 */
345 	if (p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) {
346 		for (i = 0; i < p->p_types.nprim; i++) {
347 			if (p->type_val_to_struct[i]) {
348 				if (ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i))
349 					goto bad;
350 				if (validate_type_datum(handle, p->type_val_to_struct[i], flavors))
351 					goto bad;
352 			} else {
353 				if (!ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i))
354 					goto bad;
355 			}
356 		}
357 	}
358 
359 	for (i = 0; i < p->p_users.nprim; i++) {
360 		if (p->user_val_to_struct[i]) {
361 			if (ebitmap_get_bit(&flavors[SYM_USERS].gaps, i))
362 				goto bad;
363 			if (validate_user_datum(handle, p->user_val_to_struct[i], flavors))
364 				goto bad;
365 		} else {
366 			if (!ebitmap_get_bit(&flavors[SYM_USERS].gaps, i))
367 				goto bad;
368 		}
369 	}
370 
371 	return 0;
372 
373 bad:
374 	ERR(handle, "Invalid datum arrays");
375 	return -1;
376 }
377 
378 /*
379  * Functions to validate a kernel policydb
380  */
381 
validate_avtab_key(avtab_key_t * key,validate_t flavors[])382 static int validate_avtab_key(avtab_key_t *key, validate_t flavors[])
383 {
384 	if (validate_value(key->source_type, &flavors[SYM_TYPES]))
385 		goto bad;
386 	if (validate_value(key->target_type, &flavors[SYM_TYPES]))
387 		goto bad;
388 	if (validate_value(key->target_class, &flavors[SYM_CLASSES]))
389 		goto bad;
390 
391 	return 0;
392 
393 bad:
394 	return -1;
395 }
396 
validate_avtab_key_wrapper(avtab_key_t * k,avtab_datum_t * d,void * args)397 static int validate_avtab_key_wrapper(avtab_key_t *k,  __attribute__ ((unused)) avtab_datum_t *d, void *args)
398 {
399 	validate_t *flavors = (validate_t *)args;
400 	return validate_avtab_key(k, flavors);
401 }
402 
validate_avtab(sepol_handle_t * handle,avtab_t * avtab,validate_t flavors[])403 static int validate_avtab(sepol_handle_t *handle, avtab_t *avtab, validate_t flavors[])
404 {
405 	if (avtab_map(avtab, validate_avtab_key_wrapper, flavors)) {
406 		ERR(handle, "Invalid avtab");
407 		return -1;
408 	}
409 
410 	return 0;
411 }
412 
validate_cond_av_list(sepol_handle_t * handle,cond_av_list_t * cond_av,validate_t flavors[])413 static int validate_cond_av_list(sepol_handle_t *handle, cond_av_list_t *cond_av, validate_t flavors[])
414 {
415 	avtab_ptr_t avtab_ptr;
416 
417 	for (; cond_av; cond_av = cond_av->next) {
418 		for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) {
419 			if (validate_avtab_key(&avtab_ptr->key, flavors)) {
420 				ERR(handle, "Invalid cond av list");
421 				return -1;
422 			}
423 		}
424 	}
425 
426 	return 0;
427 }
428 
validate_avrules(sepol_handle_t * handle,avrule_t * avrule,validate_t flavors[])429 static int validate_avrules(sepol_handle_t *handle, avrule_t *avrule, validate_t flavors[])
430 {
431 	class_perm_node_t *class;
432 
433 	for (; avrule; avrule = avrule->next) {
434 		if (validate_type_set(&avrule->stypes, &flavors[SYM_TYPES]))
435 			goto bad;
436 		if (validate_type_set(&avrule->ttypes, &flavors[SYM_TYPES]))
437 			goto bad;
438 		class = avrule->perms;
439 		for (; class; class = class->next) {
440 			if (validate_value(class->tclass, &flavors[SYM_CLASSES]))
441 				goto bad;
442 		}
443 	}
444 
445 	return 0;
446 
447 bad:
448 	ERR(handle, "Invalid avrule");
449 	return -1;
450 }
451 
validate_bool_id_array(sepol_handle_t * handle,uint32_t bool_ids[],unsigned int nbools,validate_t * bool)452 static int validate_bool_id_array(sepol_handle_t *handle, uint32_t bool_ids[], unsigned int nbools, validate_t *bool)
453 {
454 	unsigned int i;
455 
456 	if (nbools >= COND_MAX_BOOLS)
457 		goto bad;
458 
459 	for (i=0; i < nbools; i++) {
460 		if (validate_value(bool_ids[i], bool))
461 			goto bad;
462 	}
463 
464 	return 0;
465 
466 bad:
467 	ERR(handle, "Invalid bool id array");
468 	return -1;
469 }
470 
validate_cond_list(sepol_handle_t * handle,cond_list_t * cond,validate_t flavors[])471 static int validate_cond_list(sepol_handle_t *handle, cond_list_t *cond, validate_t flavors[])
472 {
473 	for (; cond; cond = cond->next) {
474 		if (validate_cond_av_list(handle, cond->true_list, flavors))
475 			goto bad;
476 		if (validate_cond_av_list(handle, cond->false_list, flavors))
477 			goto bad;
478 		if (validate_avrules(handle, cond->avtrue_list, flavors))
479 			goto bad;
480 		if (validate_avrules(handle, cond->avfalse_list, flavors))
481 			goto bad;
482 		if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS]))
483 			goto bad;
484 	}
485 
486 	return 0;
487 
488 bad:
489 	ERR(handle, "Invalid cond list");
490 	return -1;
491 }
492 
validate_role_transes(sepol_handle_t * handle,role_trans_t * role_trans,validate_t flavors[])493 static int validate_role_transes(sepol_handle_t *handle, role_trans_t *role_trans, validate_t flavors[])
494 {
495 	for (; role_trans; role_trans = role_trans->next) {
496 		if (validate_value(role_trans->role, &flavors[SYM_ROLES]))
497 			goto bad;
498 		if (validate_value(role_trans->type, &flavors[SYM_TYPES]))
499 			goto bad;
500 		if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES]))
501 			goto bad;
502 		if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
503 			goto bad;
504 	}
505 
506 	return 0;
507 
508 bad:
509 	ERR(handle, "Invalid role trans");
510 	return -1;
511 }
512 
validate_role_allows(sepol_handle_t * handle,role_allow_t * role_allow,validate_t flavors[])513 static int validate_role_allows(sepol_handle_t *handle, role_allow_t *role_allow, validate_t flavors[])
514 {
515 	for (; role_allow; role_allow = role_allow->next) {
516 		if (validate_value(role_allow->role, &flavors[SYM_ROLES]))
517 			goto bad;
518 		if (validate_value(role_allow->new_role, &flavors[SYM_ROLES]))
519 			goto bad;
520 	}
521 
522 	return 0;
523 
524 bad:
525 	ERR(handle, "Invalid role allow");
526 	return -1;
527 }
528 
validate_filename_trans(hashtab_key_t k,hashtab_datum_t d,void * args)529 static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args)
530 {
531 	filename_trans_key_t *ftk = (filename_trans_key_t *)k;
532 	filename_trans_datum_t *ftd = d;
533 	validate_t *flavors = (validate_t *)args;
534 
535 	if (validate_value(ftk->ttype, &flavors[SYM_TYPES]))
536 		goto bad;
537 	if (validate_value(ftk->tclass, &flavors[SYM_CLASSES]))
538 		goto bad;
539 	for (; ftd; ftd = ftd->next) {
540 		if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES]))
541 			goto bad;
542 		if (validate_value(ftd->otype, &flavors[SYM_TYPES]))
543 			goto bad;
544 	}
545 
546 	return 0;
547 
548 bad:
549 	return -1;
550 }
551 
validate_filename_trans_hashtab(sepol_handle_t * handle,hashtab_t filename_trans,validate_t flavors[])552 static int validate_filename_trans_hashtab(sepol_handle_t *handle, hashtab_t filename_trans, validate_t flavors[])
553 {
554 	if (hashtab_map(filename_trans, validate_filename_trans, flavors)) {
555 		ERR(handle, "Invalid filename trans");
556 		return -1;
557 	}
558 
559 	return 0;
560 }
561 
562 /*
563  * Functions to validate a module policydb
564  */
565 
validate_role_trans_rules(sepol_handle_t * handle,role_trans_rule_t * role_trans,validate_t flavors[])566 static int validate_role_trans_rules(sepol_handle_t *handle, role_trans_rule_t *role_trans, validate_t flavors[])
567 {
568 	for (; role_trans; role_trans = role_trans->next) {
569 		if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES]))
570 			goto bad;
571 		if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES]))
572 			goto bad;
573 		if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES]))
574 			goto bad;
575 		if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
576 			goto bad;
577 	}
578 
579 	return 0;
580 
581 bad:
582 	ERR(handle, "Invalid role trans rule");
583 	return -1;
584 }
585 
validate_role_allow_rules(sepol_handle_t * handle,role_allow_rule_t * role_allow,validate_t flavors[])586 static int validate_role_allow_rules(sepol_handle_t *handle, role_allow_rule_t *role_allow, validate_t flavors[])
587 {
588 	for (; role_allow; role_allow = role_allow->next) {
589 		if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES]))
590 			goto bad;
591 		if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES]))
592 			goto bad;
593 	}
594 
595 	return 0;
596 
597 bad:
598 	ERR(handle, "Invalid role allow rule");
599 	return -1;
600 }
601 
validate_range_trans_rules(sepol_handle_t * handle,range_trans_rule_t * range_trans,validate_t flavors[])602 static int validate_range_trans_rules(sepol_handle_t *handle, range_trans_rule_t *range_trans, validate_t flavors[])
603 {
604 	for (; range_trans; range_trans = range_trans->next) {
605 		if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES]))
606 			goto bad;
607 		if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES]))
608 			goto bad;
609 		if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES]))
610 			goto bad;
611 		if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
612 			goto bad;
613 	}
614 
615 	return 0;
616 
617 bad:
618 	ERR(handle, "Invalid range trans rule");
619 	return -1;
620 }
621 
validate_scope_index(sepol_handle_t * handle,scope_index_t * scope_index,validate_t flavors[])622 static int validate_scope_index(sepol_handle_t *handle, scope_index_t *scope_index, validate_t flavors[])
623 {
624 	if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES]))
625 		goto bad;
626 	if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES]))
627 		goto bad;
628 	if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES]))
629 		goto bad;
630 	if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS]))
631 		goto bad;
632 	if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS]))
633 		goto bad;
634 	if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS]))
635 		goto bad;
636 	if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS]))
637 		goto bad;
638 	if (scope_index->class_perms_len > flavors[SYM_CLASSES].nprim)
639 		goto bad;
640 
641 	return 0;
642 
643 bad:
644 	ERR(handle, "Invalid scope");
645 	return -1;
646 }
647 
648 
validate_filename_trans_rules(sepol_handle_t * handle,filename_trans_rule_t * filename_trans,validate_t flavors[])649 static int validate_filename_trans_rules(sepol_handle_t *handle, filename_trans_rule_t *filename_trans, validate_t flavors[])
650 {
651 	for (; filename_trans; filename_trans = filename_trans->next) {
652 		if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES]))
653 			goto bad;
654 		if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES]))
655 			goto bad;
656 		if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] ))
657 			goto bad;
658 		if (validate_value(filename_trans->otype, &flavors[SYM_TYPES]))
659 			goto bad;
660 	}
661 
662 	return 0;
663 
664 bad:
665 	ERR(handle, "Invalid filename trans rule list");
666 	return -1;
667 }
668 
validate_datum(hashtab_key_t k,hashtab_datum_t d,void * args)669 static int validate_datum(__attribute__ ((unused))hashtab_key_t k, hashtab_datum_t d, void *args)
670 {
671 	symtab_datum_t *s = d;
672 	uint32_t *nprim = (uint32_t *)args;
673 
674 	return !value_isvalid(s->value, *nprim);
675 }
676 
validate_symtabs(sepol_handle_t * handle,symtab_t symtabs[],validate_t flavors[])677 static int validate_symtabs(sepol_handle_t *handle, symtab_t symtabs[], validate_t flavors[])
678 {
679 	unsigned int i;
680 
681 	for (i = 0; i < SYM_NUM; i++) {
682 		if (hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) {
683 			ERR(handle, "Invalid symtab");
684 			return -1;
685 		}
686 	}
687 
688 	return 0;
689 }
690 
validate_avrule_blocks(sepol_handle_t * handle,avrule_block_t * avrule_block,validate_t flavors[])691 static int validate_avrule_blocks(sepol_handle_t *handle, avrule_block_t *avrule_block, validate_t flavors[])
692 {
693 	avrule_decl_t *decl;
694 
695 	for (; avrule_block; avrule_block = avrule_block->next) {
696 		for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) {
697 			if (validate_cond_list(handle, decl->cond_list, flavors))
698 				goto bad;
699 			if (validate_avrules(handle, decl->avrules, flavors))
700 				goto bad;
701 			if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors))
702 				goto bad;
703 			if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors))
704 				goto bad;
705 			if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors))
706 				goto bad;
707 			if (validate_scope_index(handle, &decl->required, flavors))
708 				goto bad;
709 			if (validate_scope_index(handle, &decl->declared, flavors))
710 				goto bad;
711 			if (validate_filename_trans_rules(handle, decl->filename_trans_rules, flavors))
712 				goto bad;
713 			if (validate_symtabs(handle, decl->symtab, flavors))
714 				goto bad;
715 		}
716 	}
717 
718 	return 0;
719 
720 bad:
721 	ERR(handle, "Invalid avrule block");
722 	return -1;
723 }
724 
validate_array_destroy(validate_t flavors[])725 static void validate_array_destroy(validate_t flavors[])
726 {
727 	unsigned int i;
728 
729 	for (i = 0; i < SYM_NUM; i++) {
730 		ebitmap_destroy(&flavors[i].gaps);
731 	}
732 }
733 
734 /*
735  * Validate policydb
736  */
validate_policydb(sepol_handle_t * handle,policydb_t * p)737 int validate_policydb(sepol_handle_t *handle, policydb_t *p)
738 {
739 	validate_t flavors[SYM_NUM] = {};
740 
741 	if (validate_array_init(p, flavors))
742 		goto bad;
743 
744 	if (p->policy_type == POLICY_KERN) {
745 		if (validate_avtab(handle, &p->te_avtab, flavors))
746 			goto bad;
747 		if (p->policyvers >= POLICYDB_VERSION_BOOL)
748 			if (validate_cond_list(handle, p->cond_list, flavors))
749 				goto bad;
750 		if (validate_role_transes(handle, p->role_tr, flavors))
751 			goto bad;
752 		if (validate_role_allows(handle, p->role_allow, flavors))
753 			goto bad;
754 		if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS)
755 			if (validate_filename_trans_hashtab(handle, p->filename_trans, flavors))
756 				goto bad;
757 	} else {
758 		if (validate_avrule_blocks(handle, p->global, flavors))
759 			goto bad;
760 	}
761 
762 	if (validate_scopes(handle, p->scope, p->global))
763 		goto bad;
764 
765 	if (validate_datum_arrays(handle, p, flavors))
766 		goto bad;
767 
768 	validate_array_destroy(flavors);
769 
770 	return 0;
771 
772 bad:
773 	ERR(handle, "Invalid policydb");
774 	validate_array_destroy(flavors);
775 	return -1;
776 }
777