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