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