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(&common->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 }
    190 
    191 static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
    192 {
    193 	cil_list_destroy(&tas->datum_expr, CIL_FALSE);
    194 }
    195 
    196 static void cil_reset_avrule(struct cil_avrule *rule)
    197 {
    198 	cil_reset_classperms_list(rule->perms.classperms);
    199 }
    200 
    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 
    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 
    216 static void cil_reset_cat(struct cil_cat *cat)
    217 {
    218 	cat->ordered = CIL_FALSE;
    219 }
    220 
    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 
    230 static void cil_reset_senscat(struct cil_senscat *senscat)
    231 {
    232 	cil_reset_cats(senscat->cats);
    233 }
    234 
    235 static void cil_reset_catset(struct cil_catset *catset)
    236 {
    237 	cil_reset_cats(catset->cats);
    238 }
    239 
    240 static inline void cil_reset_level(struct cil_level *level)
    241 {
    242 	cil_reset_cats(level->cats);
    243 }
    244 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    378 static void cil_reset_validatetrans(struct cil_validatetrans *vt)
    379 {
    380 	cil_list_destroy(&vt->datum_expr, CIL_FALSE);
    381 }
    382 
    383 static void cil_reset_default(struct cil_default *def)
    384 {
    385 	cil_list_destroy(&def->class_datums, CIL_FALSE);
    386 }
    387 
    388 static void cil_reset_defaultrange(struct cil_defaultrange *def)
    389 {
    390 	cil_list_destroy(&def->class_datums, CIL_FALSE);
    391 }
    392 
    393 static void cil_reset_booleanif(struct cil_booleanif *bif)
    394 {
    395 	cil_list_destroy(&bif->datum_expr, CIL_FALSE);
    396 }
    397 
    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 		break; /* Nothing to reset */
    553 	default:
    554 		break;
    555 	}
    556 
    557 	return SEPOL_OK;
    558 }
    559 
    560 int cil_reset_ast(struct cil_tree_node *current)
    561 {
    562 	int rc = SEPOL_ERR;
    563 
    564 	rc = cil_tree_walk(current, __cil_reset_node, NULL, NULL, NULL);
    565 	if (rc != SEPOL_OK) {
    566 		cil_log(CIL_ERR, "Failed to reset AST\n");
    567 		return SEPOL_ERR;
    568 	}
    569 
    570 	return SEPOL_OK;
    571 }
    572