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