Home | History | Annotate | Download | only in src
      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 
     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 
     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 
     35 static void cil_reset_perm(struct cil_perm *perm)
     36 {
     37 	cil_reset_classperms_list(perm->classperms);
     38 }
     39 
     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 
     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 
     58 static void cil_reset_classperms_set(struct cil_classperms_set *cp_set)
     59 {
     60 	cil_reset_classpermission(cp_set->set);
     61 }
     62 
     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 
     80 static void cil_reset_classpermissionset(struct cil_classpermissionset *cps)
     81 {
     82 	cil_reset_classperms_list(cps->classperms);
     83 }
     84 
     85 static void cil_reset_classmapping(struct cil_classmapping *cm)
     86 {
     87 	cil_reset_classperms_list(cm->classperms);
     88 }
     89 
     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 
     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 
    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 
    125 static void cil_reset_userattributeset(struct cil_userattributeset *uas)
    126 {
    127 	cil_list_destroy(&uas->datum_expr, CIL_FALSE);
    128 }
    129 
    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 
    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 
    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 
    161 static void cil_reset_roleattributeset(struct cil_roleattributeset *ras)
    162 {
    163 	cil_list_destroy(&ras->datum_expr, CIL_FALSE);
    164 }
    165 
    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 
    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 
    192 static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
    193 {
    194 	cil_list_destroy(&tas->datum_expr, CIL_FALSE);
    195 }
    196 
    197 static void cil_reset_avrule(struct cil_avrule *rule)
    198 {
    199 	cil_reset_classperms_list(rule->perms.classperms);
    200 }
    201 
    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 
    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 
    217 static void cil_reset_cat(struct cil_cat *cat)
    218 {
    219 	cat->ordered = CIL_FALSE;
    220 }
    221 
    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 
    231 static void cil_reset_senscat(struct cil_senscat *senscat)
    232 {
    233 	cil_reset_cats(senscat->cats);
    234 }
    235 
    236 static void cil_reset_catset(struct cil_catset *catset)
    237 {
    238 	cil_reset_cats(catset->cats);
    239 }
    240 
    241 static inline void cil_reset_level(struct cil_level *level)
    242 {
    243 	cil_reset_cats(level->cats);
    244 }
    245 
    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 
    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 
    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 
    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 
    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 
    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 
    292 static void cil_reset_ibpkeycon(struct cil_ibpkeycon *ibpkeycon)
    293 {
    294 	if (!ibpkeycon->context_str)
    295 		cil_reset_context(ibpkeycon->context);
    296 }
    297 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    392 static void cil_reset_validatetrans(struct cil_validatetrans *vt)
    393 {
    394 	cil_list_destroy(&vt->datum_expr, CIL_FALSE);
    395 }
    396 
    397 static void cil_reset_default(struct cil_default *def)
    398 {
    399 	cil_list_destroy(&def->class_datums, CIL_FALSE);
    400 }
    401 
    402 static void cil_reset_defaultrange(struct cil_defaultrange *def)
    403 {
    404 	cil_list_destroy(&def->class_datums, CIL_FALSE);
    405 }
    406 
    407 static void cil_reset_booleanif(struct cil_booleanif *bif)
    408 {
    409 	cil_list_destroy(&bif->datum_expr, CIL_FALSE);
    410 }
    411 
    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 
    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