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