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