• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	attr->keep = CIL_FALSE;
190 }
191 
cil_reset_typeattributeset(struct cil_typeattributeset * tas)192 static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
193 {
194 	cil_list_destroy(&tas->datum_expr, CIL_FALSE);
195 }
196 
cil_reset_avrule(struct cil_avrule * rule)197 static void cil_reset_avrule(struct cil_avrule *rule)
198 {
199 	cil_reset_classperms_list(rule->perms.classperms);
200 }
201 
cil_reset_rangetransition(struct cil_rangetransition * rangetrans)202 static void cil_reset_rangetransition(struct cil_rangetransition *rangetrans)
203 {
204 	if (rangetrans->range_str == NULL) {
205 		cil_reset_levelrange(rangetrans->range);
206 	}
207 }
208 
cil_reset_sens(struct cil_sens * sens)209 static void cil_reset_sens(struct cil_sens *sens)
210 {
211 	/* during a re-resolve, we need to reset the categories associated with
212 	 * this sensitivity from a (sensitivitycategory) statement */
213 	cil_list_destroy(&sens->cats_list, CIL_FALSE);
214 	sens->ordered = CIL_FALSE;
215 }
216 
cil_reset_cat(struct cil_cat * cat)217 static void cil_reset_cat(struct cil_cat *cat)
218 {
219 	cat->ordered = CIL_FALSE;
220 }
221 
cil_reset_cats(struct cil_cats * cats)222 static inline void cil_reset_cats(struct cil_cats *cats)
223 {
224 	if (cats != NULL) {
225 		cats->evaluated = CIL_FALSE;
226 		cil_list_destroy(&cats->datum_expr, CIL_FALSE);
227 	}
228 }
229 
230 
cil_reset_senscat(struct cil_senscat * senscat)231 static void cil_reset_senscat(struct cil_senscat *senscat)
232 {
233 	cil_reset_cats(senscat->cats);
234 }
235 
cil_reset_catset(struct cil_catset * catset)236 static void cil_reset_catset(struct cil_catset *catset)
237 {
238 	cil_reset_cats(catset->cats);
239 }
240 
cil_reset_level(struct cil_level * level)241 static inline void cil_reset_level(struct cil_level *level)
242 {
243 	cil_reset_cats(level->cats);
244 }
245 
cil_reset_levelrange(struct cil_levelrange * levelrange)246 static inline void cil_reset_levelrange(struct cil_levelrange *levelrange)
247 {
248 	if (levelrange->low_str == NULL) {
249 		cil_reset_level(levelrange->low);
250 	}
251 
252 	if (levelrange->high_str == NULL) {
253 		cil_reset_level(levelrange->high);
254 	}
255 }
256 
cil_reset_userlevel(struct cil_userlevel * userlevel)257 static inline void cil_reset_userlevel(struct cil_userlevel *userlevel)
258 {
259 	if (userlevel->level_str == NULL) {
260 		cil_reset_level(userlevel->level);
261 	}
262 }
263 
cil_reset_userrange(struct cil_userrange * userrange)264 static inline void cil_reset_userrange(struct cil_userrange *userrange)
265 {
266 	if (userrange->range_str == NULL) {
267 		cil_reset_levelrange(userrange->range);
268 	}
269 }
270 
cil_reset_context(struct cil_context * context)271 static inline void cil_reset_context(struct cil_context *context)
272 {
273 	if (context->range_str == NULL) {
274 		cil_reset_levelrange(context->range);
275 	}
276 }
277 
cil_reset_sidcontext(struct cil_sidcontext * sidcontext)278 static void cil_reset_sidcontext(struct cil_sidcontext *sidcontext)
279 {
280 	if (sidcontext->context_str == NULL) {
281 		cil_reset_context(sidcontext->context);
282 	}
283 }
284 
cil_reset_filecon(struct cil_filecon * filecon)285 static void cil_reset_filecon(struct cil_filecon *filecon)
286 {
287 	if (filecon->context_str == NULL && filecon->context != NULL) {
288 		cil_reset_context(filecon->context);
289 	}
290 }
291 
cil_reset_ibpkeycon(struct cil_ibpkeycon * ibpkeycon)292 static void cil_reset_ibpkeycon(struct cil_ibpkeycon *ibpkeycon)
293 {
294 	if (!ibpkeycon->context_str)
295 		cil_reset_context(ibpkeycon->context);
296 }
297 
cil_reset_portcon(struct cil_portcon * portcon)298 static void cil_reset_portcon(struct cil_portcon *portcon)
299 {
300 	if (portcon->context_str == NULL) {
301 		cil_reset_context(portcon->context);
302 	}
303 }
304 
cil_reset_nodecon(struct cil_nodecon * nodecon)305 static void cil_reset_nodecon(struct cil_nodecon *nodecon)
306 {
307 	if (nodecon->context_str == NULL) {
308 		cil_reset_context(nodecon->context);
309 	}
310 }
311 
cil_reset_genfscon(struct cil_genfscon * genfscon)312 static void cil_reset_genfscon(struct cil_genfscon *genfscon)
313 {
314 	if (genfscon->context_str == NULL) {
315 		cil_reset_context(genfscon->context);
316 	}
317 }
318 
cil_reset_netifcon(struct cil_netifcon * netifcon)319 static void cil_reset_netifcon(struct cil_netifcon *netifcon)
320 {
321 	if (netifcon->if_context_str == NULL) {
322 		cil_reset_context(netifcon->if_context);
323 	}
324 
325 	if (netifcon->packet_context_str == NULL) {
326 		cil_reset_context(netifcon->packet_context);
327 	}
328 }
329 
cil_reset_ibendportcon(struct cil_ibendportcon * ibendportcon)330 static void cil_reset_ibendportcon(struct cil_ibendportcon *ibendportcon)
331 {
332 	if (!ibendportcon->context_str) {
333 		cil_reset_context(ibendportcon->context);
334 	}
335 }
336 
cil_reset_pirqcon(struct cil_pirqcon * pirqcon)337 static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon)
338 {
339 	if (pirqcon->context_str == NULL) {
340 		cil_reset_context(pirqcon->context);
341 	}
342 }
343 
cil_reset_iomemcon(struct cil_iomemcon * iomemcon)344 static void cil_reset_iomemcon(struct cil_iomemcon *iomemcon)
345 {
346 	if (iomemcon->context_str == NULL) {
347 		cil_reset_context(iomemcon->context);
348 	}
349 }
350 
cil_reset_ioportcon(struct cil_ioportcon * ioportcon)351 static void cil_reset_ioportcon(struct cil_ioportcon *ioportcon)
352 {
353 	if (ioportcon->context_str == NULL) {
354 		cil_reset_context(ioportcon->context);
355 	}
356 }
357 
cil_reset_pcidevicecon(struct cil_pcidevicecon * pcidevicecon)358 static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
359 {
360 	if (pcidevicecon->context_str == NULL) {
361 		cil_reset_context(pcidevicecon->context);
362 	}
363 }
364 
cil_reset_devicetreecon(struct cil_devicetreecon * devicetreecon)365 static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon)
366 {
367 	if (devicetreecon->context_str == NULL) {
368 		cil_reset_context(devicetreecon->context);
369 	}
370 }
371 
cil_reset_fsuse(struct cil_fsuse * fsuse)372 static void cil_reset_fsuse(struct cil_fsuse *fsuse)
373 {
374 	if (fsuse->context_str == NULL) {
375 		cil_reset_context(fsuse->context);
376 	}
377 }
378 
cil_reset_sid(struct cil_sid * sid)379 static void cil_reset_sid(struct cil_sid *sid)
380 {
381 	/* reset the context to NULL during a re-resolve */
382 	sid->context = NULL;
383 	sid->ordered = CIL_FALSE;
384 }
385 
cil_reset_constrain(struct cil_constrain * con)386 static void cil_reset_constrain(struct cil_constrain *con)
387 {
388 	cil_reset_classperms_list(con->classperms);
389 	cil_list_destroy(&con->datum_expr, CIL_FALSE);
390 }
391 
cil_reset_validatetrans(struct cil_validatetrans * vt)392 static void cil_reset_validatetrans(struct cil_validatetrans *vt)
393 {
394 	cil_list_destroy(&vt->datum_expr, CIL_FALSE);
395 }
396 
cil_reset_default(struct cil_default * def)397 static void cil_reset_default(struct cil_default *def)
398 {
399 	cil_list_destroy(&def->class_datums, CIL_FALSE);
400 }
401 
cil_reset_defaultrange(struct cil_defaultrange * def)402 static void cil_reset_defaultrange(struct cil_defaultrange *def)
403 {
404 	cil_list_destroy(&def->class_datums, CIL_FALSE);
405 }
406 
cil_reset_booleanif(struct cil_booleanif * bif)407 static void cil_reset_booleanif(struct cil_booleanif *bif)
408 {
409 	cil_list_destroy(&bif->datum_expr, CIL_FALSE);
410 }
411 
__cil_reset_node(struct cil_tree_node * node,uint32_t * finished,void * extra_args)412 int __cil_reset_node(struct cil_tree_node *node,  __attribute__((unused)) uint32_t *finished, __attribute__((unused)) void *extra_args)
413 {
414 	switch (node->flavor) {
415 	case CIL_CLASS:
416 		cil_reset_class(node->data);
417 		break;
418 	case CIL_PERM:
419 	case CIL_MAP_PERM:
420 		cil_reset_perm(node->data);
421 		break;
422 	case CIL_CLASSPERMISSION:
423 		cil_reset_classpermission(node->data);
424 		break;
425 	case CIL_CLASSPERMISSIONSET:
426 		cil_reset_classpermissionset(node->data);
427 		break;
428 	case CIL_CLASSMAPPING:
429 		cil_reset_classmapping(node->data);
430 		break;
431 	case CIL_TYPEALIAS:
432 	case CIL_SENSALIAS:
433 	case CIL_CATALIAS:
434 		cil_reset_alias(node->data);
435 		break;
436 	case CIL_USERRANGE:
437 		cil_reset_userrange(node->data);
438 		break;
439 	case CIL_USERLEVEL:
440 		cil_reset_userlevel(node->data);
441 		break;
442 	case CIL_USER:
443 		cil_reset_user(node->data);
444 		break;
445 	case CIL_USERATTRIBUTE:
446 		cil_reset_userattr(node->data);
447 		break;
448 	case CIL_USERATTRIBUTESET:
449 		cil_reset_userattributeset(node->data);
450 		break;
451 	case CIL_SELINUXUSERDEFAULT:
452 	case CIL_SELINUXUSER:
453 		cil_reset_selinuxuser(node->data);
454 		break;
455 	case CIL_ROLE:
456 		cil_reset_role(node->data);
457 		break;
458 	case CIL_ROLEATTRIBUTE:
459 		cil_reset_roleattr(node->data);
460 		break;
461 	case CIL_ROLEATTRIBUTESET:
462 		cil_reset_roleattributeset(node->data);
463 		break;
464 	case CIL_TYPE:
465 		cil_reset_type(node->data);
466 		break;
467 	case CIL_TYPEATTRIBUTE:
468 		cil_reset_typeattr(node->data);
469 		break;
470 	case CIL_TYPEATTRIBUTESET:
471 		cil_reset_typeattributeset(node->data);
472 		break;
473 	case CIL_RANGETRANSITION:
474 		cil_reset_rangetransition(node->data);
475 		break;
476 	case CIL_AVRULE:
477 		cil_reset_avrule(node->data);
478 		break;
479 	case CIL_SENS:
480 		cil_reset_sens(node->data);
481 		break;
482 	case CIL_CAT:
483 		cil_reset_cat(node->data);
484 		break;
485 	case CIL_SENSCAT:
486 		cil_reset_senscat(node->data);
487 		break;
488 	case CIL_CATSET:
489 		cil_reset_catset(node->data);
490 		break;
491 	case CIL_LEVEL:
492 		cil_reset_level(node->data);
493 		break;
494 	case CIL_LEVELRANGE:
495 		cil_reset_levelrange(node->data);
496 		break;
497 	case CIL_CONTEXT:
498 		cil_reset_context(node->data);
499 		break;
500 	case CIL_SIDCONTEXT:
501 		cil_reset_sidcontext(node->data);
502 		break;
503 	case CIL_FILECON:
504 		cil_reset_filecon(node->data);
505 		break;
506 	case CIL_IBPKEYCON:
507 		cil_reset_ibpkeycon(node->data);
508 		break;
509 	case CIL_IBENDPORTCON:
510 		cil_reset_ibendportcon(node->data);
511 		break;
512 	case CIL_PORTCON:
513 		cil_reset_portcon(node->data);
514 		break;
515 	case CIL_NODECON:
516 		cil_reset_nodecon(node->data);
517 		break;
518 	case CIL_GENFSCON:
519 		cil_reset_genfscon(node->data);
520 		break;
521 	case CIL_NETIFCON:
522 		cil_reset_netifcon(node->data);
523 		break;
524 	case CIL_PIRQCON:
525 		cil_reset_pirqcon(node->data);
526 		break;
527 	case CIL_IOMEMCON:
528 		cil_reset_iomemcon(node->data);
529 		break;
530 	case CIL_IOPORTCON:
531 		cil_reset_ioportcon(node->data);
532 		break;
533 	case CIL_PCIDEVICECON:
534 		cil_reset_pcidevicecon(node->data);
535 		break;
536 	case CIL_DEVICETREECON:
537 		cil_reset_devicetreecon(node->data);
538 		break;
539 	case CIL_FSUSE:
540 		cil_reset_fsuse(node->data);
541 		break;
542 	case CIL_SID:
543 		cil_reset_sid(node->data);
544 		break;
545 	case CIL_CONSTRAIN:
546 	case CIL_MLSCONSTRAIN:
547 		cil_reset_constrain(node->data);
548 		break;
549 	case CIL_VALIDATETRANS:
550 	case CIL_MLSVALIDATETRANS:
551 		cil_reset_validatetrans(node->data);
552 		break;
553 	case CIL_DEFAULTUSER:
554 	case CIL_DEFAULTROLE:
555 	case CIL_DEFAULTTYPE:
556 		cil_reset_default(node->data);
557 		break;
558 	case CIL_DEFAULTRANGE:
559 		cil_reset_defaultrange(node->data);
560 		break;
561 	case CIL_BOOLEANIF:
562 		cil_reset_booleanif(node->data);
563 		break;
564 	case CIL_TUNABLEIF:
565 	case CIL_CALL:
566 		break; /* Not effected by optional block disabling */
567 	case CIL_MACRO:
568 	case CIL_SIDORDER:
569 	case CIL_CLASSORDER:
570 	case CIL_CATORDER:
571 	case CIL_SENSITIVITYORDER:
572 	case CIL_EXPANDTYPEATTRIBUTE:
573 		break; /* Nothing to reset */
574 	default:
575 		break;
576 	}
577 
578 	return SEPOL_OK;
579 }
580 
cil_reset_ast(struct cil_tree_node * current)581 int cil_reset_ast(struct cil_tree_node *current)
582 {
583 	int rc = SEPOL_ERR;
584 
585 	rc = cil_tree_walk(current, __cil_reset_node, NULL, NULL, NULL);
586 	if (rc != SEPOL_OK) {
587 		cil_log(CIL_ERR, "Failed to reset AST\n");
588 		return SEPOL_ERR;
589 	}
590 
591 	return SEPOL_OK;
592 }
593