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 	cil_list_destroy(&user->roles, CIL_FALSE);
    103 }
    104 
    105 static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser)
    106 {
    107 	if (selinuxuser->range_str == NULL) {
    108 		cil_reset_levelrange(selinuxuser->range);
    109 	}
    110 }
    111 
    112 static void cil_reset_role(struct cil_role *role)
    113 {
    114 	/* reset the bounds to NULL during a re-resolve */
    115 	role->bounds = NULL;
    116 }
    117 
    118 static void cil_reset_roleattr(struct cil_roleattribute *attr)
    119 {
    120 	/* during a re-resolve, we need to reset the lists of expression stacks  associated with this attribute from a attributeroles statement */
    121 	if (attr->expr_list != NULL) {
    122 		/* we don't want to destroy the expression stacks (cil_list) inside
    123 		 * this list cil_list_destroy destroys sublists, so we need to do it
    124 		 * manually */
    125 		struct cil_list_item *expr = attr->expr_list->head;
    126 		while (expr != NULL) {
    127 			struct cil_list_item *next = expr->next;
    128 			cil_list_item_destroy(&expr, CIL_FALSE);
    129 			expr = next;
    130 		}
    131 		free(attr->expr_list);
    132 		attr->expr_list = NULL;
    133 	}
    134 }
    135 
    136 static void cil_reset_roleattributeset(struct cil_roleattributeset *ras)
    137 {
    138 	cil_list_destroy(&ras->datum_expr, CIL_FALSE);
    139 }
    140 
    141 static void cil_reset_type(struct cil_type *type)
    142 {
    143 	/* reset the bounds to NULL during a re-resolve */
    144 	type->bounds = NULL;
    145 }
    146 
    147 static void cil_reset_typeattr(struct cil_typeattribute *attr)
    148 {
    149 	/* during a re-resolve, we need to reset the lists of expression stacks  associated with this attribute from a attributetypes statement */
    150 	if (attr->expr_list != NULL) {
    151 		/* we don't want to destroy the expression stacks (cil_list) inside
    152 		 * this list cil_list_destroy destroys sublists, so we need to do it
    153 		 * manually */
    154 		struct cil_list_item *expr = attr->expr_list->head;
    155 		while (expr != NULL) {
    156 			struct cil_list_item *next = expr->next;
    157 			cil_list_item_destroy(&expr, CIL_FALSE);
    158 			expr = next;
    159 		}
    160 		free(attr->expr_list);
    161 		attr->expr_list = NULL;
    162 	}
    163 	attr->used = CIL_FALSE;
    164 }
    165 
    166 static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
    167 {
    168 	cil_list_destroy(&tas->datum_expr, CIL_FALSE);
    169 }
    170 
    171 static void cil_reset_avrule(struct cil_avrule *rule)
    172 {
    173 	cil_reset_classperms_list(rule->classperms);
    174 }
    175 
    176 static void cil_reset_rangetransition(struct cil_rangetransition *rangetrans)
    177 {
    178 	if (rangetrans->range_str == NULL) {
    179 		cil_reset_levelrange(rangetrans->range);
    180 	}
    181 }
    182 
    183 static void cil_reset_sens(struct cil_sens *sens)
    184 {
    185 	/* during a re-resolve, we need to reset the categories associated with
    186 	 * this sensitivity from a (sensitivitycategory) statement */
    187 	cil_list_destroy(&sens->cats_list, CIL_FALSE);
    188 	sens->ordered = CIL_FALSE;
    189 }
    190 
    191 static void cil_reset_cat(struct cil_cat *cat)
    192 {
    193 	cat->ordered = CIL_FALSE;
    194 }
    195 
    196 static inline void cil_reset_cats(struct cil_cats *cats)
    197 {
    198 	if (cats != NULL) {
    199 		cats->evaluated = CIL_FALSE;
    200 		cil_list_destroy(&cats->datum_expr, CIL_FALSE);
    201 	}
    202 }
    203 
    204 
    205 static void cil_reset_senscat(struct cil_senscat *senscat)
    206 {
    207 	cil_reset_cats(senscat->cats);
    208 }
    209 
    210 static void cil_reset_catset(struct cil_catset *catset)
    211 {
    212 	cil_reset_cats(catset->cats);
    213 }
    214 
    215 static inline void cil_reset_level(struct cil_level *level)
    216 {
    217 	cil_reset_cats(level->cats);
    218 }
    219 
    220 static inline void cil_reset_levelrange(struct cil_levelrange *levelrange)
    221 {
    222 	if (levelrange->low_str == NULL) {
    223 		cil_reset_level(levelrange->low);
    224 	}
    225 
    226 	if (levelrange->high_str == NULL) {
    227 		cil_reset_level(levelrange->high);
    228 	}
    229 }
    230 
    231 static inline void cil_reset_userlevel(struct cil_userlevel *userlevel)
    232 {
    233 	if (userlevel->level_str == NULL) {
    234 		cil_reset_level(userlevel->level);
    235 	}
    236 }
    237 
    238 static inline void cil_reset_userrange(struct cil_userrange *userrange)
    239 {
    240 	if (userrange->range_str == NULL) {
    241 		cil_reset_levelrange(userrange->range);
    242 	}
    243 }
    244 
    245 static inline void cil_reset_context(struct cil_context *context)
    246 {
    247 	if (context->range_str == NULL) {
    248 		cil_reset_levelrange(context->range);
    249 	}
    250 }
    251 
    252 static void cil_reset_sidcontext(struct cil_sidcontext *sidcontext)
    253 {
    254 	if (sidcontext->context_str == NULL) {
    255 		cil_reset_context(sidcontext->context);
    256 	}
    257 }
    258 
    259 static void cil_reset_filecon(struct cil_filecon *filecon)
    260 {
    261 	if (filecon->context_str == NULL && filecon->context != NULL) {
    262 		cil_reset_context(filecon->context);
    263 	}
    264 }
    265 
    266 static void cil_reset_portcon(struct cil_portcon *portcon)
    267 {
    268 	if (portcon->context_str == NULL) {
    269 		cil_reset_context(portcon->context);
    270 	}
    271 }
    272 
    273 static void cil_reset_nodecon(struct cil_nodecon *nodecon)
    274 {
    275 	if (nodecon->context_str == NULL) {
    276 		cil_reset_context(nodecon->context);
    277 	}
    278 }
    279 
    280 static void cil_reset_genfscon(struct cil_genfscon *genfscon)
    281 {
    282 	if (genfscon->context_str == NULL) {
    283 		cil_reset_context(genfscon->context);
    284 	}
    285 }
    286 
    287 static void cil_reset_netifcon(struct cil_netifcon *netifcon)
    288 {
    289 	if (netifcon->if_context_str == NULL) {
    290 		cil_reset_context(netifcon->if_context);
    291 	}
    292 
    293 	if (netifcon->packet_context_str == NULL) {
    294 		cil_reset_context(netifcon->packet_context);
    295 	}
    296 }
    297 
    298 static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon)
    299 {
    300 	if (pirqcon->context_str == NULL) {
    301 		cil_reset_context(pirqcon->context);
    302 	}
    303 }
    304 
    305 static void cil_reset_iomemcon(struct cil_iomemcon *iomemcon)
    306 {
    307 	if (iomemcon->context_str == NULL) {
    308 		cil_reset_context(iomemcon->context);
    309 	}
    310 }
    311 
    312 static void cil_reset_ioportcon(struct cil_ioportcon *ioportcon)
    313 {
    314 	if (ioportcon->context_str == NULL) {
    315 		cil_reset_context(ioportcon->context);
    316 	}
    317 }
    318 
    319 static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
    320 {
    321 	if (pcidevicecon->context_str == NULL) {
    322 		cil_reset_context(pcidevicecon->context);
    323 	}
    324 }
    325 
    326 static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon)
    327 {
    328 	if (devicetreecon->context_str == NULL) {
    329 		cil_reset_context(devicetreecon->context);
    330 	}
    331 }
    332 
    333 static void cil_reset_fsuse(struct cil_fsuse *fsuse)
    334 {
    335 	if (fsuse->context_str == NULL) {
    336 		cil_reset_context(fsuse->context);
    337 	}
    338 }
    339 
    340 static void cil_reset_sid(struct cil_sid *sid)
    341 {
    342 	/* reset the context to NULL during a re-resolve */
    343 	sid->context = NULL;
    344 	sid->ordered = CIL_FALSE;
    345 }
    346 
    347 static void cil_reset_constrain(struct cil_constrain *con)
    348 {
    349 	cil_reset_classperms_list(con->classperms);
    350 	cil_list_destroy(&con->datum_expr, CIL_FALSE);
    351 }
    352 
    353 static void cil_reset_validatetrans(struct cil_validatetrans *vt)
    354 {
    355 	cil_list_destroy(&vt->datum_expr, CIL_FALSE);
    356 }
    357 
    358 static void cil_reset_default(struct cil_default *def)
    359 {
    360 	cil_list_destroy(&def->class_datums, CIL_FALSE);
    361 }
    362 
    363 static void cil_reset_defaultrange(struct cil_defaultrange *def)
    364 {
    365 	cil_list_destroy(&def->class_datums, CIL_FALSE);
    366 }
    367 
    368 static void cil_reset_booleanif(struct cil_booleanif *bif)
    369 {
    370 	cil_list_destroy(&bif->datum_expr, CIL_FALSE);
    371 }
    372 
    373 int __cil_reset_node(struct cil_tree_node *node,  __attribute__((unused)) uint32_t *finished, __attribute__((unused)) void *extra_args)
    374 {
    375 	switch (node->flavor) {
    376 	case CIL_CLASS:
    377 		cil_reset_class(node->data);
    378 		break;
    379 	case CIL_PERM:
    380 	case CIL_MAP_PERM:
    381 		cil_reset_perm(node->data);
    382 		break;
    383 	case CIL_CLASSPERMISSION:
    384 		cil_reset_classpermission(node->data);
    385 		break;
    386 	case CIL_CLASSPERMISSIONSET:
    387 		cil_reset_classpermissionset(node->data);
    388 		break;
    389 	case CIL_CLASSMAPPING:
    390 		cil_reset_classmapping(node->data);
    391 		break;
    392 	case CIL_TYPEALIAS:
    393 	case CIL_SENSALIAS:
    394 	case CIL_CATALIAS:
    395 		cil_reset_alias(node->data);
    396 		break;
    397 	case CIL_USERRANGE:
    398 		cil_reset_userrange(node->data);
    399 		break;
    400 	case CIL_USERLEVEL:
    401 		cil_reset_userlevel(node->data);
    402 		break;
    403 	case CIL_USER:
    404 		cil_reset_user(node->data);
    405 		break;
    406 	case CIL_SELINUXUSERDEFAULT:
    407 	case CIL_SELINUXUSER:
    408 		cil_reset_selinuxuser(node->data);
    409 		break;
    410 	case CIL_ROLE:
    411 		cil_reset_role(node->data);
    412 		break;
    413 	case CIL_ROLEATTRIBUTE:
    414 		cil_reset_roleattr(node->data);
    415 		break;
    416 	case CIL_ROLEATTRIBUTESET:
    417 		cil_reset_roleattributeset(node->data);
    418 		break;
    419 	case CIL_TYPE:
    420 		cil_reset_type(node->data);
    421 		break;
    422 	case CIL_TYPEATTRIBUTE:
    423 		cil_reset_typeattr(node->data);
    424 		break;
    425 	case CIL_TYPEATTRIBUTESET:
    426 		cil_reset_typeattributeset(node->data);
    427 		break;
    428 	case CIL_RANGETRANSITION:
    429 		cil_reset_rangetransition(node->data);
    430 		break;
    431 	case CIL_AVRULE:
    432 		cil_reset_avrule(node->data);
    433 		break;
    434 	case CIL_SENS:
    435 		cil_reset_sens(node->data);
    436 		break;
    437 	case CIL_CAT:
    438 		cil_reset_cat(node->data);
    439 		break;
    440 	case CIL_SENSCAT:
    441 		cil_reset_senscat(node->data);
    442 		break;
    443 	case CIL_CATSET:
    444 		cil_reset_catset(node->data);
    445 		break;
    446 	case CIL_LEVEL:
    447 		cil_reset_level(node->data);
    448 		break;
    449 	case CIL_LEVELRANGE:
    450 		cil_reset_levelrange(node->data);
    451 		break;
    452 	case CIL_CONTEXT:
    453 		cil_reset_context(node->data);
    454 		break;
    455 	case CIL_SIDCONTEXT:
    456 		cil_reset_sidcontext(node->data);
    457 		break;
    458 	case CIL_FILECON:
    459 		cil_reset_filecon(node->data);
    460 		break;
    461 	case CIL_PORTCON:
    462 		cil_reset_portcon(node->data);
    463 		break;
    464 	case CIL_NODECON:
    465 		cil_reset_nodecon(node->data);
    466 		break;
    467 	case CIL_GENFSCON:
    468 		cil_reset_genfscon(node->data);
    469 		break;
    470 	case CIL_NETIFCON:
    471 		cil_reset_netifcon(node->data);
    472 		break;
    473 	case CIL_PIRQCON:
    474 		cil_reset_pirqcon(node->data);
    475 		break;
    476 	case CIL_IOMEMCON:
    477 		cil_reset_iomemcon(node->data);
    478 		break;
    479 	case CIL_IOPORTCON:
    480 		cil_reset_ioportcon(node->data);
    481 		break;
    482 	case CIL_PCIDEVICECON:
    483 		cil_reset_pcidevicecon(node->data);
    484 		break;
    485 	case CIL_DEVICETREECON:
    486 		cil_reset_devicetreecon(node->data);
    487 		break;
    488 	case CIL_FSUSE:
    489 		cil_reset_fsuse(node->data);
    490 		break;
    491 	case CIL_SID:
    492 		cil_reset_sid(node->data);
    493 		break;
    494 	case CIL_CONSTRAIN:
    495 	case CIL_MLSCONSTRAIN:
    496 		cil_reset_constrain(node->data);
    497 		break;
    498 	case CIL_VALIDATETRANS:
    499 	case CIL_MLSVALIDATETRANS:
    500 		cil_reset_validatetrans(node->data);
    501 		break;
    502 	case CIL_DEFAULTUSER:
    503 	case CIL_DEFAULTROLE:
    504 	case CIL_DEFAULTTYPE:
    505 		cil_reset_default(node->data);
    506 		break;
    507 	case CIL_DEFAULTRANGE:
    508 		cil_reset_defaultrange(node->data);
    509 		break;
    510 	case CIL_BOOLEANIF:
    511 		cil_reset_booleanif(node->data);
    512 		break;
    513 	case CIL_TUNABLEIF:
    514 	case CIL_CALL:
    515 		break; /* Not effected by optional block disabling */
    516 	case CIL_MACRO:
    517 	case CIL_SIDORDER:
    518 	case CIL_CLASSORDER:
    519 	case CIL_CATORDER:
    520 	case CIL_SENSITIVITYORDER:
    521 		break; /* Nothing to reset */
    522 	default:
    523 		break;
    524 	}
    525 
    526 	return SEPOL_OK;
    527 }
    528 
    529 int cil_reset_ast(struct cil_tree_node *current)
    530 {
    531 	int rc = SEPOL_ERR;
    532 
    533 	rc = cil_tree_walk(current, __cil_reset_node, NULL, NULL, NULL);
    534 	if (rc != SEPOL_OK) {
    535 		cil_log(CIL_ERR, "Failed to reset AST\n");
    536 		return SEPOL_ERR;
    537 	}
    538 
    539 	return SEPOL_OK;
    540 }
    541