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