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