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