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