1
2 #include "cil_internal.h"
3 #include "cil_log.h"
4 #include "cil_list.h"
5 #include "cil_reset_ast.h"
6 #include "cil_symtab.h"
7
8 static inline void cil_reset_classperms_list(struct cil_list *cp_list);
9 static inline void cil_reset_level(struct cil_level *level);
10 static inline void cil_reset_levelrange(struct cil_levelrange *levelrange);
11 static inline void cil_reset_context(struct cil_context *context);
12
13
cil_reset_ordered(struct cil_ordered * ordered)14 static void cil_reset_ordered(struct cil_ordered *ordered)
15 {
16 ordered->merged = CIL_FALSE;
17 cil_list_destroy(&ordered->datums, CIL_FALSE);
18 }
19
__class_reset_perm_values(hashtab_key_t k,hashtab_datum_t d,void * args)20 static int __class_reset_perm_values(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
21 {
22 struct cil_perm *perm = (struct cil_perm *)d;
23
24 perm->value -= *((int *)args);
25
26 return SEPOL_OK;
27 }
28
cil_reset_class(struct cil_class * class)29 static void cil_reset_class(struct cil_class *class)
30 {
31 if (class->common != NULL) {
32 /* Must assume that the common has been destroyed */
33 int num_common_perms = class->num_perms - class->perms.nprim;
34 cil_symtab_map(&class->perms, __class_reset_perm_values, &num_common_perms);
35 /* during a re-resolve, we need to reset the common, so a classcommon
36 * statement isn't seen as a duplicate */
37 class->num_perms = class->perms.nprim;
38 class->common = NULL; /* Must make this NULL or there will be an error when re-resolving */
39 }
40 class->ordered = CIL_FALSE;
41 }
42
cil_reset_perm(struct cil_perm * perm)43 static void cil_reset_perm(struct cil_perm *perm)
44 {
45 cil_list_destroy(&perm->classperms, CIL_FALSE);
46 }
47
cil_reset_classperms(struct cil_classperms * cp)48 static inline void cil_reset_classperms(struct cil_classperms *cp)
49 {
50 if (cp == NULL) {
51 return;
52 }
53
54 cp->class = NULL;
55 cil_list_destroy(&cp->perms, CIL_FALSE);
56 }
57
cil_reset_classpermission(struct cil_classpermission * cp)58 static void cil_reset_classpermission(struct cil_classpermission *cp)
59 {
60 if (cp == NULL) {
61 return;
62 }
63
64 cil_list_destroy(&cp->classperms, CIL_FALSE);
65 }
66
cil_reset_classperms_set(struct cil_classperms_set * cp_set)67 static void cil_reset_classperms_set(struct cil_classperms_set *cp_set)
68 {
69 if (cp_set == NULL || cp_set->set == NULL) {
70 return;
71 }
72
73 if (cp_set->set->datum.name == NULL) {
74 cil_reset_classperms_list(cp_set->set->classperms);
75 }
76
77 cp_set->set = NULL;
78 }
79
cil_reset_classperms_list(struct cil_list * cp_list)80 static inline void cil_reset_classperms_list(struct cil_list *cp_list)
81 {
82 struct cil_list_item *curr;
83
84 if (cp_list == NULL) {
85 return;
86 }
87
88 cil_list_for_each(curr, cp_list) {
89 if (curr->flavor == CIL_CLASSPERMS) { /* KERNEL or MAP */
90 cil_reset_classperms(curr->data);
91 } else if (curr->flavor == CIL_CLASSPERMS_SET) { /* SET */
92 cil_reset_classperms_set(curr->data);
93 }
94 }
95 }
96
cil_reset_classpermissionset(struct cil_classpermissionset * cps)97 static void cil_reset_classpermissionset(struct cil_classpermissionset *cps)
98 {
99 cil_reset_classperms_list(cps->classperms);
100 }
101
cil_reset_classmapping(struct cil_classmapping * cm)102 static void cil_reset_classmapping(struct cil_classmapping *cm)
103 {
104 cil_reset_classperms_list(cm->classperms);
105 }
106
cil_reset_alias(struct cil_alias * alias)107 static void cil_reset_alias(struct cil_alias *alias)
108 {
109 /* reset actual to NULL during a re-resolve */
110 alias->actual = NULL;
111 }
112
cil_reset_user(struct cil_user * user)113 static void cil_reset_user(struct cil_user *user)
114 {
115 /* reset the bounds to NULL during a re-resolve */
116 user->bounds = NULL;
117 user->dftlevel = NULL;
118 user->range = NULL;
119 }
120
cil_reset_userattr(struct cil_userattribute * attr)121 static void cil_reset_userattr(struct cil_userattribute *attr)
122 {
123 struct cil_list_item *expr = NULL;
124 struct cil_list_item *next = NULL;
125
126 /* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a userattribute statement */
127 if (attr->expr_list != NULL) {
128 /* we don't want to destroy the expression stacks (cil_list) inside
129 * this list cil_list_destroy destroys sublists, so we need to do it
130 * manually */
131 expr = attr->expr_list->head;
132 while (expr != NULL) {
133 next = expr->next;
134 cil_list_item_destroy(&expr, CIL_FALSE);
135 expr = next;
136 }
137 free(attr->expr_list);
138 attr->expr_list = NULL;
139 }
140 }
141
cil_reset_userattributeset(struct cil_userattributeset * uas)142 static void cil_reset_userattributeset(struct cil_userattributeset *uas)
143 {
144 cil_list_destroy(&uas->datum_expr, CIL_FALSE);
145 }
146
cil_reset_selinuxuser(struct cil_selinuxuser * selinuxuser)147 static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser)
148 {
149 selinuxuser->user = NULL;
150 if (selinuxuser->range_str == NULL) {
151 cil_reset_levelrange(selinuxuser->range);
152 } else {
153 selinuxuser->range = NULL;
154 }
155 }
156
cil_reset_role(struct cil_role * role)157 static void cil_reset_role(struct cil_role *role)
158 {
159 /* reset the bounds to NULL during a re-resolve */
160 role->bounds = NULL;
161 }
162
cil_reset_roleattr(struct cil_roleattribute * attr)163 static void cil_reset_roleattr(struct cil_roleattribute *attr)
164 {
165 /* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a attributeroles statement */
166 if (attr->expr_list != NULL) {
167 /* we don't want to destroy the expression stacks (cil_list) inside
168 * this list cil_list_destroy destroys sublists, so we need to do it
169 * manually */
170 struct cil_list_item *expr = attr->expr_list->head;
171 while (expr != NULL) {
172 struct cil_list_item *next = expr->next;
173 cil_list_item_destroy(&expr, CIL_FALSE);
174 expr = next;
175 }
176 free(attr->expr_list);
177 attr->expr_list = NULL;
178 }
179 }
180
cil_reset_roleattributeset(struct cil_roleattributeset * ras)181 static void cil_reset_roleattributeset(struct cil_roleattributeset *ras)
182 {
183 cil_list_destroy(&ras->datum_expr, CIL_FALSE);
184 }
185
cil_reset_type(struct cil_type * type)186 static void cil_reset_type(struct cil_type *type)
187 {
188 /* reset the bounds to NULL during a re-resolve */
189 type->bounds = NULL;
190 }
191
cil_reset_typeattr(struct cil_typeattribute * attr)192 static void cil_reset_typeattr(struct cil_typeattribute *attr)
193 {
194 /* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a attributetypes statement */
195 if (attr->expr_list != NULL) {
196 /* we don't want to destroy the expression stacks (cil_list) inside
197 * this list cil_list_destroy destroys sublists, so we need to do it
198 * manually */
199 struct cil_list_item *expr = attr->expr_list->head;
200 while (expr != NULL) {
201 struct cil_list_item *next = expr->next;
202 cil_list_item_destroy(&expr, CIL_FALSE);
203 expr = next;
204 }
205 free(attr->expr_list);
206 attr->expr_list = NULL;
207 }
208 attr->used = CIL_FALSE;
209 attr->keep = CIL_FALSE;
210 }
211
cil_reset_typeattributeset(struct cil_typeattributeset * tas)212 static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
213 {
214 cil_list_destroy(&tas->datum_expr, CIL_FALSE);
215 }
216
cil_reset_expandtypeattribute(struct cil_expandtypeattribute * expandattr)217 static void cil_reset_expandtypeattribute(struct cil_expandtypeattribute *expandattr)
218 {
219 cil_list_destroy(&expandattr->attr_datums, CIL_FALSE);
220 }
221
cil_reset_avrule(struct cil_avrule * rule)222 static void cil_reset_avrule(struct cil_avrule *rule)
223 {
224 cil_reset_classperms_list(rule->perms.classperms);
225 }
226
cil_reset_deny_rule(struct cil_deny_rule * rule)227 static void cil_reset_deny_rule(struct cil_deny_rule *rule)
228 {
229 cil_reset_classperms_list(rule->classperms);
230 }
231
cil_reset_rangetransition(struct cil_rangetransition * rangetrans)232 static void cil_reset_rangetransition(struct cil_rangetransition *rangetrans)
233 {
234 if (rangetrans->range_str == NULL) {
235 cil_reset_levelrange(rangetrans->range);
236 } else {
237 rangetrans->range = NULL;
238 }
239 }
240
cil_reset_sens(struct cil_sens * sens)241 static void cil_reset_sens(struct cil_sens *sens)
242 {
243 /* during a re-resolve, we need to reset the categories associated with
244 * this sensitivity from a (sensitivitycategory) statement */
245 cil_list_destroy(&sens->cats_list, CIL_FALSE);
246 sens->ordered = CIL_FALSE;
247 }
248
cil_reset_cat(struct cil_cat * cat)249 static void cil_reset_cat(struct cil_cat *cat)
250 {
251 cat->ordered = CIL_FALSE;
252 }
253
cil_reset_cats(struct cil_cats * cats)254 static inline void cil_reset_cats(struct cil_cats *cats)
255 {
256 if (cats != NULL) {
257 cats->evaluated = CIL_FALSE;
258 cil_list_destroy(&cats->datum_expr, CIL_FALSE);
259 }
260 }
261
262
cil_reset_senscat(struct cil_senscat * senscat)263 static void cil_reset_senscat(struct cil_senscat *senscat)
264 {
265 cil_reset_cats(senscat->cats);
266 }
267
cil_reset_catset(struct cil_catset * catset)268 static void cil_reset_catset(struct cil_catset *catset)
269 {
270 cil_reset_cats(catset->cats);
271 }
272
cil_reset_level(struct cil_level * level)273 static inline void cil_reset_level(struct cil_level *level)
274 {
275 level->sens = NULL;
276 cil_reset_cats(level->cats);
277 }
278
cil_reset_levelrange(struct cil_levelrange * levelrange)279 static inline void cil_reset_levelrange(struct cil_levelrange *levelrange)
280 {
281 if (levelrange->low_str == NULL) {
282 cil_reset_level(levelrange->low);
283 } else {
284 levelrange->low = NULL;
285 }
286
287 if (levelrange->high_str == NULL) {
288 cil_reset_level(levelrange->high);
289 } else {
290 levelrange->high = NULL;
291 }
292 }
293
cil_reset_userlevel(struct cil_userlevel * userlevel)294 static inline void cil_reset_userlevel(struct cil_userlevel *userlevel)
295 {
296 if (userlevel->level_str == NULL) {
297 cil_reset_level(userlevel->level);
298 } else {
299 userlevel->level = NULL;
300 }
301 }
302
cil_reset_userrange(struct cil_userrange * userrange)303 static inline void cil_reset_userrange(struct cil_userrange *userrange)
304 {
305 if (userrange->range_str == NULL) {
306 cil_reset_levelrange(userrange->range);
307 } else {
308 userrange->range = NULL;
309 }
310 }
311
cil_reset_context(struct cil_context * context)312 static inline void cil_reset_context(struct cil_context *context)
313 {
314 if (!context) {
315 return;
316 }
317 if (context->range_str == NULL) {
318 cil_reset_levelrange(context->range);
319 } else {
320 context->range = NULL;
321 }
322 }
323
cil_reset_sidcontext(struct cil_sidcontext * sidcontext)324 static void cil_reset_sidcontext(struct cil_sidcontext *sidcontext)
325 {
326 if (sidcontext->context_str == NULL) {
327 cil_reset_context(sidcontext->context);
328 } else {
329 sidcontext->context = NULL;
330 }
331 }
332
cil_reset_filecon(struct cil_filecon * filecon)333 static void cil_reset_filecon(struct cil_filecon *filecon)
334 {
335 if (filecon->context_str == NULL) {
336 cil_reset_context(filecon->context);
337 } else {
338 filecon->context = NULL;
339 }
340 }
341
cil_reset_ibpkeycon(struct cil_ibpkeycon * ibpkeycon)342 static void cil_reset_ibpkeycon(struct cil_ibpkeycon *ibpkeycon)
343 {
344 if (ibpkeycon->context_str == NULL) {
345 cil_reset_context(ibpkeycon->context);
346 } else {
347 ibpkeycon->context = NULL;
348 }
349 }
350
cil_reset_portcon(struct cil_portcon * portcon)351 static void cil_reset_portcon(struct cil_portcon *portcon)
352 {
353 if (portcon->context_str == NULL) {
354 cil_reset_context(portcon->context);
355 } else {
356 portcon->context = NULL;
357 }
358 }
359
cil_reset_nodecon(struct cil_nodecon * nodecon)360 static void cil_reset_nodecon(struct cil_nodecon *nodecon)
361 {
362 if (nodecon->context_str == NULL) {
363 cil_reset_context(nodecon->context);
364 } else {
365 nodecon->context = NULL;
366 }
367 }
368
cil_reset_genfscon(struct cil_genfscon * genfscon)369 static void cil_reset_genfscon(struct cil_genfscon *genfscon)
370 {
371 if (genfscon->context_str == NULL) {
372 cil_reset_context(genfscon->context);
373 } else {
374 genfscon->context = NULL;
375 }
376 }
377
cil_reset_netifcon(struct cil_netifcon * netifcon)378 static void cil_reset_netifcon(struct cil_netifcon *netifcon)
379 {
380 if (netifcon->if_context_str == NULL) {
381 cil_reset_context(netifcon->if_context);
382 } else {
383 netifcon->if_context = NULL;
384 }
385
386 if (netifcon->packet_context_str == NULL) {
387 cil_reset_context(netifcon->packet_context);
388 } else {
389 netifcon->packet_context = NULL;
390 }
391 }
392
cil_reset_ibendportcon(struct cil_ibendportcon * ibendportcon)393 static void cil_reset_ibendportcon(struct cil_ibendportcon *ibendportcon)
394 {
395 if (ibendportcon->context_str == NULL) {
396 cil_reset_context(ibendportcon->context);
397 } else {
398 ibendportcon->context = NULL;
399 }
400 }
401
cil_reset_pirqcon(struct cil_pirqcon * pirqcon)402 static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon)
403 {
404 if (pirqcon->context_str == NULL) {
405 cil_reset_context(pirqcon->context);
406 } else {
407 pirqcon->context = NULL;
408 }
409 }
410
cil_reset_iomemcon(struct cil_iomemcon * iomemcon)411 static void cil_reset_iomemcon(struct cil_iomemcon *iomemcon)
412 {
413 if (iomemcon->context_str == NULL) {
414 cil_reset_context(iomemcon->context);
415 } else {
416 iomemcon->context = NULL;
417 }
418 }
419
cil_reset_ioportcon(struct cil_ioportcon * ioportcon)420 static void cil_reset_ioportcon(struct cil_ioportcon *ioportcon)
421 {
422 if (ioportcon->context_str == NULL) {
423 cil_reset_context(ioportcon->context);
424 } else {
425 ioportcon->context = NULL;
426 }
427 }
428
cil_reset_pcidevicecon(struct cil_pcidevicecon * pcidevicecon)429 static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
430 {
431 if (pcidevicecon->context_str == NULL) {
432 cil_reset_context(pcidevicecon->context);
433 } else {
434 pcidevicecon->context = NULL;
435 }
436 }
437
cil_reset_devicetreecon(struct cil_devicetreecon * devicetreecon)438 static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon)
439 {
440 if (devicetreecon->context_str == NULL) {
441 cil_reset_context(devicetreecon->context);
442 } else {
443 devicetreecon->context = NULL;
444 }
445 }
446
cil_reset_fsuse(struct cil_fsuse * fsuse)447 static void cil_reset_fsuse(struct cil_fsuse *fsuse)
448 {
449 if (fsuse->context_str == NULL) {
450 cil_reset_context(fsuse->context);
451 } else {
452 fsuse->context = NULL;
453 }
454 }
455
cil_reset_sid(struct cil_sid * sid)456 static void cil_reset_sid(struct cil_sid *sid)
457 {
458 /* reset the context to NULL during a re-resolve */
459 sid->context = NULL;
460 sid->ordered = CIL_FALSE;
461 }
462
cil_reset_constrain(struct cil_constrain * con)463 static void cil_reset_constrain(struct cil_constrain *con)
464 {
465 cil_reset_classperms_list(con->classperms);
466 cil_list_destroy(&con->datum_expr, CIL_FALSE);
467 }
468
cil_reset_validatetrans(struct cil_validatetrans * vt)469 static void cil_reset_validatetrans(struct cil_validatetrans *vt)
470 {
471 cil_list_destroy(&vt->datum_expr, CIL_FALSE);
472 }
473
cil_reset_default(struct cil_default * def)474 static void cil_reset_default(struct cil_default *def)
475 {
476 cil_list_destroy(&def->class_datums, CIL_FALSE);
477 }
478
cil_reset_defaultrange(struct cil_defaultrange * def)479 static void cil_reset_defaultrange(struct cil_defaultrange *def)
480 {
481 cil_list_destroy(&def->class_datums, CIL_FALSE);
482 }
483
cil_reset_booleanif(struct cil_booleanif * bif)484 static void cil_reset_booleanif(struct cil_booleanif *bif)
485 {
486 cil_list_destroy(&bif->datum_expr, CIL_FALSE);
487 }
488
__cil_reset_node(struct cil_tree_node * node,uint32_t * finished,void * extra_args)489 static int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, __attribute__((unused)) void *extra_args)
490 {
491 switch (node->flavor) {
492 case CIL_CLASS:
493 cil_reset_class(node->data);
494 break;
495 case CIL_PERM:
496 case CIL_MAP_PERM:
497 cil_reset_perm(node->data);
498 break;
499 case CIL_CLASSPERMISSION:
500 cil_reset_classpermission(node->data);
501 break;
502 case CIL_CLASSPERMISSIONSET:
503 cil_reset_classpermissionset(node->data);
504 break;
505 case CIL_CLASSMAPPING:
506 cil_reset_classmapping(node->data);
507 break;
508 case CIL_TYPEALIAS:
509 case CIL_SENSALIAS:
510 case CIL_CATALIAS:
511 cil_reset_alias(node->data);
512 break;
513 case CIL_USERRANGE:
514 cil_reset_userrange(node->data);
515 break;
516 case CIL_USERLEVEL:
517 cil_reset_userlevel(node->data);
518 break;
519 case CIL_USER:
520 cil_reset_user(node->data);
521 break;
522 case CIL_USERATTRIBUTE:
523 cil_reset_userattr(node->data);
524 break;
525 case CIL_USERATTRIBUTESET:
526 cil_reset_userattributeset(node->data);
527 break;
528 case CIL_SELINUXUSERDEFAULT:
529 case CIL_SELINUXUSER:
530 cil_reset_selinuxuser(node->data);
531 break;
532 case CIL_ROLE:
533 cil_reset_role(node->data);
534 break;
535 case CIL_ROLEATTRIBUTE:
536 cil_reset_roleattr(node->data);
537 break;
538 case CIL_ROLEATTRIBUTESET:
539 cil_reset_roleattributeset(node->data);
540 break;
541 case CIL_TYPE:
542 cil_reset_type(node->data);
543 break;
544 case CIL_TYPEATTRIBUTE:
545 cil_reset_typeattr(node->data);
546 break;
547 case CIL_TYPEATTRIBUTESET:
548 cil_reset_typeattributeset(node->data);
549 break;
550 case CIL_EXPANDTYPEATTRIBUTE:
551 cil_reset_expandtypeattribute(node->data);
552 break;
553 case CIL_RANGETRANSITION:
554 cil_reset_rangetransition(node->data);
555 break;
556 case CIL_AVRULE:
557 cil_reset_avrule(node->data);
558 break;
559 case CIL_DENY_RULE:
560 cil_reset_deny_rule(node->data);
561 break;
562 case CIL_SENS:
563 cil_reset_sens(node->data);
564 break;
565 case CIL_CAT:
566 cil_reset_cat(node->data);
567 break;
568 case CIL_SENSCAT:
569 cil_reset_senscat(node->data);
570 break;
571 case CIL_CATSET:
572 cil_reset_catset(node->data);
573 break;
574 case CIL_LEVEL:
575 cil_reset_level(node->data);
576 break;
577 case CIL_LEVELRANGE:
578 cil_reset_levelrange(node->data);
579 break;
580 case CIL_CONTEXT:
581 cil_reset_context(node->data);
582 break;
583 case CIL_SIDCONTEXT:
584 cil_reset_sidcontext(node->data);
585 break;
586 case CIL_FILECON:
587 cil_reset_filecon(node->data);
588 break;
589 case CIL_IBPKEYCON:
590 cil_reset_ibpkeycon(node->data);
591 break;
592 case CIL_IBENDPORTCON:
593 cil_reset_ibendportcon(node->data);
594 break;
595 case CIL_PORTCON:
596 cil_reset_portcon(node->data);
597 break;
598 case CIL_NODECON:
599 cil_reset_nodecon(node->data);
600 break;
601 case CIL_GENFSCON:
602 cil_reset_genfscon(node->data);
603 break;
604 case CIL_NETIFCON:
605 cil_reset_netifcon(node->data);
606 break;
607 case CIL_PIRQCON:
608 cil_reset_pirqcon(node->data);
609 break;
610 case CIL_IOMEMCON:
611 cil_reset_iomemcon(node->data);
612 break;
613 case CIL_IOPORTCON:
614 cil_reset_ioportcon(node->data);
615 break;
616 case CIL_PCIDEVICECON:
617 cil_reset_pcidevicecon(node->data);
618 break;
619 case CIL_DEVICETREECON:
620 cil_reset_devicetreecon(node->data);
621 break;
622 case CIL_FSUSE:
623 cil_reset_fsuse(node->data);
624 break;
625 case CIL_SID:
626 cil_reset_sid(node->data);
627 break;
628 case CIL_CONSTRAIN:
629 case CIL_MLSCONSTRAIN:
630 cil_reset_constrain(node->data);
631 break;
632 case CIL_VALIDATETRANS:
633 case CIL_MLSVALIDATETRANS:
634 cil_reset_validatetrans(node->data);
635 break;
636 case CIL_DEFAULTUSER:
637 case CIL_DEFAULTROLE:
638 case CIL_DEFAULTTYPE:
639 cil_reset_default(node->data);
640 break;
641 case CIL_DEFAULTRANGE:
642 cil_reset_defaultrange(node->data);
643 break;
644 case CIL_BOOLEANIF:
645 cil_reset_booleanif(node->data);
646 break;
647 case CIL_SIDORDER:
648 case CIL_CLASSORDER:
649 case CIL_CATORDER:
650 case CIL_SENSITIVITYORDER:
651 cil_reset_ordered(node->data);
652 break;
653 case CIL_TUNABLEIF:
654 case CIL_CALL:
655 break; /* Not effected by optional block disabling */
656 case CIL_MACRO:
657 break; /* Nothing to reset */
658 default:
659 break;
660 }
661
662 return SEPOL_OK;
663 }
664
cil_reset_ast(struct cil_tree_node * current)665 int cil_reset_ast(struct cil_tree_node *current)
666 {
667 int rc = SEPOL_ERR;
668
669 rc = cil_tree_walk(current, __cil_reset_node, NULL, NULL, NULL);
670 if (rc != SEPOL_OK) {
671 cil_log(CIL_ERR, "Failed to reset AST\n");
672 return SEPOL_ERR;
673 }
674
675 return SEPOL_OK;
676 }
677