1 /* 2 * Copyright 2011 Tresys Technology, LLC. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * The views and conclusions contained in the software and documentation are those 26 * of the authors and should not be interpreted as representing official policies, 27 * either expressed or implied, of Tresys Technology, LLC. 28 */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <string.h> 33 34 #include <sepol/policydb/conditional.h> 35 36 #include "cil_internal.h" 37 #include "cil_flavor.h" 38 #include "cil_log.h" 39 #include "cil_mem.h" 40 #include "cil_tree.h" 41 #include "cil_list.h" 42 #include "cil_build_ast.h" 43 #include "cil_resolve_ast.h" 44 #include "cil_reset_ast.h" 45 #include "cil_copy_ast.h" 46 #include "cil_verify.h" 47 #include "cil_strpool.h" 48 #include "cil_symtab.h" 49 50 struct cil_args_resolve { 51 struct cil_db *db; 52 enum cil_pass pass; 53 uint32_t *changed; 54 char *last_resolved_name; 55 struct cil_tree_node *optstack; 56 struct cil_tree_node *boolif; 57 struct cil_tree_node *macro; 58 struct cil_tree_node *blockstack; 59 struct cil_list *sidorder_lists; 60 struct cil_list *classorder_lists; 61 struct cil_list *unordered_classorder_lists; 62 struct cil_list *catorder_lists; 63 struct cil_list *sensitivityorder_lists; 64 struct cil_list *in_list; 65 }; 66 67 static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node) 68 { 69 /* Currently only used for typetransition file names. 70 But could be used for any string that is passed as a parameter. 71 */ 72 struct cil_tree_node *parent = ast_node->parent; 73 struct cil_macro *macro = NULL; 74 struct cil_name *name; 75 symtab_t *symtab; 76 enum cil_sym_index sym_index; 77 struct cil_symtab_datum *datum = NULL; 78 79 cil_flavor_to_symtab_index(CIL_NAME, &sym_index); 80 symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index]; 81 82 cil_symtab_get_datum(symtab, key, &datum); 83 if (datum != NULL) { 84 return (struct cil_name *)datum; 85 } 86 87 if (parent->flavor == CIL_CALL) { 88 struct cil_call *call = parent->data; 89 macro = call->macro; 90 } else if (parent->flavor == CIL_MACRO) { 91 macro = parent->data; 92 } 93 if (macro != NULL) { 94 struct cil_list_item *item; 95 cil_list_for_each(item, macro->params) { 96 if (((struct cil_param*)item->data)->str == key) { 97 return NULL; 98 } 99 } 100 } 101 102 cil_name_init(&name); 103 cil_symtab_insert(symtab, key, (struct cil_symtab_datum *)name, ast_node); 104 cil_list_append(db->names, CIL_NAME, name); 105 106 return name; 107 } 108 109 static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, struct cil_list *perm_strs, struct cil_list **perm_datums, enum cil_flavor class_flavor) 110 { 111 int rc = SEPOL_ERR; 112 struct cil_list_item *curr; 113 114 cil_list_init(perm_datums, perm_strs->flavor); 115 116 cil_list_for_each(curr, perm_strs) { 117 if (curr->flavor == CIL_LIST) { 118 struct cil_list *sub_list; 119 rc = __cil_resolve_perms(class_symtab, common_symtab, curr->data, &sub_list, class_flavor); 120 if (rc != SEPOL_OK) { 121 cil_log(CIL_ERR, "Failed to resolve permission list\n"); 122 goto exit; 123 } 124 cil_list_append(*perm_datums, CIL_LIST, sub_list); 125 } else if (curr->flavor == CIL_STRING) { 126 struct cil_symtab_datum *perm_datum = NULL; 127 rc = cil_symtab_get_datum(class_symtab, curr->data, &perm_datum); 128 if (rc == SEPOL_ENOENT) { 129 if (common_symtab) { 130 rc = cil_symtab_get_datum(common_symtab, curr->data, &perm_datum); 131 } 132 } 133 if (rc != SEPOL_OK) { 134 struct cil_list *empty_list; 135 if (class_flavor == CIL_MAP_CLASS) { 136 cil_log(CIL_ERR, "Failed to resolve permission %s for map class\n", (char*)curr->data); 137 goto exit; 138 } 139 cil_log(CIL_WARN, "Failed to resolve permission %s\n", (char*)curr->data); 140 /* Use an empty list to represent unknown perm */ 141 cil_list_init(&empty_list, perm_strs->flavor); 142 cil_list_append(*perm_datums, CIL_LIST, empty_list); 143 } else { 144 cil_list_append(*perm_datums, CIL_DATUM, perm_datum); 145 } 146 } else { 147 cil_list_append(*perm_datums, curr->flavor, curr->data); 148 } 149 } 150 151 return SEPOL_OK; 152 153 exit: 154 return rc; 155 } 156 157 int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, void *extra_args) 158 { 159 int rc = SEPOL_ERR; 160 struct cil_symtab_datum *datum = NULL; 161 symtab_t *common_symtab = NULL; 162 struct cil_class *class; 163 164 rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, extra_args, &datum); 165 if (rc != SEPOL_OK) { 166 goto exit; 167 } 168 169 class = (struct cil_class *)datum; 170 171 if (class->common != NULL) { 172 common_symtab = &class->common->perms; 173 } 174 175 cp->class = class; 176 177 rc = __cil_resolve_perms(&class->perms, common_symtab, cp->perm_strs, &cp->perms, FLAVOR(datum)); 178 if (rc != SEPOL_OK) { 179 goto exit; 180 } 181 182 return SEPOL_OK; 183 184 exit: 185 return rc; 186 } 187 188 int cil_resolve_classperms_set(struct cil_tree_node *current, struct cil_classperms_set *cp_set, void *extra_args) 189 { 190 int rc = SEPOL_ERR; 191 struct cil_symtab_datum *datum = NULL; 192 193 rc = cil_resolve_name(current, cp_set->set_str, CIL_SYM_CLASSPERMSETS, extra_args, &datum); 194 if (rc != SEPOL_OK) { 195 goto exit; 196 } 197 cp_set->set = (struct cil_classpermission*)datum; 198 199 /* This could be an anonymous classpermission */ 200 if (datum->name == NULL) { 201 rc = cil_resolve_classperms_list(current, cp_set->set->classperms, extra_args); 202 if (rc != SEPOL_OK) { 203 goto exit; 204 } 205 } 206 207 return SEPOL_OK; 208 209 exit: 210 return rc; 211 } 212 213 int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, void *extra_args) 214 { 215 int rc = SEPOL_ERR; 216 struct cil_list_item *curr; 217 218 cil_list_for_each(curr, cp_list) { 219 if (curr->flavor == CIL_CLASSPERMS) { 220 rc = cil_resolve_classperms(current, curr->data, extra_args); 221 if (rc != SEPOL_OK) { 222 goto exit; 223 } 224 } else { 225 rc = cil_resolve_classperms_set(current, curr->data, extra_args); 226 if (rc != SEPOL_OK) { 227 goto exit; 228 } 229 } 230 } 231 232 return SEPOL_OK; 233 234 exit: 235 return rc; 236 } 237 238 int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, void *extra_args) 239 { 240 int rc = SEPOL_ERR; 241 struct cil_args_resolve *args = extra_args; 242 struct cil_list_item *curr; 243 struct cil_symtab_datum *datum; 244 struct cil_classpermission *cp; 245 246 rc = cil_resolve_name(current, cps->set_str, CIL_SYM_CLASSPERMSETS, args, &datum); 247 if (rc != SEPOL_OK) { 248 goto exit; 249 } 250 251 rc = cil_resolve_classperms_list(current, cps->classperms, extra_args); 252 if (rc != SEPOL_OK) { 253 goto exit; 254 } 255 256 cp = (struct cil_classpermission *)datum; 257 258 if (cp->classperms == NULL) { 259 cil_list_init(&cp->classperms, CIL_CLASSPERMS); 260 } 261 262 cil_list_for_each(curr, cps->classperms) { 263 cil_list_append(cp->classperms, curr->flavor, curr->data); 264 } 265 266 return SEPOL_OK; 267 268 exit: 269 return rc; 270 } 271 272 int cil_type_used(struct cil_symtab_datum *datum, int used) 273 { 274 int rc = SEPOL_ERR; 275 struct cil_typeattribute *attr = NULL; 276 277 if (FLAVOR(datum) == CIL_TYPEATTRIBUTE) { 278 attr = (struct cil_typeattribute*)datum; 279 attr->used |= used; 280 if ((attr->used & CIL_ATTR_EXPAND_TRUE) && 281 (attr->used & CIL_ATTR_EXPAND_FALSE)) { 282 cil_log(CIL_ERR, "Conflicting use of expandtypeattribute. " 283 "Expandtypeattribute may be set to true or false " 284 "but not both. \n"); 285 goto exit; 286 } 287 } 288 289 return SEPOL_OK; 290 exit: 291 return rc; 292 } 293 294 int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, void *extra_args) 295 { 296 struct cil_symtab_datum *obj_datum = NULL; 297 int rc = SEPOL_ERR; 298 299 rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); 300 if (rc != SEPOL_OK) { 301 goto exit; 302 } 303 permx->obj = (struct cil_class*)obj_datum; 304 305 return SEPOL_OK; 306 307 exit: 308 return rc; 309 } 310 311 int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args) 312 { 313 struct cil_args_resolve *args = extra_args; 314 struct cil_db *db = NULL; 315 316 struct cil_avrule *rule = current->data; 317 struct cil_symtab_datum *src_datum = NULL; 318 struct cil_symtab_datum *tgt_datum = NULL; 319 struct cil_symtab_datum *permx_datum = NULL; 320 int used; 321 int rc = SEPOL_ERR; 322 323 if (args != NULL) { 324 db = args->db; 325 } 326 327 rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, args, &src_datum); 328 if (rc != SEPOL_OK) { 329 goto exit; 330 } 331 rule->src = src_datum; 332 333 if (rule->tgt_str == CIL_KEY_SELF) { 334 rule->tgt = db->selftype; 335 } else { 336 rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum); 337 if (rc != SEPOL_OK) { 338 goto exit; 339 } 340 rule->tgt = tgt_datum; 341 used = (rule->rule_kind == CIL_AVRULE_NEVERALLOW) ? 342 CIL_ATTR_NEVERALLOW : CIL_ATTR_AVRULE; 343 cil_type_used(src_datum, used); /* src not used if tgt is self */ 344 cil_type_used(tgt_datum, used); 345 } 346 347 if (!rule->is_extended) { 348 rc = cil_resolve_classperms_list(current, rule->perms.classperms, extra_args); 349 if (rc != SEPOL_OK) { 350 goto exit; 351 } 352 } else { 353 if (rule->perms.x.permx_str != NULL) { 354 rc = cil_resolve_name(current, rule->perms.x.permx_str, CIL_SYM_PERMX, args, &permx_datum); 355 if (rc != SEPOL_OK) { 356 goto exit; 357 } 358 rule->perms.x.permx = (struct cil_permissionx*)permx_datum; 359 } else { 360 rc = cil_resolve_permissionx(current, rule->perms.x.permx, extra_args); 361 if (rc != SEPOL_OK) { 362 goto exit; 363 } 364 } 365 } 366 367 return SEPOL_OK; 368 369 exit: 370 return rc; 371 } 372 373 int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args) 374 { 375 struct cil_type_rule *rule = current->data; 376 struct cil_symtab_datum *src_datum = NULL; 377 struct cil_symtab_datum *tgt_datum = NULL; 378 struct cil_symtab_datum *obj_datum = NULL; 379 struct cil_symtab_datum *result_datum = NULL; 380 struct cil_tree_node *result_node = NULL; 381 int rc = SEPOL_ERR; 382 383 rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, extra_args, &src_datum); 384 if (rc != SEPOL_OK) { 385 goto exit; 386 } 387 rule->src = src_datum; 388 389 rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); 390 if (rc != SEPOL_OK) { 391 goto exit; 392 } 393 rule->tgt = tgt_datum; 394 395 rc = cil_resolve_name(current, rule->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); 396 if (rc != SEPOL_OK) { 397 goto exit; 398 } 399 rule->obj = (struct cil_class*)obj_datum; 400 401 rc = cil_resolve_name(current, rule->result_str, CIL_SYM_TYPES, extra_args, &result_datum); 402 if (rc != SEPOL_OK) { 403 goto exit; 404 } 405 406 result_node = result_datum->nodes->head->data; 407 408 if (result_node->flavor != CIL_TYPE) { 409 cil_log(CIL_ERR, "Type rule result must be a type [%d]\n",result_node->flavor); 410 rc = SEPOL_ERR; 411 goto exit; 412 } 413 rule->result = result_datum; 414 415 return SEPOL_OK; 416 417 exit: 418 return rc; 419 } 420 421 int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args) 422 { 423 struct cil_typeattributeset *attrtypes = current->data; 424 struct cil_symtab_datum *attr_datum = NULL; 425 struct cil_tree_node *attr_node = NULL; 426 struct cil_typeattribute *attr = NULL; 427 int rc = SEPOL_ERR; 428 429 rc = cil_resolve_name(current, attrtypes->attr_str, CIL_SYM_TYPES, extra_args, &attr_datum); 430 if (rc != SEPOL_OK) { 431 goto exit; 432 } 433 434 attr_node = attr_datum->nodes->head->data; 435 436 if (attr_node->flavor != CIL_TYPEATTRIBUTE) { 437 rc = SEPOL_ERR; 438 cil_log(CIL_ERR, "Attribute type not an attribute\n"); 439 goto exit; 440 } 441 442 attr = (struct cil_typeattribute*)attr_datum; 443 444 rc = cil_resolve_expr(CIL_TYPEATTRIBUTESET, attrtypes->str_expr, &attrtypes->datum_expr, current, extra_args); 445 if (rc != SEPOL_OK) { 446 goto exit; 447 } 448 449 rc = cil_verify_no_self_reference(attr_datum, attrtypes->datum_expr); 450 if (rc != SEPOL_OK) { 451 goto exit; 452 } 453 454 if (attr->expr_list == NULL) { 455 cil_list_init(&attr->expr_list, CIL_TYPEATTRIBUTE); 456 } 457 458 cil_list_append(attr->expr_list, CIL_LIST, attrtypes->datum_expr); 459 460 return SEPOL_OK; 461 462 exit: 463 return rc; 464 } 465 466 int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void *extra_args) 467 { 468 struct cil_expandtypeattribute *expandattr = current->data; 469 struct cil_symtab_datum *attr_datum = NULL; 470 struct cil_tree_node *attr_node = NULL; 471 struct cil_list_item *curr; 472 int used; 473 int rc = SEPOL_ERR; 474 475 cil_list_init(&expandattr->attr_datums, CIL_TYPE); 476 477 cil_list_for_each(curr, expandattr->attr_strs) { 478 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_TYPES, extra_args, &attr_datum); 479 if (rc != SEPOL_OK) { 480 goto exit; 481 } 482 483 attr_node = attr_datum->nodes->head->data; 484 485 if (attr_node->flavor != CIL_TYPEATTRIBUTE) { 486 rc = SEPOL_ERR; 487 cil_log(CIL_ERR, "Attribute type not an attribute\n"); 488 goto exit; 489 } 490 used = expandattr->expand ? CIL_ATTR_EXPAND_TRUE : CIL_ATTR_EXPAND_FALSE; 491 rc = cil_type_used(attr_datum, used); 492 if (rc != SEPOL_OK) { 493 goto exit; 494 } 495 496 cil_list_append(expandattr->attr_datums, CIL_TYPE, attr_datum); 497 } 498 499 return SEPOL_OK; 500 exit: 501 return rc; 502 } 503 504 int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor alias_flavor) 505 { 506 int rc = SEPOL_ERR; 507 enum cil_sym_index sym_index; 508 struct cil_aliasactual *aliasactual = current->data; 509 struct cil_symtab_datum *alias_datum = NULL; 510 struct cil_symtab_datum *actual_datum = NULL; 511 struct cil_alias *alias; 512 513 rc = cil_flavor_to_symtab_index(flavor, &sym_index); 514 if (rc != SEPOL_OK) { 515 goto exit; 516 } 517 518 rc = cil_resolve_name(current, aliasactual->alias_str, sym_index, extra_args, &alias_datum); 519 if (rc != SEPOL_OK) { 520 goto exit; 521 } 522 if (NODE(alias_datum)->flavor != alias_flavor) { 523 cil_log(CIL_ERR, "%s is not an alias\n",alias_datum->name); 524 goto exit; 525 } 526 527 rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, extra_args, &actual_datum); 528 if (rc != SEPOL_OK) { 529 goto exit; 530 } 531 532 alias = (struct cil_alias *)alias_datum; 533 534 if (alias->actual != NULL) { 535 cil_log(CIL_ERR, "Alias cannot bind more than one value\n"); 536 rc = SEPOL_ERR; 537 goto exit; 538 } 539 540 alias->actual = actual_datum; 541 542 return SEPOL_OK; 543 544 exit: 545 return rc; 546 } 547 548 int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor flavor) 549 { 550 struct cil_alias *alias = current->data; 551 struct cil_alias *a1 = current->data; 552 struct cil_alias *a2 = current->data; 553 struct cil_tree_node *a1_node = NULL; 554 int steps = 0; 555 int limit = 2; 556 557 if (alias->actual == NULL) { 558 cil_tree_log(current, CIL_ERR, "Alias declared but not used"); 559 return SEPOL_ERR; 560 } 561 562 a1_node = a1->datum.nodes->head->data; 563 564 while (flavor != a1_node->flavor) { 565 a1 = a1->actual; 566 a1_node = a1->datum.nodes->head->data; 567 steps += 1; 568 569 if (a1 == a2) { 570 cil_log(CIL_ERR, "Circular alias found: %s ", a1->datum.name); 571 a1 = a1->actual; 572 while (a1 != a2) { 573 cil_log(CIL_ERR, "%s ", a1->datum.name); 574 a1 = a1->actual; 575 } 576 cil_log(CIL_ERR,"\n"); 577 return SEPOL_ERR; 578 } 579 580 if (steps == limit) { 581 steps = 0; 582 limit *= 2; 583 a2 = a1; 584 } 585 } 586 587 alias->actual = a1; 588 589 return SEPOL_OK; 590 } 591 592 int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args) 593 { 594 struct cil_typepermissive *typeperm = current->data; 595 struct cil_symtab_datum *type_datum = NULL; 596 struct cil_tree_node *type_node = NULL; 597 int rc = SEPOL_ERR; 598 599 rc = cil_resolve_name(current, typeperm->type_str, CIL_SYM_TYPES, extra_args, &type_datum); 600 if (rc != SEPOL_OK) { 601 goto exit; 602 } 603 604 type_node = type_datum->nodes->head->data; 605 606 if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) { 607 cil_log(CIL_ERR, "Typepermissive must be a type or type alias\n"); 608 rc = SEPOL_ERR; 609 goto exit; 610 } 611 612 typeperm->type = type_datum; 613 614 return SEPOL_OK; 615 616 exit: 617 return rc; 618 } 619 620 int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_args) 621 { 622 struct cil_args_resolve *args = extra_args; 623 struct cil_nametypetransition *nametypetrans = current->data; 624 struct cil_symtab_datum *src_datum = NULL; 625 struct cil_symtab_datum *tgt_datum = NULL; 626 struct cil_symtab_datum *obj_datum = NULL; 627 struct cil_symtab_datum *name_datum = NULL; 628 struct cil_symtab_datum *result_datum = NULL; 629 struct cil_tree_node *result_node = NULL; 630 int rc = SEPOL_ERR; 631 632 rc = cil_resolve_name(current, nametypetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum); 633 if (rc != SEPOL_OK) { 634 goto exit; 635 } 636 nametypetrans->src = src_datum; 637 638 rc = cil_resolve_name(current, nametypetrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); 639 if (rc != SEPOL_OK) { 640 goto exit; 641 } 642 nametypetrans->tgt = tgt_datum; 643 644 rc = cil_resolve_name(current, nametypetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); 645 if (rc != SEPOL_OK) { 646 goto exit; 647 } 648 nametypetrans->obj = (struct cil_class*)obj_datum; 649 650 nametypetrans->name = __cil_insert_name(args->db, nametypetrans->name_str, current); 651 if (nametypetrans->name == NULL) { 652 rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_NAMES, extra_args, &name_datum); 653 if (rc != SEPOL_OK) { 654 goto exit; 655 } 656 nametypetrans->name = (struct cil_name *)name_datum; 657 } 658 659 rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, extra_args, &result_datum); 660 if (rc != SEPOL_OK) { 661 goto exit; 662 } 663 664 result_node = result_datum->nodes->head->data; 665 666 if (result_node->flavor != CIL_TYPE && result_node->flavor != CIL_TYPEALIAS) { 667 cil_log(CIL_ERR, "typetransition result is not a type or type alias\n"); 668 rc = SEPOL_ERR; 669 goto exit; 670 } 671 nametypetrans->result = result_datum; 672 673 return SEPOL_OK; 674 675 exit: 676 return rc; 677 } 678 679 int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args) 680 { 681 struct cil_rangetransition *rangetrans = current->data; 682 struct cil_symtab_datum *src_datum = NULL; 683 struct cil_symtab_datum *exec_datum = NULL; 684 struct cil_symtab_datum *obj_datum = NULL; 685 struct cil_symtab_datum *range_datum = NULL; 686 int rc = SEPOL_ERR; 687 688 rc = cil_resolve_name(current, rangetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum); 689 if (rc != SEPOL_OK) { 690 goto exit; 691 } 692 rangetrans->src = src_datum; 693 694 rc = cil_resolve_name(current, rangetrans->exec_str, CIL_SYM_TYPES, extra_args, &exec_datum); 695 if (rc != SEPOL_OK) { 696 goto exit; 697 } 698 rangetrans->exec = exec_datum; 699 700 rc = cil_resolve_name(current, rangetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); 701 if (rc != SEPOL_OK) { 702 goto exit; 703 } 704 rangetrans->obj = (struct cil_class*)obj_datum; 705 706 if (rangetrans->range_str != NULL) { 707 rc = cil_resolve_name(current, rangetrans->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum); 708 if (rc != SEPOL_OK) { 709 goto exit; 710 } 711 rangetrans->range = (struct cil_levelrange*)range_datum; 712 713 /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/ 714 if (rangetrans->range->datum.name == NULL) { 715 rc = cil_resolve_levelrange(current, rangetrans->range, extra_args); 716 if (rc != SEPOL_OK) { 717 goto exit; 718 } 719 } 720 } else { 721 rc = cil_resolve_levelrange(current, rangetrans->range, extra_args); 722 if (rc != SEPOL_OK) { 723 goto exit; 724 } 725 } 726 727 return SEPOL_OK; 728 729 exit: 730 return rc; 731 } 732 733 int __class_update_perm_values(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 734 { 735 struct cil_perm *perm = (struct cil_perm *)d; 736 737 perm->value += *((int *)args); 738 739 return SEPOL_OK; 740 } 741 742 int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args) 743 { 744 struct cil_class *class = NULL; 745 struct cil_class *common = NULL; 746 struct cil_classcommon *clscom = current->data; 747 struct cil_symtab_datum *class_datum = NULL; 748 struct cil_symtab_datum *common_datum = NULL; 749 int rc = SEPOL_ERR; 750 751 rc = cil_resolve_name(current, clscom->class_str, CIL_SYM_CLASSES, extra_args, &class_datum); 752 if (rc != SEPOL_OK) { 753 goto exit; 754 } 755 756 rc = cil_resolve_name(current, clscom->common_str, CIL_SYM_COMMONS, extra_args, &common_datum); 757 if (rc != SEPOL_OK) { 758 goto exit; 759 } 760 761 class = (struct cil_class *)class_datum; 762 common = (struct cil_class *)common_datum; 763 if (class->common != NULL) { 764 cil_log(CIL_ERR, "class cannot be associeated with more than one common\n"); 765 rc = SEPOL_ERR; 766 goto exit; 767 } 768 769 class->common = common; 770 771 cil_symtab_map(&class->perms, __class_update_perm_values, &common->num_perms); 772 773 class->num_perms += common->num_perms; 774 if (class->num_perms > CIL_PERMS_PER_CLASS) { 775 cil_tree_log(current, CIL_ERR, "Too many permissions in class '%s' when including common permissions", class->datum.name); 776 goto exit; 777 } 778 779 return SEPOL_OK; 780 781 exit: 782 return rc; 783 } 784 785 int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args) 786 { 787 int rc = SEPOL_ERR; 788 struct cil_classmapping *mapping = current->data; 789 struct cil_class *map = NULL; 790 struct cil_perm *mp = NULL; 791 struct cil_symtab_datum *datum = NULL; 792 struct cil_list_item *curr; 793 794 rc = cil_resolve_name(current, mapping->map_class_str, CIL_SYM_CLASSES, extra_args, &datum); 795 if (rc != SEPOL_OK) { 796 goto exit; 797 } 798 map = (struct cil_class*)datum; 799 800 rc = cil_symtab_get_datum(&map->perms, mapping->map_perm_str, &datum); 801 if (rc != SEPOL_OK) { 802 goto exit; 803 } 804 805 mp = (struct cil_perm*)datum; 806 807 rc = cil_resolve_classperms_list(current, mapping->classperms, extra_args); 808 if (rc != SEPOL_OK) { 809 goto exit; 810 } 811 812 if (mp->classperms == NULL) { 813 cil_list_init(&mp->classperms, CIL_CLASSPERMS); 814 } 815 816 cil_list_for_each(curr, mapping->classperms) { 817 cil_list_append(mp->classperms, curr->flavor, curr->data); 818 } 819 820 return SEPOL_OK; 821 822 exit: 823 return rc; 824 } 825 826 int cil_resolve_userrole(struct cil_tree_node *current, void *extra_args) 827 { 828 struct cil_userrole *userrole = current->data; 829 struct cil_symtab_datum *user_datum = NULL; 830 struct cil_symtab_datum *role_datum = NULL; 831 int rc = SEPOL_ERR; 832 833 rc = cil_resolve_name(current, userrole->user_str, CIL_SYM_USERS, extra_args, &user_datum); 834 if (rc != SEPOL_OK) { 835 goto exit; 836 } 837 userrole->user = (struct cil_user*)user_datum; 838 839 rc = cil_resolve_name(current, userrole->role_str, CIL_SYM_ROLES, extra_args, &role_datum); 840 if (rc != SEPOL_OK) { 841 goto exit; 842 } 843 userrole->role = role_datum; 844 845 return SEPOL_OK; 846 847 exit: 848 return rc; 849 } 850 851 int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args) 852 { 853 struct cil_userlevel *usrlvl = current->data; 854 struct cil_symtab_datum *user_datum = NULL; 855 struct cil_symtab_datum *lvl_datum = NULL; 856 struct cil_user *user = NULL; 857 struct cil_tree_node *user_node = NULL; 858 int rc = SEPOL_ERR; 859 860 rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, extra_args, &user_datum); 861 if (rc != SEPOL_OK) { 862 goto exit; 863 } 864 865 user_node = user_datum->nodes->head->data; 866 867 if (user_node->flavor != CIL_USER) { 868 cil_log(CIL_ERR, "Userlevel must be a user\n"); 869 rc = SEPOL_ERR; 870 goto exit; 871 } 872 873 user = (struct cil_user*)user_datum; 874 875 if (usrlvl->level_str != NULL) { 876 rc = cil_resolve_name(current, usrlvl->level_str, CIL_SYM_LEVELS, extra_args, &lvl_datum); 877 if (rc != SEPOL_OK) { 878 goto exit; 879 } 880 usrlvl->level = (struct cil_level*)lvl_datum; 881 user->dftlevel = usrlvl->level; 882 883 /* This could still be an anonymous level even if level_str is set, if level_str is a param_str*/ 884 if (user->dftlevel->datum.name == NULL) { 885 rc = cil_resolve_level(current, user->dftlevel, extra_args); 886 if (rc != SEPOL_OK) { 887 goto exit; 888 } 889 } 890 } else if (usrlvl->level != NULL) { 891 rc = cil_resolve_level(current, usrlvl->level, extra_args); 892 if (rc != SEPOL_OK) { 893 goto exit; 894 } 895 user->dftlevel = usrlvl->level; 896 } 897 898 return SEPOL_OK; 899 900 exit: 901 return rc; 902 } 903 904 int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args) 905 { 906 struct cil_userrange *userrange = current->data; 907 struct cil_symtab_datum *user_datum = NULL; 908 struct cil_symtab_datum *range_datum = NULL; 909 struct cil_user *user = NULL; 910 struct cil_tree_node *user_node = NULL; 911 int rc = SEPOL_ERR; 912 913 rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, extra_args, &user_datum); 914 if (rc != SEPOL_OK) { 915 goto exit; 916 } 917 918 user_node = user_datum->nodes->head->data; 919 920 if (user_node->flavor != CIL_USER) { 921 cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn); 922 rc = SEPOL_ERR; 923 goto exit; 924 } 925 926 user = (struct cil_user*)user_datum; 927 928 if (userrange->range_str != NULL) { 929 rc = cil_resolve_name(current, userrange->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum); 930 if (rc != SEPOL_OK) { 931 goto exit; 932 } 933 userrange->range = (struct cil_levelrange*)range_datum; 934 user->range = userrange->range; 935 936 /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/ 937 if (user->range->datum.name == NULL) { 938 rc = cil_resolve_levelrange(current, user->range, extra_args); 939 if (rc != SEPOL_OK) { 940 goto exit; 941 } 942 } 943 } else if (userrange->range != NULL) { 944 rc = cil_resolve_levelrange(current, userrange->range, extra_args); 945 if (rc != SEPOL_OK) { 946 goto exit; 947 } 948 user->range = userrange->range; 949 } 950 951 return SEPOL_OK; 952 953 exit: 954 return rc; 955 } 956 957 int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args) 958 { 959 struct cil_userprefix *userprefix = current->data; 960 struct cil_symtab_datum *user_datum = NULL; 961 struct cil_tree_node *user_node = NULL; 962 int rc = SEPOL_ERR; 963 964 rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, extra_args, &user_datum); 965 if (rc != SEPOL_OK) { 966 goto exit; 967 } 968 969 user_node = user_datum->nodes->head->data; 970 971 if (user_node->flavor != CIL_USER) { 972 cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn); 973 rc = SEPOL_ERR; 974 goto exit; 975 } 976 977 userprefix->user = (struct cil_user*)user_datum; 978 979 exit: 980 return rc; 981 } 982 983 int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args) 984 { 985 struct cil_selinuxuser *selinuxuser = current->data; 986 struct cil_symtab_datum *user_datum = NULL; 987 struct cil_symtab_datum *lvlrange_datum = NULL; 988 struct cil_tree_node *user_node = NULL; 989 int rc = SEPOL_ERR; 990 991 rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, extra_args, &user_datum); 992 if (rc != SEPOL_OK) { 993 goto exit; 994 } 995 996 user_node = user_datum->nodes->head->data; 997 998 if (user_node->flavor != CIL_USER) { 999 cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn); 1000 rc = SEPOL_ERR; 1001 goto exit; 1002 } 1003 1004 selinuxuser->user = (struct cil_user*)user_datum; 1005 1006 if (selinuxuser->range_str != NULL) { 1007 rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum); 1008 if (rc != SEPOL_OK) { 1009 goto exit; 1010 } 1011 selinuxuser->range = (struct cil_levelrange*)lvlrange_datum; 1012 1013 /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/ 1014 if (selinuxuser->range->datum.name == NULL) { 1015 rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args); 1016 if (rc != SEPOL_OK) { 1017 goto exit; 1018 } 1019 } 1020 } else if (selinuxuser->range != NULL) { 1021 rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args); 1022 if (rc != SEPOL_OK) { 1023 goto exit; 1024 } 1025 } 1026 1027 rc = SEPOL_OK; 1028 exit: 1029 return rc; 1030 } 1031 1032 int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args) 1033 { 1034 struct cil_roletype *roletype = current->data; 1035 struct cil_symtab_datum *role_datum = NULL; 1036 struct cil_symtab_datum *type_datum = NULL; 1037 int rc = SEPOL_ERR; 1038 1039 rc = cil_resolve_name(current, roletype->role_str, CIL_SYM_ROLES, extra_args, &role_datum); 1040 if (rc != SEPOL_OK) { 1041 goto exit; 1042 } 1043 roletype->role = (struct cil_role*)role_datum; 1044 1045 rc = cil_resolve_name(current, roletype->type_str, CIL_SYM_TYPES, extra_args, &type_datum); 1046 if (rc != SEPOL_OK) { 1047 goto exit; 1048 } 1049 roletype->type = (struct cil_type*)type_datum; 1050 1051 return SEPOL_OK; 1052 1053 exit: 1054 return rc; 1055 } 1056 1057 int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args) 1058 { 1059 struct cil_roletransition *roletrans = current->data; 1060 struct cil_symtab_datum *src_datum = NULL; 1061 struct cil_symtab_datum *tgt_datum = NULL; 1062 struct cil_symtab_datum *obj_datum = NULL; 1063 struct cil_symtab_datum *result_datum = NULL; 1064 struct cil_tree_node *node = NULL; 1065 int rc = SEPOL_ERR; 1066 1067 rc = cil_resolve_name(current, roletrans->src_str, CIL_SYM_ROLES, extra_args, &src_datum); 1068 if (rc != SEPOL_OK) { 1069 goto exit; 1070 } 1071 roletrans->src = (struct cil_role*)src_datum; 1072 1073 rc = cil_resolve_name(current, roletrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum); 1074 if (rc != SEPOL_OK) { 1075 goto exit; 1076 } 1077 roletrans->tgt = tgt_datum; 1078 1079 rc = cil_resolve_name(current, roletrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum); 1080 if (rc != SEPOL_OK) { 1081 goto exit; 1082 } 1083 roletrans->obj = (struct cil_class*)obj_datum; 1084 1085 rc = cil_resolve_name(current, roletrans->result_str, CIL_SYM_ROLES, extra_args, &result_datum); 1086 if (rc != SEPOL_OK) { 1087 goto exit; 1088 } 1089 node = result_datum->nodes->head->data; 1090 if (node->flavor != CIL_ROLE) { 1091 rc = SEPOL_ERR; 1092 printf("%i\n", node->flavor); 1093 cil_log(CIL_ERR, "roletransition must result in a role, but %s is a %s\n", roletrans->result_str, cil_node_to_string(node)); 1094 goto exit; 1095 } 1096 roletrans->result = (struct cil_role*)result_datum; 1097 1098 return SEPOL_OK; 1099 1100 exit: 1101 return rc; 1102 } 1103 1104 int cil_resolve_roleallow(struct cil_tree_node *current, void *extra_args) 1105 { 1106 struct cil_roleallow *roleallow = current->data; 1107 struct cil_symtab_datum *src_datum = NULL; 1108 struct cil_symtab_datum *tgt_datum = NULL; 1109 int rc = SEPOL_ERR; 1110 1111 rc = cil_resolve_name(current, roleallow->src_str, CIL_SYM_ROLES, extra_args, &src_datum); 1112 if (rc != SEPOL_OK) { 1113 goto exit; 1114 } 1115 roleallow->src = (struct cil_role*)src_datum; 1116 1117 rc = cil_resolve_name(current, roleallow->tgt_str, CIL_SYM_ROLES, extra_args, &tgt_datum); 1118 if (rc != SEPOL_OK) { 1119 goto exit; 1120 } 1121 roleallow->tgt = (struct cil_role*)tgt_datum; 1122 1123 return SEPOL_OK; 1124 1125 exit: 1126 return rc; 1127 } 1128 1129 int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args) 1130 { 1131 int rc = SEPOL_ERR; 1132 struct cil_roleattributeset *attrroles = current->data; 1133 struct cil_symtab_datum *attr_datum = NULL; 1134 struct cil_tree_node *attr_node = NULL; 1135 struct cil_roleattribute *attr = NULL; 1136 1137 rc = cil_resolve_name(current, attrroles->attr_str, CIL_SYM_ROLES, extra_args, &attr_datum); 1138 if (rc != SEPOL_OK) { 1139 goto exit; 1140 } 1141 attr_node = attr_datum->nodes->head->data; 1142 1143 if (attr_node->flavor != CIL_ROLEATTRIBUTE) { 1144 rc = SEPOL_ERR; 1145 cil_log(CIL_ERR, "Attribute role not an attribute\n"); 1146 goto exit; 1147 } 1148 attr = (struct cil_roleattribute*)attr_datum; 1149 1150 rc = cil_resolve_expr(CIL_ROLEATTRIBUTESET, attrroles->str_expr, &attrroles->datum_expr, current, extra_args); 1151 if (rc != SEPOL_OK) { 1152 goto exit; 1153 } 1154 1155 rc = cil_verify_no_self_reference(attr_datum, attrroles->datum_expr); 1156 if (rc != SEPOL_OK) { 1157 goto exit; 1158 } 1159 1160 if (attr->expr_list == NULL) { 1161 cil_list_init(&attr->expr_list, CIL_ROLEATTRIBUTE); 1162 } 1163 1164 cil_list_append(attr->expr_list, CIL_LIST, attrroles->datum_expr); 1165 1166 return SEPOL_OK; 1167 1168 exit: 1169 return rc; 1170 } 1171 1172 struct cil_ordered_list { 1173 int merged; 1174 struct cil_list *list; 1175 struct cil_tree_node *node; 1176 }; 1177 1178 void __cil_ordered_list_init(struct cil_ordered_list **ordered) 1179 { 1180 *ordered = cil_malloc(sizeof(**ordered)); 1181 1182 (*ordered)->merged = CIL_FALSE; 1183 (*ordered)->list = NULL; 1184 (*ordered)->node = NULL; 1185 } 1186 1187 void __cil_ordered_list_destroy(struct cil_ordered_list **ordered) 1188 { 1189 cil_list_destroy(&(*ordered)->list, CIL_FALSE); 1190 (*ordered)->node = NULL; 1191 free(*ordered); 1192 *ordered = NULL; 1193 } 1194 1195 void __cil_ordered_lists_destroy(struct cil_list **ordered_lists) 1196 { 1197 struct cil_list_item *item = NULL; 1198 1199 if (ordered_lists == NULL || *ordered_lists == NULL) { 1200 return; 1201 } 1202 1203 item = (*ordered_lists)->head; 1204 while (item != NULL) { 1205 struct cil_list_item *next = item->next; 1206 struct cil_ordered_list *ordered = item->data; 1207 __cil_ordered_list_destroy(&ordered); 1208 free(item); 1209 item = next; 1210 } 1211 free(*ordered_lists); 1212 *ordered_lists = NULL; 1213 } 1214 1215 void __cil_ordered_lists_reset(struct cil_list **ordered_lists) 1216 { 1217 __cil_ordered_lists_destroy(ordered_lists); 1218 cil_list_init(ordered_lists, CIL_LIST_ITEM); 1219 } 1220 1221 struct cil_list_item *__cil_ordered_item_insert(struct cil_list *old, struct cil_list_item *curr, struct cil_list_item *item) 1222 { 1223 if (item->flavor == CIL_SID) { 1224 struct cil_sid *sid = item->data; 1225 if (sid->ordered == CIL_TRUE) { 1226 cil_log(CIL_ERR, "SID %s has already been merged into the ordered list\n", sid->datum.name); 1227 return NULL; 1228 } 1229 sid->ordered = CIL_TRUE; 1230 } else if (item->flavor == CIL_CLASS) { 1231 struct cil_class *class = item->data; 1232 if (class->ordered == CIL_TRUE) { 1233 cil_log(CIL_ERR, "Class %s has already been merged into the ordered list\n", class->datum.name); 1234 return NULL; 1235 } 1236 class->ordered = CIL_TRUE; 1237 } else if (item->flavor == CIL_CAT) { 1238 struct cil_cat *cat = item->data; 1239 if (cat->ordered == CIL_TRUE) { 1240 cil_log(CIL_ERR, "Category %s has already been merged into the ordered list\n", cat->datum.name); 1241 return NULL; 1242 } 1243 cat->ordered = CIL_TRUE; 1244 } else if (item->flavor == CIL_SENS) { 1245 struct cil_sens *sens = item->data; 1246 if (sens->ordered == CIL_TRUE) { 1247 cil_log(CIL_ERR, "Sensitivity %s has already been merged into the ordered list\n", sens->datum.name); 1248 return NULL; 1249 } 1250 sens->ordered = CIL_TRUE; 1251 } 1252 1253 return cil_list_insert(old, curr, item->flavor, item->data); 1254 } 1255 1256 int __cil_ordered_list_insert(struct cil_list *old, struct cil_list_item *ocurr, struct cil_list_item *nstart, struct cil_list_item *nstop) 1257 { 1258 struct cil_list_item *ncurr = NULL; 1259 1260 for (ncurr = nstart; ncurr != nstop; ncurr = ncurr->next) { 1261 ocurr = __cil_ordered_item_insert(old, ocurr, ncurr); 1262 if (ocurr == NULL) { 1263 return SEPOL_ERR; 1264 } 1265 } 1266 return SEPOL_OK; 1267 } 1268 1269 struct cil_list_item *__cil_ordered_find_match(struct cil_list_item *t, struct cil_list_item *i) 1270 { 1271 while (i) { 1272 if (i->data == t->data) { 1273 return i; 1274 } 1275 i = i->next; 1276 } 1277 return NULL; 1278 } 1279 1280 int __cil_ordered_lists_merge(struct cil_list *old, struct cil_list *new) 1281 { 1282 struct cil_list_item *omatch = NULL; 1283 struct cil_list_item *ofirst = old->head; 1284 struct cil_list_item *ocurr = NULL; 1285 struct cil_list_item *oprev = NULL; 1286 struct cil_list_item *nmatch = NULL; 1287 struct cil_list_item *nfirst = new->head; 1288 struct cil_list_item *ncurr = NULL; 1289 int rc = SEPOL_ERR; 1290 1291 if (nfirst == NULL) { 1292 return SEPOL_OK; 1293 } 1294 1295 if (ofirst == NULL) { 1296 /* First list added */ 1297 rc = __cil_ordered_list_insert(old, NULL, nfirst, NULL); 1298 return rc; 1299 } 1300 1301 /* Find a match between the new list and the old one */ 1302 for (nmatch = nfirst; nmatch; nmatch = nmatch->next) { 1303 omatch = __cil_ordered_find_match(nmatch, ofirst); 1304 if (omatch) { 1305 break; 1306 } 1307 } 1308 1309 if (!nmatch) { 1310 /* List cannot be merged yet */ 1311 return SEPOL_ERR; 1312 } 1313 1314 if (nmatch != nfirst && omatch != ofirst) { 1315 /* Potential ordering conflict--try again later */ 1316 return SEPOL_ERR; 1317 } 1318 1319 if (nmatch != nfirst) { 1320 /* Prepend the beginning of the new list up to the first match to the old list */ 1321 rc = __cil_ordered_list_insert(old, NULL, nfirst, nmatch); 1322 if (rc != SEPOL_OK) { 1323 return rc; 1324 } 1325 } 1326 1327 /* In the overlapping protion, add items from the new list not in the old list */ 1328 ncurr = nmatch->next; 1329 ocurr = omatch->next; 1330 oprev = omatch; 1331 while (ncurr && ocurr) { 1332 if (ncurr->data == ocurr->data) { 1333 oprev = ocurr; 1334 ocurr = ocurr->next; 1335 ncurr = ncurr->next; 1336 } else { 1337 /* Handle gap in old: old = (A C) new = (A B C) */ 1338 nmatch = __cil_ordered_find_match(ocurr, ncurr->next); 1339 if (nmatch) { 1340 rc = __cil_ordered_list_insert(old, oprev, ncurr, nmatch); 1341 if (rc != SEPOL_OK) { 1342 return rc; 1343 } 1344 oprev = ocurr; 1345 ocurr = ocurr->next; 1346 ncurr = nmatch->next; 1347 continue; 1348 } 1349 /* Handle gap in new: old = (A B C) new = (A C) */ 1350 omatch = __cil_ordered_find_match(ncurr, ocurr->next); 1351 if (omatch) { 1352 /* Nothing to insert, just skip */ 1353 oprev = omatch; 1354 ocurr = omatch->next; 1355 ncurr = ncurr->next; 1356 continue; 1357 } else { 1358 return SEPOL_ERR; 1359 } 1360 } 1361 } 1362 1363 if (ncurr) { 1364 /* Add the rest of the items from the new list */ 1365 rc = __cil_ordered_list_insert(old, old->tail, ncurr, NULL); 1366 if (rc != SEPOL_OK) { 1367 return rc; 1368 } 1369 } 1370 1371 return SEPOL_OK; 1372 } 1373 1374 static int insert_unordered(struct cil_list *merged, struct cil_list *unordered) 1375 { 1376 struct cil_list_item *curr = NULL; 1377 struct cil_ordered_list *unordered_list = NULL; 1378 struct cil_list_item *item = NULL; 1379 struct cil_list_item *ret = NULL; 1380 int rc = SEPOL_ERR; 1381 1382 cil_list_for_each(curr, unordered) { 1383 unordered_list = curr->data; 1384 1385 cil_list_for_each(item, unordered_list->list) { 1386 if (cil_list_contains(merged, item->data)) { 1387 /* item was declared in an ordered statement, which supercedes 1388 * all unordered statements */ 1389 if (item->flavor == CIL_CLASS) { 1390 cil_log(CIL_WARN, "Ignoring '%s' as it has already been declared in classorder.\n", ((struct cil_class*)(item->data))->datum.name); 1391 } 1392 continue; 1393 } 1394 1395 ret = __cil_ordered_item_insert(merged, merged->tail, item); 1396 if (ret == NULL) { 1397 rc = SEPOL_ERR; 1398 goto exit; 1399 } 1400 } 1401 } 1402 1403 rc = SEPOL_OK; 1404 1405 exit: 1406 return rc; 1407 } 1408 1409 struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists, struct cil_list **unordered_lists) 1410 { 1411 struct cil_list *composite = NULL; 1412 struct cil_list_item *curr = NULL; 1413 int changed = CIL_TRUE; 1414 int waiting = 1; 1415 int rc = SEPOL_ERR; 1416 1417 cil_list_init(&composite, CIL_LIST_ITEM); 1418 1419 while (waiting && changed == CIL_TRUE) { 1420 changed = CIL_FALSE; 1421 waiting = 0; 1422 cil_list_for_each(curr, *ordered_lists) { 1423 struct cil_ordered_list *ordered_list = curr->data; 1424 if (ordered_list->merged == CIL_FALSE) { 1425 rc = __cil_ordered_lists_merge(composite, ordered_list->list); 1426 if (rc != SEPOL_OK) { 1427 /* Can't merge yet */ 1428 waiting++; 1429 } else { 1430 ordered_list->merged = CIL_TRUE; 1431 changed = CIL_TRUE; 1432 } 1433 } 1434 } 1435 if (waiting > 0 && changed == CIL_FALSE) { 1436 cil_list_for_each(curr, *ordered_lists) { 1437 struct cil_ordered_list *ordered_list = curr->data; 1438 if (ordered_list->merged == CIL_FALSE) { 1439 cil_tree_log(ordered_list->node, CIL_ERR, "Unable to merge ordered list"); 1440 } 1441 } 1442 goto exit; 1443 } 1444 } 1445 1446 if (unordered_lists != NULL) { 1447 rc = insert_unordered(composite, *unordered_lists); 1448 if (rc != SEPOL_OK) { 1449 goto exit; 1450 } 1451 } 1452 1453 __cil_ordered_lists_destroy(ordered_lists); 1454 __cil_ordered_lists_destroy(unordered_lists); 1455 1456 return composite; 1457 1458 exit: 1459 __cil_ordered_lists_destroy(ordered_lists); 1460 __cil_ordered_lists_destroy(unordered_lists); 1461 cil_list_destroy(&composite, CIL_FALSE); 1462 return NULL; 1463 } 1464 1465 int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args) 1466 { 1467 struct cil_args_resolve *args = extra_args; 1468 struct cil_list *classorder_list = args->classorder_lists; 1469 struct cil_list *unordered_classorder_list = args->unordered_classorder_lists; 1470 struct cil_classorder *classorder = current->data; 1471 struct cil_list *new = NULL; 1472 struct cil_list_item *curr = NULL; 1473 struct cil_symtab_datum *datum = NULL; 1474 struct cil_ordered_list *class_list = NULL; 1475 int rc = SEPOL_ERR; 1476 int unordered = CIL_FALSE; 1477 1478 cil_list_init(&new, CIL_CLASSORDER); 1479 1480 cil_list_for_each(curr, classorder->class_list_str) { 1481 if (curr->data == CIL_KEY_UNORDERED) { 1482 unordered = CIL_TRUE; 1483 continue; 1484 } 1485 1486 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum); 1487 if (rc != SEPOL_OK) { 1488 cil_log(CIL_ERR, "Failed to resolve class %s in classorder\n", (char *)curr->data); 1489 goto exit; 1490 } 1491 cil_list_append(new, CIL_CLASS, datum); 1492 } 1493 1494 __cil_ordered_list_init(&class_list); 1495 class_list->list = new; 1496 class_list->node = current; 1497 if (unordered) { 1498 cil_list_append(unordered_classorder_list, CIL_CLASSORDER, class_list); 1499 } else { 1500 cil_list_append(classorder_list, CIL_CLASSORDER, class_list); 1501 } 1502 1503 return SEPOL_OK; 1504 1505 exit: 1506 cil_list_destroy(&new, CIL_FALSE); 1507 return rc; 1508 } 1509 1510 int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args) 1511 { 1512 struct cil_args_resolve *args = extra_args; 1513 struct cil_list *sidorder_list = args->sidorder_lists; 1514 struct cil_sidorder *sidorder = current->data; 1515 struct cil_list *new = NULL; 1516 struct cil_list_item *curr = NULL; 1517 struct cil_symtab_datum *datum = NULL; 1518 struct cil_ordered_list *ordered = NULL; 1519 int rc = SEPOL_ERR; 1520 1521 cil_list_init(&new, CIL_SIDORDER); 1522 1523 cil_list_for_each(curr, sidorder->sid_list_str) { 1524 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SIDS, extra_args, &datum); 1525 if (rc != SEPOL_OK) { 1526 cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data); 1527 goto exit; 1528 } 1529 cil_list_append(new, CIL_SID, datum); 1530 } 1531 1532 __cil_ordered_list_init(&ordered); 1533 ordered->list = new; 1534 ordered->node = current; 1535 cil_list_append(sidorder_list, CIL_SIDORDER, ordered); 1536 1537 return SEPOL_OK; 1538 1539 exit: 1540 return rc; 1541 } 1542 1543 void cil_set_cat_values(struct cil_list *ordered_cats, struct cil_db *db) 1544 { 1545 struct cil_list_item *curr; 1546 int v = 0; 1547 1548 cil_list_for_each(curr, ordered_cats) { 1549 struct cil_cat *cat = curr->data; 1550 cat->value = v; 1551 v++; 1552 } 1553 1554 db->num_cats = v; 1555 } 1556 1557 int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args) 1558 { 1559 struct cil_args_resolve *args = extra_args; 1560 struct cil_list *catorder_list = args->catorder_lists; 1561 struct cil_catorder *catorder = current->data; 1562 struct cil_list *new = NULL; 1563 struct cil_list_item *curr = NULL; 1564 struct cil_symtab_datum *cat_datum; 1565 struct cil_cat *cat = NULL; 1566 struct cil_ordered_list *ordered = NULL; 1567 int rc = SEPOL_ERR; 1568 1569 cil_list_init(&new, CIL_CATORDER); 1570 1571 cil_list_for_each(curr, catorder->cat_list_str) { 1572 struct cil_tree_node *node = NULL; 1573 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, extra_args, &cat_datum); 1574 if (rc != SEPOL_OK) { 1575 cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data); 1576 goto exit; 1577 } 1578 node = cat_datum->nodes->head->data; 1579 if (node->flavor != CIL_CAT) { 1580 cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", cat_datum->name); 1581 rc = SEPOL_ERR; 1582 goto exit; 1583 } 1584 cat = (struct cil_cat *)cat_datum; 1585 cil_list_append(new, CIL_CAT, cat); 1586 } 1587 1588 __cil_ordered_list_init(&ordered); 1589 ordered->list = new; 1590 ordered->node = current; 1591 cil_list_append(catorder_list, CIL_CATORDER, ordered); 1592 1593 return SEPOL_OK; 1594 1595 exit: 1596 return rc; 1597 } 1598 1599 int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args) 1600 { 1601 struct cil_args_resolve *args = extra_args; 1602 struct cil_list *sensitivityorder_list = args->sensitivityorder_lists; 1603 struct cil_sensorder *sensorder = current->data; 1604 struct cil_list *new = NULL; 1605 struct cil_list_item *curr = NULL; 1606 struct cil_symtab_datum *datum = NULL; 1607 struct cil_ordered_list *ordered = NULL; 1608 int rc = SEPOL_ERR; 1609 1610 cil_list_init(&new, CIL_LIST_ITEM); 1611 1612 cil_list_for_each(curr, sensorder->sens_list_str) { 1613 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, extra_args, &datum); 1614 if (rc != SEPOL_OK) { 1615 cil_log(CIL_ERR, "Failed to resolve sensitivty %s in sensitivityorder\n", (char *)curr->data); 1616 goto exit; 1617 } 1618 cil_list_append(new, CIL_SENS, datum); 1619 } 1620 1621 __cil_ordered_list_init(&ordered); 1622 ordered->list = new; 1623 ordered->node = current; 1624 cil_list_append(sensitivityorder_list, CIL_SENSITIVITYORDER, ordered); 1625 1626 return SEPOL_OK; 1627 1628 exit: 1629 return rc; 1630 } 1631 1632 int cil_resolve_cats(struct cil_tree_node *current, struct cil_cats *cats, void *extra_args) 1633 { 1634 int rc = SEPOL_ERR; 1635 1636 rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, extra_args); 1637 if (rc != SEPOL_OK) { 1638 goto exit; 1639 } 1640 1641 return SEPOL_OK; 1642 1643 exit: 1644 return rc; 1645 } 1646 1647 1648 int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args) 1649 { 1650 int rc = SEPOL_ERR; 1651 1652 rc = cil_resolve_cats(current, catset->cats, extra_args); 1653 if (rc != SEPOL_OK) { 1654 goto exit; 1655 } 1656 1657 rc = cil_verify_no_self_reference((struct cil_symtab_datum *)catset, catset->cats->datum_expr); 1658 if (rc != SEPOL_OK) { 1659 cil_list_destroy(&catset->cats->datum_expr, CIL_FALSE); 1660 goto exit; 1661 } 1662 1663 exit: 1664 return rc; 1665 } 1666 1667 int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args) 1668 { 1669 int rc = SEPOL_ERR; 1670 struct cil_senscat *senscat = current->data; 1671 struct cil_symtab_datum *sens_datum; 1672 struct cil_sens *sens = NULL; 1673 1674 rc = cil_resolve_name(current, (char*)senscat->sens_str, CIL_SYM_SENS, extra_args, &sens_datum); 1675 if (rc != SEPOL_OK) { 1676 cil_log(CIL_ERR, "Failed to find sensitivity\n"); 1677 goto exit; 1678 } 1679 1680 rc = cil_resolve_cats(current, senscat->cats, extra_args); 1681 if (rc != SEPOL_OK) { 1682 goto exit; 1683 } 1684 1685 sens = (struct cil_sens *)sens_datum; 1686 1687 if (sens->cats_list == NULL ) { 1688 cil_list_init(&sens->cats_list, CIL_CAT); 1689 } 1690 1691 cil_list_append(sens->cats_list, CIL_CAT, senscat->cats); 1692 1693 return SEPOL_OK; 1694 1695 exit: 1696 return rc; 1697 } 1698 1699 int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, void *extra_args) 1700 { 1701 struct cil_symtab_datum *sens_datum = NULL; 1702 int rc = SEPOL_ERR; 1703 1704 rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, extra_args, &sens_datum); 1705 if (rc != SEPOL_OK) { 1706 cil_log(CIL_ERR, "Failed to find sensitivity\n"); 1707 goto exit; 1708 } 1709 1710 level->sens = (struct cil_sens *)sens_datum; 1711 1712 if (level->cats != NULL) { 1713 rc = cil_resolve_cats(current, level->cats, extra_args); 1714 if (rc != SEPOL_OK) { 1715 goto exit; 1716 } 1717 } 1718 1719 return SEPOL_OK; 1720 1721 exit: 1722 return rc; 1723 } 1724 1725 int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *lvlrange, void *extra_args) 1726 { 1727 struct cil_symtab_datum *low_datum = NULL; 1728 struct cil_symtab_datum *high_datum = NULL; 1729 int rc = SEPOL_ERR; 1730 1731 if (lvlrange->low_str != NULL) { 1732 rc = cil_resolve_name(current, lvlrange->low_str, CIL_SYM_LEVELS, extra_args, &low_datum); 1733 if (rc != SEPOL_OK) { 1734 goto exit; 1735 } 1736 lvlrange->low = (struct cil_level*)low_datum; 1737 1738 /* This could still be an anonymous level even if low_str is set, if low_str is a param_str */ 1739 if (lvlrange->low->datum.name == NULL) { 1740 rc = cil_resolve_level(current, lvlrange->low, extra_args); 1741 if (rc != SEPOL_OK) { 1742 goto exit; 1743 } 1744 } 1745 } else if (lvlrange->low != NULL) { 1746 rc = cil_resolve_level(current, lvlrange->low, extra_args); 1747 if (rc != SEPOL_OK) { 1748 goto exit; 1749 } 1750 } 1751 1752 if (lvlrange->high_str != NULL) { 1753 rc = cil_resolve_name(current, lvlrange->high_str, CIL_SYM_LEVELS, extra_args, &high_datum); 1754 if (rc != SEPOL_OK) { 1755 goto exit; 1756 } 1757 lvlrange->high = (struct cil_level*)high_datum; 1758 1759 /* This could still be an anonymous level even if high_str is set, if high_str is a param_str */ 1760 if (lvlrange->high->datum.name == NULL) { 1761 rc = cil_resolve_level(current, lvlrange->high, extra_args); 1762 if (rc != SEPOL_OK) { 1763 goto exit; 1764 } 1765 } 1766 } else if (lvlrange->high != NULL) { 1767 rc = cil_resolve_level(current, lvlrange->high, extra_args); 1768 if (rc != SEPOL_OK) { 1769 goto exit; 1770 } 1771 } 1772 1773 return SEPOL_OK; 1774 1775 exit: 1776 return rc; 1777 } 1778 1779 int cil_resolve_constrain(struct cil_tree_node *current, void *extra_args) 1780 { 1781 struct cil_constrain *cons = current->data; 1782 int rc = SEPOL_ERR; 1783 1784 rc = cil_resolve_classperms_list(current, cons->classperms, extra_args); 1785 if (rc != SEPOL_OK) { 1786 goto exit; 1787 } 1788 1789 rc = cil_resolve_expr(CIL_CONSTRAIN, cons->str_expr, &cons->datum_expr, current, extra_args); 1790 if (rc != SEPOL_OK) { 1791 goto exit; 1792 } 1793 1794 return SEPOL_OK; 1795 1796 exit: 1797 return rc; 1798 } 1799 1800 int cil_resolve_validatetrans(struct cil_tree_node *current, void *extra_args) 1801 { 1802 struct cil_validatetrans *validtrans = current->data; 1803 struct cil_args_resolve *args = extra_args; 1804 struct cil_symtab_datum *class_datum = NULL; 1805 int rc = SEPOL_ERR; 1806 1807 rc = cil_resolve_name(current, validtrans->class_str, CIL_SYM_CLASSES, args, &class_datum); 1808 if (rc != SEPOL_OK) { 1809 goto exit; 1810 } 1811 validtrans->class = (struct cil_class*)class_datum; 1812 1813 rc = cil_resolve_expr(CIL_VALIDATETRANS, validtrans->str_expr, &validtrans->datum_expr, current, extra_args); 1814 if (rc != SEPOL_OK) { 1815 goto exit; 1816 } 1817 1818 return SEPOL_OK; 1819 1820 exit: 1821 return rc; 1822 } 1823 1824 int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, void *extra_args) 1825 { 1826 struct cil_symtab_datum *user_datum = NULL; 1827 struct cil_symtab_datum *role_datum = NULL; 1828 struct cil_symtab_datum *type_datum = NULL; 1829 struct cil_tree_node *node = NULL; 1830 struct cil_symtab_datum *lvlrange_datum = NULL; 1831 1832 int rc = SEPOL_ERR; 1833 1834 rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, extra_args, &user_datum); 1835 if (rc != SEPOL_OK) { 1836 goto exit; 1837 } 1838 1839 node = user_datum->nodes->head->data; 1840 1841 if (node->flavor != CIL_USER) { 1842 cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn); 1843 rc = SEPOL_ERR; 1844 goto exit; 1845 } 1846 1847 context->user = (struct cil_user*)user_datum; 1848 1849 rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, extra_args, &role_datum); 1850 if (rc != SEPOL_OK) { 1851 goto exit; 1852 } 1853 1854 node = role_datum->nodes->head->data; 1855 if (node->flavor != CIL_ROLE) { 1856 rc = SEPOL_ERR; 1857 cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn); 1858 goto exit; 1859 } 1860 1861 context->role = (struct cil_role*)role_datum; 1862 1863 rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, extra_args, &type_datum); 1864 if (rc != SEPOL_OK) { 1865 goto exit; 1866 } 1867 1868 node = type_datum->nodes->head->data; 1869 1870 if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) { 1871 rc = SEPOL_ERR; 1872 cil_log(CIL_ERR, "Type not a type or type alias\n"); 1873 goto exit; 1874 } 1875 context->type = type_datum; 1876 1877 if (context->range_str != NULL) { 1878 rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum); 1879 if (rc != SEPOL_OK) { 1880 goto exit; 1881 } 1882 context->range = (struct cil_levelrange*)lvlrange_datum; 1883 1884 /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/ 1885 if (context->range->datum.name == NULL) { 1886 rc = cil_resolve_levelrange(current, context->range, extra_args); 1887 if (rc != SEPOL_OK) { 1888 goto exit; 1889 } 1890 } 1891 } else if (context->range != NULL) { 1892 rc = cil_resolve_levelrange(current, context->range, extra_args); 1893 if (rc != SEPOL_OK) { 1894 goto exit; 1895 } 1896 } 1897 1898 return SEPOL_OK; 1899 1900 exit: 1901 return rc; 1902 } 1903 1904 int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args) 1905 { 1906 struct cil_filecon *filecon = current->data; 1907 struct cil_symtab_datum *context_datum = NULL; 1908 int rc = SEPOL_ERR; 1909 1910 if (filecon->context_str != NULL) { 1911 rc = cil_resolve_name(current, filecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 1912 if (rc != SEPOL_OK) { 1913 return rc; 1914 } 1915 filecon->context = (struct cil_context*)context_datum; 1916 } else if (filecon->context != NULL) { 1917 rc = cil_resolve_context(current, filecon->context, extra_args); 1918 if (rc != SEPOL_OK) { 1919 return rc; 1920 } 1921 } 1922 1923 return SEPOL_OK; 1924 } 1925 1926 int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args) 1927 { 1928 struct cil_portcon *portcon = current->data; 1929 struct cil_symtab_datum *context_datum = NULL; 1930 int rc = SEPOL_ERR; 1931 1932 if (portcon->context_str != NULL) { 1933 rc = cil_resolve_name(current, portcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 1934 if (rc != SEPOL_OK) { 1935 goto exit; 1936 } 1937 portcon->context = (struct cil_context*)context_datum; 1938 } else { 1939 rc = cil_resolve_context(current, portcon->context, extra_args); 1940 if (rc != SEPOL_OK) { 1941 goto exit; 1942 } 1943 } 1944 1945 return SEPOL_OK; 1946 1947 exit: 1948 return rc; 1949 } 1950 1951 int cil_resolve_genfscon(struct cil_tree_node *current, void *extra_args) 1952 { 1953 struct cil_genfscon *genfscon = current->data; 1954 struct cil_symtab_datum *context_datum = NULL; 1955 int rc = SEPOL_ERR; 1956 1957 if (genfscon->context_str != NULL) { 1958 rc = cil_resolve_name(current, genfscon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 1959 if (rc != SEPOL_OK) { 1960 goto exit; 1961 } 1962 genfscon->context = (struct cil_context*)context_datum; 1963 } else { 1964 rc = cil_resolve_context(current, genfscon->context, extra_args); 1965 if (rc != SEPOL_OK) { 1966 goto exit; 1967 } 1968 } 1969 1970 return SEPOL_OK; 1971 1972 exit: 1973 return rc; 1974 } 1975 1976 int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args) 1977 { 1978 struct cil_nodecon *nodecon = current->data; 1979 struct cil_symtab_datum *addr_datum = NULL; 1980 struct cil_symtab_datum *mask_datum = NULL; 1981 struct cil_symtab_datum *context_datum = NULL; 1982 int rc = SEPOL_ERR; 1983 1984 if (nodecon->addr_str != NULL) { 1985 rc = cil_resolve_name(current, nodecon->addr_str, CIL_SYM_IPADDRS, extra_args, &addr_datum); 1986 if (rc != SEPOL_OK) { 1987 goto exit; 1988 } 1989 nodecon->addr = (struct cil_ipaddr*)addr_datum; 1990 } 1991 1992 if (nodecon->mask_str != NULL) { 1993 rc = cil_resolve_name(current, nodecon->mask_str, CIL_SYM_IPADDRS, extra_args, &mask_datum); 1994 if (rc != SEPOL_OK) { 1995 goto exit; 1996 } 1997 nodecon->mask = (struct cil_ipaddr*)mask_datum; 1998 } 1999 2000 if (nodecon->context_str != NULL) { 2001 rc = cil_resolve_name(current, nodecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2002 if (rc != SEPOL_OK) { 2003 goto exit; 2004 } 2005 nodecon->context = (struct cil_context*)context_datum; 2006 } else { 2007 rc = cil_resolve_context(current, nodecon->context, extra_args); 2008 if (rc != SEPOL_OK) { 2009 goto exit; 2010 } 2011 } 2012 2013 if (nodecon->addr->family != nodecon->mask->family) { 2014 cil_log(CIL_ERR, "Nodecon ip address not in the same family\n"); 2015 rc = SEPOL_ERR; 2016 goto exit; 2017 } 2018 2019 2020 return SEPOL_OK; 2021 2022 exit: 2023 return rc; 2024 } 2025 2026 int cil_resolve_netifcon(struct cil_tree_node *current, void *extra_args) 2027 { 2028 struct cil_netifcon *netifcon = current->data; 2029 struct cil_symtab_datum *ifcon_datum = NULL; 2030 struct cil_symtab_datum *packcon_datum = NULL; 2031 2032 int rc = SEPOL_ERR; 2033 2034 if (netifcon->if_context_str != NULL) { 2035 rc = cil_resolve_name(current, netifcon->if_context_str, CIL_SYM_CONTEXTS, extra_args, &ifcon_datum); 2036 if (rc != SEPOL_OK) { 2037 goto exit; 2038 } 2039 netifcon->if_context = (struct cil_context*)ifcon_datum; 2040 } else { 2041 rc = cil_resolve_context(current, netifcon->if_context, extra_args); 2042 if (rc != SEPOL_OK) { 2043 goto exit; 2044 } 2045 } 2046 2047 if (netifcon->packet_context_str != NULL) { 2048 rc = cil_resolve_name(current, netifcon->packet_context_str, CIL_SYM_CONTEXTS, extra_args, &packcon_datum); 2049 if (rc != SEPOL_OK) { 2050 goto exit; 2051 } 2052 netifcon->packet_context = (struct cil_context*)packcon_datum; 2053 } else { 2054 rc = cil_resolve_context(current, netifcon->packet_context, extra_args); 2055 if (rc != SEPOL_OK) { 2056 goto exit; 2057 } 2058 } 2059 return SEPOL_OK; 2060 2061 exit: 2062 return rc; 2063 } 2064 2065 int cil_resolve_pirqcon(struct cil_tree_node *current, void *extra_args) 2066 { 2067 struct cil_pirqcon *pirqcon = current->data; 2068 struct cil_symtab_datum *context_datum = NULL; 2069 int rc = SEPOL_ERR; 2070 2071 if (pirqcon->context_str != NULL) { 2072 rc = cil_resolve_name(current, pirqcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2073 if (rc != SEPOL_OK) { 2074 goto exit; 2075 } 2076 pirqcon->context = (struct cil_context*)context_datum; 2077 } else { 2078 rc = cil_resolve_context(current, pirqcon->context, extra_args); 2079 if (rc != SEPOL_OK) { 2080 goto exit; 2081 } 2082 } 2083 2084 return SEPOL_OK; 2085 2086 exit: 2087 return rc; 2088 } 2089 2090 int cil_resolve_iomemcon(struct cil_tree_node *current, void *extra_args) 2091 { 2092 struct cil_iomemcon *iomemcon = current->data; 2093 struct cil_symtab_datum *context_datum = NULL; 2094 int rc = SEPOL_ERR; 2095 2096 if (iomemcon->context_str != NULL) { 2097 rc = cil_resolve_name(current, iomemcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2098 if (rc != SEPOL_OK) { 2099 goto exit; 2100 } 2101 iomemcon->context = (struct cil_context*)context_datum; 2102 } else { 2103 rc = cil_resolve_context(current, iomemcon->context, extra_args); 2104 if (rc != SEPOL_OK) { 2105 goto exit; 2106 } 2107 } 2108 2109 return SEPOL_OK; 2110 2111 exit: 2112 return rc; 2113 } 2114 2115 int cil_resolve_ioportcon(struct cil_tree_node *current, void *extra_args) 2116 { 2117 struct cil_ioportcon *ioportcon = current->data; 2118 struct cil_symtab_datum *context_datum = NULL; 2119 int rc = SEPOL_ERR; 2120 2121 if (ioportcon->context_str != NULL) { 2122 rc = cil_resolve_name(current, ioportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2123 if (rc != SEPOL_OK) { 2124 goto exit; 2125 } 2126 ioportcon->context = (struct cil_context*)context_datum; 2127 } else { 2128 rc = cil_resolve_context(current, ioportcon->context, extra_args); 2129 if (rc != SEPOL_OK) { 2130 goto exit; 2131 } 2132 } 2133 2134 return SEPOL_OK; 2135 2136 exit: 2137 return rc; 2138 } 2139 2140 int cil_resolve_pcidevicecon(struct cil_tree_node *current, void *extra_args) 2141 { 2142 struct cil_pcidevicecon *pcidevicecon = current->data; 2143 struct cil_symtab_datum *context_datum = NULL; 2144 int rc = SEPOL_ERR; 2145 2146 if (pcidevicecon->context_str != NULL) { 2147 rc = cil_resolve_name(current, pcidevicecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2148 if (rc != SEPOL_OK) { 2149 goto exit; 2150 } 2151 pcidevicecon->context = (struct cil_context*)context_datum; 2152 } else { 2153 rc = cil_resolve_context(current, pcidevicecon->context, extra_args); 2154 if (rc != SEPOL_OK) { 2155 goto exit; 2156 } 2157 } 2158 2159 return SEPOL_OK; 2160 2161 exit: 2162 return rc; 2163 } 2164 2165 int cil_resolve_devicetreecon(struct cil_tree_node *current, void *extra_args) 2166 { 2167 struct cil_devicetreecon *devicetreecon = current->data; 2168 struct cil_symtab_datum *context_datum = NULL; 2169 int rc = SEPOL_ERR; 2170 2171 if (devicetreecon->context_str != NULL) { 2172 rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2173 if (rc != SEPOL_OK) { 2174 goto exit; 2175 } 2176 devicetreecon->context = (struct cil_context*)context_datum; 2177 } else { 2178 rc = cil_resolve_context(current, devicetreecon->context, extra_args); 2179 if (rc != SEPOL_OK) { 2180 goto exit; 2181 } 2182 } 2183 2184 return SEPOL_OK; 2185 2186 exit: 2187 return rc; 2188 } 2189 2190 int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args) 2191 { 2192 struct cil_fsuse *fsuse = current->data; 2193 struct cil_symtab_datum *context_datum = NULL; 2194 int rc = SEPOL_ERR; 2195 2196 if (fsuse->context_str != NULL) { 2197 rc = cil_resolve_name(current, fsuse->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2198 if (rc != SEPOL_OK) { 2199 goto exit; 2200 } 2201 fsuse->context = (struct cil_context*)context_datum; 2202 } else { 2203 rc = cil_resolve_context(current, fsuse->context, extra_args); 2204 if (rc != SEPOL_OK) { 2205 goto exit; 2206 } 2207 } 2208 2209 return SEPOL_OK; 2210 2211 exit: 2212 return rc; 2213 } 2214 2215 int cil_resolve_sidcontext(struct cil_tree_node *current, void *extra_args) 2216 { 2217 struct cil_sidcontext *sidcon = current->data; 2218 struct cil_symtab_datum *sid_datum = NULL; 2219 struct cil_symtab_datum *context_datum = NULL; 2220 struct cil_sid *sid = NULL; 2221 2222 int rc = SEPOL_ERR; 2223 2224 rc = cil_resolve_name(current, sidcon->sid_str, CIL_SYM_SIDS, extra_args, &sid_datum); 2225 if (rc != SEPOL_OK) { 2226 goto exit; 2227 } 2228 sid = (struct cil_sid*)sid_datum; 2229 2230 if (sidcon->context_str != NULL) { 2231 rc = cil_resolve_name(current, sidcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); 2232 if (rc != SEPOL_OK) { 2233 goto exit; 2234 } 2235 sidcon->context = (struct cil_context*)context_datum; 2236 } else if (sidcon->context != NULL) { 2237 rc = cil_resolve_context(current, sidcon->context, extra_args); 2238 if (rc != SEPOL_OK) { 2239 goto exit; 2240 } 2241 } 2242 2243 if (sid->context != NULL) { 2244 cil_log(CIL_ERR, "sid's cannot be associated with more than one context\n"); 2245 rc = SEPOL_ERR; 2246 goto exit; 2247 } 2248 2249 sid->context = sidcon->context; 2250 2251 return SEPOL_OK; 2252 2253 exit: 2254 return rc; 2255 } 2256 2257 int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_args) 2258 { 2259 struct cil_blockinherit *inherit = current->data; 2260 struct cil_symtab_datum *block_datum = NULL; 2261 struct cil_tree_node *node = NULL; 2262 int rc = SEPOL_ERR; 2263 2264 rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); 2265 if (rc != SEPOL_OK) { 2266 goto exit; 2267 } 2268 2269 node = block_datum->nodes->head->data; 2270 2271 if (node->flavor != CIL_BLOCK) { 2272 cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node)); 2273 rc = SEPOL_ERR; 2274 goto exit; 2275 } 2276 2277 inherit->block = (struct cil_block *)block_datum; 2278 2279 if (inherit->block->bi_nodes == NULL) { 2280 cil_list_init(&inherit->block->bi_nodes, CIL_NODE); 2281 } 2282 cil_list_append(inherit->block->bi_nodes, CIL_NODE, current); 2283 2284 return SEPOL_OK; 2285 2286 exit: 2287 return rc; 2288 } 2289 2290 void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node) 2291 { 2292 struct cil_list *trace = NULL; 2293 struct cil_list_item *item = NULL; 2294 struct cil_tree_node *curr = NULL; 2295 2296 cil_list_init(&trace, CIL_NODE); 2297 2298 for (curr = bi_node; curr != terminating_node; curr = curr->parent) { 2299 if (curr->flavor == CIL_BLOCK) { 2300 cil_list_prepend(trace, CIL_NODE, curr); 2301 } else { 2302 if (curr != bi_node) { 2303 cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_blockinherit *)curr->data)->block)); 2304 } 2305 cil_list_prepend(trace, CIL_NODE, curr); 2306 } 2307 } 2308 cil_list_prepend(trace, CIL_NODE, terminating_node); 2309 2310 cil_list_for_each(item, trace) { 2311 curr = item->data; 2312 if (curr->flavor == CIL_BLOCK) { 2313 cil_tree_log(curr, CIL_ERR, "block %s", DATUM(curr->data)->name); 2314 } else { 2315 cil_tree_log(curr, CIL_ERR, "blockinherit %s", ((struct cil_blockinherit *)curr->data)->block_str); 2316 } 2317 } 2318 2319 cil_list_destroy(&trace, CIL_FALSE); 2320 } 2321 2322 int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node) 2323 { 2324 struct cil_tree_node *curr = NULL; 2325 struct cil_blockinherit *bi = NULL; 2326 struct cil_block *block = NULL; 2327 int rc = SEPOL_ERR; 2328 2329 bi = bi_node->data; 2330 2331 for (curr = bi_node->parent; curr != NULL; curr = curr->parent) { 2332 if (curr->flavor != CIL_BLOCK) { 2333 continue; 2334 } 2335 2336 block = curr->data; 2337 2338 if (block != bi->block) { 2339 continue; 2340 } 2341 2342 cil_log(CIL_ERR, "Recursive blockinherit found:\n"); 2343 cil_print_recursive_blockinherit(bi_node, curr); 2344 2345 rc = SEPOL_ERR; 2346 goto exit; 2347 } 2348 2349 rc = SEPOL_OK; 2350 2351 exit: 2352 return rc; 2353 } 2354 2355 int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args) 2356 { 2357 struct cil_block *block = current->data; 2358 struct cil_args_resolve *args = extra_args; 2359 struct cil_db *db = NULL; 2360 struct cil_list_item *item = NULL; 2361 int rc = SEPOL_ERR; 2362 2363 // This block is not inherited 2364 if (block->bi_nodes == NULL) { 2365 rc = SEPOL_OK; 2366 goto exit; 2367 } 2368 2369 db = args->db; 2370 2371 // Make sure this is the original block and not a merged block from a blockinherit 2372 if (current != block->datum.nodes->head->data) { 2373 rc = SEPOL_OK; 2374 goto exit; 2375 } 2376 2377 cil_list_for_each(item, block->bi_nodes) { 2378 rc = cil_check_recursive_blockinherit(item->data); 2379 if (rc != SEPOL_OK) { 2380 goto exit; 2381 } 2382 2383 rc = cil_copy_ast(db, current, item->data); 2384 if (rc != SEPOL_OK) { 2385 cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n"); 2386 goto exit; 2387 } 2388 } 2389 2390 return SEPOL_OK; 2391 2392 exit: 2393 return rc; 2394 } 2395 2396 int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args) 2397 { 2398 struct cil_blockabstract *abstract = current->data; 2399 struct cil_symtab_datum *block_datum = NULL; 2400 struct cil_tree_node *block_node = NULL; 2401 int rc = SEPOL_ERR; 2402 2403 rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); 2404 if (rc != SEPOL_OK) { 2405 goto exit; 2406 } 2407 2408 block_node = block_datum->nodes->head->data; 2409 if (block_node->flavor != CIL_BLOCK) { 2410 cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc); 2411 goto exit; 2412 } 2413 2414 ((struct cil_block*)block_datum)->is_abstract = CIL_TRUE; 2415 2416 return SEPOL_OK; 2417 2418 exit: 2419 return rc; 2420 } 2421 2422 int cil_resolve_in(struct cil_tree_node *current, void *extra_args) 2423 { 2424 struct cil_in *in = current->data; 2425 struct cil_args_resolve *args = extra_args; 2426 struct cil_db *db = NULL; 2427 struct cil_symtab_datum *block_datum = NULL; 2428 struct cil_tree_node *block_node = NULL; 2429 int rc = SEPOL_ERR; 2430 2431 if (args != NULL) { 2432 db = args->db; 2433 } 2434 2435 rc = cil_resolve_name(current, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); 2436 if (rc != SEPOL_OK) { 2437 goto exit; 2438 } 2439 2440 block_node = block_datum->nodes->head->data; 2441 2442 rc = cil_copy_ast(db, current, block_node); 2443 if (rc != SEPOL_OK) { 2444 printf("Failed to copy in, rc: %d\n", rc); 2445 goto exit; 2446 } 2447 2448 cil_tree_children_destroy(current); 2449 current->cl_head = NULL; 2450 current->cl_tail = NULL; 2451 2452 return SEPOL_OK; 2453 2454 exit: 2455 return rc; 2456 } 2457 2458 int cil_resolve_in_list(void *extra_args) 2459 { 2460 struct cil_args_resolve *args = extra_args; 2461 struct cil_list *ins = args->in_list; 2462 struct cil_list_item *curr = NULL; 2463 struct cil_tree_node *node = NULL; 2464 struct cil_tree_node *last_failed_node = NULL; 2465 struct cil_in *in = NULL; 2466 struct cil_symtab_datum *block_datum = NULL; 2467 int resolved = 0; 2468 int unresolved = 0; 2469 int rc = SEPOL_ERR; 2470 2471 do { 2472 resolved = 0; 2473 unresolved = 0; 2474 2475 cil_list_for_each(curr, ins) { 2476 if (curr->flavor != CIL_NODE) { 2477 continue; 2478 } 2479 2480 node = curr->data; 2481 in = node->data; 2482 2483 rc = cil_resolve_name(node, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); 2484 if (rc != SEPOL_OK) { 2485 unresolved++; 2486 last_failed_node = node; 2487 } else { 2488 rc = cil_resolve_in(node, extra_args); 2489 if (rc != SEPOL_OK) { 2490 goto exit; 2491 } 2492 2493 resolved++; 2494 curr->data = NULL; 2495 curr->flavor = CIL_NONE; 2496 } 2497 } 2498 2499 if (unresolved > 0 && resolved == 0) { 2500 cil_tree_log(last_failed_node, CIL_ERR, "Failed to resolve in-statement"); 2501 rc = SEPOL_ERR; 2502 goto exit; 2503 } 2504 2505 } while (unresolved > 0); 2506 2507 rc = SEPOL_OK; 2508 2509 exit: 2510 return rc; 2511 } 2512 2513 2514 int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor attr_flavor) 2515 { 2516 int rc = SEPOL_ERR; 2517 struct cil_bounds *bounds = current->data; 2518 enum cil_sym_index index; 2519 struct cil_symtab_datum *parent_datum = NULL; 2520 struct cil_symtab_datum *child_datum = NULL; 2521 2522 rc = cil_flavor_to_symtab_index(flavor, &index); 2523 if (rc != SEPOL_OK) { 2524 goto exit; 2525 } 2526 2527 rc = cil_resolve_name(current, bounds->parent_str, index, extra_args, &parent_datum); 2528 if (rc != SEPOL_OK) { 2529 goto exit; 2530 } 2531 if (NODE(parent_datum)->flavor == attr_flavor) { 2532 cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str); 2533 rc = SEPOL_ERR; 2534 goto exit; 2535 } 2536 2537 2538 rc = cil_resolve_name(current, bounds->child_str, index, extra_args, &child_datum); 2539 if (rc != SEPOL_OK) { 2540 goto exit; 2541 } 2542 if (NODE(child_datum)->flavor == attr_flavor) { 2543 cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str); 2544 rc = SEPOL_ERR; 2545 goto exit; 2546 } 2547 2548 switch (flavor) { 2549 case CIL_USER: { 2550 struct cil_user *user = (struct cil_user *)child_datum; 2551 2552 if (user->bounds != NULL) { 2553 cil_tree_log(NODE(user->bounds), CIL_ERR, "User %s already bound by parent", bounds->child_str); 2554 rc = SEPOL_ERR; 2555 goto exit; 2556 } 2557 2558 user->bounds = (struct cil_user *)parent_datum; 2559 break; 2560 } 2561 case CIL_ROLE: { 2562 struct cil_role *role = (struct cil_role *)child_datum; 2563 2564 if (role->bounds != NULL) { 2565 cil_tree_log(NODE(role->bounds), CIL_ERR, "Role %s already bound by parent", bounds->child_str); 2566 rc = SEPOL_ERR; 2567 goto exit; 2568 } 2569 2570 role->bounds = (struct cil_role *)parent_datum; 2571 break; 2572 } 2573 case CIL_TYPE: { 2574 struct cil_type *type = (struct cil_type *)child_datum; 2575 2576 if (type->bounds != NULL) { 2577 cil_tree_log(NODE(type->bounds), CIL_ERR, "Type %s already bound by parent", bounds->child_str); 2578 rc = SEPOL_ERR; 2579 goto exit; 2580 } 2581 2582 type->bounds = (struct cil_type *)parent_datum; 2583 break; 2584 } 2585 default: 2586 break; 2587 } 2588 2589 return SEPOL_OK; 2590 2591 exit: 2592 cil_tree_log(current, CIL_ERR, "Bad bounds statement"); 2593 return rc; 2594 } 2595 2596 int cil_resolve_default(struct cil_tree_node *current, void *extra_args) 2597 { 2598 int rc = SEPOL_ERR; 2599 struct cil_default *def = current->data; 2600 struct cil_list_item *curr; 2601 struct cil_symtab_datum *datum; 2602 2603 cil_list_init(&def->class_datums, def->flavor); 2604 2605 cil_list_for_each(curr, def->class_strs) { 2606 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum); 2607 if (rc != SEPOL_OK) { 2608 goto exit; 2609 } 2610 cil_list_append(def->class_datums, CIL_CLASS, datum); 2611 } 2612 2613 return SEPOL_OK; 2614 2615 exit: 2616 return rc; 2617 } 2618 2619 int cil_resolve_defaultrange(struct cil_tree_node *current, void *extra_args) 2620 { 2621 int rc = SEPOL_ERR; 2622 struct cil_defaultrange *def = current->data; 2623 struct cil_list_item *curr; 2624 struct cil_symtab_datum *datum; 2625 2626 cil_list_init(&def->class_datums, CIL_DEFAULTRANGE); 2627 2628 cil_list_for_each(curr, def->class_strs) { 2629 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum); 2630 if (rc != SEPOL_OK) { 2631 goto exit; 2632 } 2633 cil_list_append(def->class_datums, CIL_CLASS, datum); 2634 } 2635 2636 return SEPOL_OK; 2637 2638 exit: 2639 return rc; 2640 } 2641 2642 void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *terminating_node) 2643 { 2644 struct cil_list *trace = NULL; 2645 struct cil_list_item * item = NULL; 2646 struct cil_tree_node *curr = NULL; 2647 2648 cil_list_init(&trace, CIL_NODE); 2649 2650 for (curr = call_node; curr != terminating_node; curr = curr->parent) { 2651 if (curr->flavor == CIL_CALL) { 2652 if (curr != call_node) { 2653 cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)curr->data)->macro)); 2654 } 2655 cil_list_prepend(trace, CIL_NODE, curr); 2656 } 2657 } 2658 2659 if (terminating_node->flavor == CIL_MACRO) { 2660 cil_list_prepend(trace, CIL_NODE, terminating_node); 2661 } else { 2662 cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)terminating_node->data)->macro)); 2663 } 2664 2665 cil_list_for_each(item, trace) { 2666 curr = item->data; 2667 if (curr->flavor == CIL_MACRO) { 2668 cil_tree_log(curr, CIL_ERR, "macro %s", DATUM(curr->data)->name); 2669 } else { 2670 cil_tree_log(curr, CIL_ERR, "call %s", ((struct cil_call *)curr->data)->macro_str); 2671 } 2672 } 2673 2674 cil_list_destroy(&trace, CIL_FALSE); 2675 } 2676 2677 int cil_check_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *macro_node) 2678 { 2679 struct cil_tree_node *curr = NULL; 2680 struct cil_call * call = NULL; 2681 int rc = SEPOL_ERR; 2682 2683 for (curr = call_node; curr != NULL; curr = curr->parent) { 2684 if (curr->flavor == CIL_CALL) { 2685 if (curr == call_node) { 2686 continue; 2687 } 2688 2689 call = curr->data; 2690 if (call->macro != macro_node->data) { 2691 continue; 2692 } 2693 } else if (curr->flavor == CIL_MACRO) { 2694 if (curr != macro_node) { 2695 rc = SEPOL_OK; 2696 goto exit; 2697 } 2698 } else { 2699 continue; 2700 } 2701 2702 cil_log(CIL_ERR, "Recursive macro call found:\n"); 2703 cil_print_recursive_call(call_node, curr); 2704 2705 rc = SEPOL_ERR; 2706 goto exit; 2707 } 2708 2709 rc = SEPOL_OK; 2710 exit: 2711 return rc; 2712 } 2713 2714 int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) 2715 { 2716 struct cil_call *new_call = current->data; 2717 struct cil_args_resolve *args = extra_args; 2718 struct cil_db *db = NULL; 2719 struct cil_tree_node *macro_node = NULL; 2720 struct cil_symtab_datum *macro_datum = NULL; 2721 int rc = SEPOL_ERR; 2722 2723 if (args != NULL) { 2724 db = args->db; 2725 } 2726 2727 rc = cil_resolve_name(current, new_call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum); 2728 if (rc != SEPOL_OK) { 2729 goto exit; 2730 } 2731 2732 macro_node = macro_datum->nodes->head->data; 2733 2734 if (macro_node->flavor != CIL_MACRO) { 2735 printf("Failed to resolve %s to a macro\n", new_call->macro_str); 2736 rc = SEPOL_ERR; 2737 goto exit; 2738 } 2739 new_call->macro = (struct cil_macro*)macro_datum; 2740 2741 if (new_call->macro->params != NULL ) { 2742 2743 struct cil_list_item *item; 2744 struct cil_args *new_arg = NULL; 2745 struct cil_tree_node *pc = NULL; 2746 2747 if (new_call->args_tree == NULL) { 2748 cil_tree_log(current, CIL_ERR, "Missing arguments"); 2749 rc = SEPOL_ERR; 2750 goto exit; 2751 } 2752 2753 pc = new_call->args_tree->root->cl_head; 2754 2755 cil_list_init(&new_call->args, CIL_LIST_ITEM); 2756 2757 cil_list_for_each(item, new_call->macro->params) { 2758 enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor; 2759 2760 if (pc == NULL) { 2761 cil_tree_log(current, CIL_ERR, "Missing arguments"); 2762 rc = SEPOL_ERR; 2763 goto exit; 2764 } 2765 if (item->flavor != CIL_PARAM) { 2766 rc = SEPOL_ERR; 2767 goto exit; 2768 } 2769 2770 cil_args_init(&new_arg); 2771 2772 switch (flavor) { 2773 case CIL_NAME: { 2774 struct cil_name *name; 2775 name = __cil_insert_name(args->db, pc->data, current); 2776 if (name != NULL) { 2777 new_arg->arg = (struct cil_symtab_datum *)name; 2778 } else { 2779 new_arg->arg_str = pc->data; 2780 } 2781 } 2782 break; 2783 case CIL_TYPE: 2784 new_arg->arg_str = pc->data; 2785 break; 2786 case CIL_ROLE: 2787 new_arg->arg_str = pc->data; 2788 break; 2789 case CIL_USER: 2790 new_arg->arg_str = pc->data; 2791 break; 2792 case CIL_SENS: 2793 new_arg->arg_str = pc->data; 2794 break; 2795 case CIL_CAT: 2796 new_arg->arg_str = pc->data; 2797 break; 2798 case CIL_BOOL: 2799 new_arg->arg_str = pc->data; 2800 break; 2801 case CIL_CATSET: { 2802 if (pc->cl_head != NULL) { 2803 struct cil_catset *catset = NULL; 2804 struct cil_tree_node *cat_node = NULL; 2805 cil_catset_init(&catset); 2806 rc = cil_fill_cats(pc, &catset->cats); 2807 if (rc != SEPOL_OK) { 2808 cil_destroy_catset(catset); 2809 goto exit; 2810 } 2811 cil_tree_node_init(&cat_node); 2812 cat_node->flavor = CIL_CATSET; 2813 cat_node->data = catset; 2814 cil_list_append(((struct cil_symtab_datum*)catset)->nodes, 2815 CIL_LIST_ITEM, cat_node); 2816 new_arg->arg = (struct cil_symtab_datum*)catset; 2817 } else { 2818 new_arg->arg_str = pc->data; 2819 } 2820 2821 break; 2822 } 2823 case CIL_LEVEL: { 2824 if (pc->cl_head != NULL) { 2825 struct cil_level *level = NULL; 2826 struct cil_tree_node *lvl_node = NULL; 2827 cil_level_init(&level); 2828 2829 rc = cil_fill_level(pc->cl_head, level); 2830 if (rc != SEPOL_OK) { 2831 cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc); 2832 cil_destroy_level(level); 2833 goto exit; 2834 } 2835 cil_tree_node_init(&lvl_node); 2836 lvl_node->flavor = CIL_LEVEL; 2837 lvl_node->data = level; 2838 cil_list_append(((struct cil_symtab_datum*)level)->nodes, 2839 CIL_LIST_ITEM, lvl_node); 2840 new_arg->arg = (struct cil_symtab_datum*)level; 2841 } else { 2842 new_arg->arg_str = pc->data; 2843 } 2844 2845 break; 2846 } 2847 case CIL_LEVELRANGE: { 2848 if (pc->cl_head != NULL) { 2849 struct cil_levelrange *range = NULL; 2850 struct cil_tree_node *range_node = NULL; 2851 cil_levelrange_init(&range); 2852 2853 rc = cil_fill_levelrange(pc->cl_head, range); 2854 if (rc != SEPOL_OK) { 2855 cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc); 2856 cil_destroy_levelrange(range); 2857 goto exit; 2858 } 2859 cil_tree_node_init(&range_node); 2860 range_node->flavor = CIL_LEVELRANGE; 2861 range_node->data = range; 2862 cil_list_append(((struct cil_symtab_datum*)range)->nodes, 2863 CIL_LIST_ITEM, range_node); 2864 new_arg->arg = (struct cil_symtab_datum*)range; 2865 } else { 2866 new_arg->arg_str = pc->data; 2867 } 2868 2869 break; 2870 } 2871 case CIL_IPADDR: { 2872 if (pc->cl_head != NULL) { 2873 struct cil_ipaddr *ipaddr = NULL; 2874 struct cil_tree_node *addr_node = NULL; 2875 cil_ipaddr_init(&ipaddr); 2876 2877 rc = cil_fill_ipaddr(pc->cl_head, ipaddr); 2878 if (rc != SEPOL_OK) { 2879 cil_log(CIL_ERR, "Failed to create anonymous ip address, rc; %d\n", rc); 2880 cil_destroy_ipaddr(ipaddr); 2881 goto exit; 2882 } 2883 cil_tree_node_init(&addr_node); 2884 addr_node->flavor = CIL_IPADDR; 2885 addr_node->data = ipaddr; 2886 cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes, 2887 CIL_LIST_ITEM, addr_node); 2888 new_arg->arg = (struct cil_symtab_datum*)ipaddr; 2889 } else { 2890 new_arg->arg_str = pc->data; 2891 } 2892 2893 break; 2894 } 2895 case CIL_CLASS: 2896 new_arg->arg_str = pc->data; 2897 break; 2898 case CIL_MAP_CLASS: 2899 new_arg->arg_str = pc->data; 2900 break; 2901 case CIL_CLASSPERMISSION: { 2902 if (pc->cl_head != NULL) { 2903 struct cil_classpermission *cp = NULL; 2904 struct cil_tree_node *cp_node = NULL; 2905 2906 cil_classpermission_init(&cp); 2907 rc = cil_fill_classperms_list(pc, &cp->classperms); 2908 if (rc != SEPOL_OK) { 2909 cil_log(CIL_ERR, "Failed to create anonymous classpermission\n"); 2910 cil_destroy_classpermission(cp); 2911 goto exit; 2912 } 2913 cil_tree_node_init(&cp_node); 2914 cp_node->flavor = CIL_CLASSPERMISSION; 2915 cp_node->data = cp; 2916 cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node); 2917 new_arg->arg = (struct cil_symtab_datum*)cp; 2918 } else { 2919 new_arg->arg_str = pc->data; 2920 } 2921 break; 2922 } 2923 default: 2924 cil_log(CIL_ERR, "Unexpected flavor: %d\n", 2925 (((struct cil_param*)item->data)->flavor)); 2926 rc = SEPOL_ERR; 2927 goto exit; 2928 } 2929 new_arg->param_str = ((struct cil_param*)item->data)->str; 2930 new_arg->flavor = flavor; 2931 2932 cil_list_append(new_call->args, CIL_ARGS, new_arg); 2933 2934 pc = pc->next; 2935 } 2936 2937 if (pc != NULL) { 2938 cil_tree_log(current, CIL_ERR, "Unexpected arguments"); 2939 rc = SEPOL_ERR; 2940 goto exit; 2941 } 2942 } else if (new_call->args_tree != NULL) { 2943 cil_tree_log(current, CIL_ERR, "Unexpected arguments"); 2944 rc = SEPOL_ERR; 2945 goto exit; 2946 } 2947 2948 if (new_call->copied == 0) { 2949 new_call->copied = 1; 2950 2951 rc = cil_check_recursive_call(current, macro_node); 2952 if (rc != SEPOL_OK) { 2953 goto exit; 2954 } 2955 2956 rc = cil_copy_ast(db, macro_node, current); 2957 if (rc != SEPOL_OK) { 2958 cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc); 2959 goto exit; 2960 } 2961 } 2962 2963 return SEPOL_OK; 2964 2965 exit: 2966 return rc; 2967 } 2968 2969 int cil_resolve_call2(struct cil_tree_node *current, void *extra_args) 2970 { 2971 struct cil_call *new_call = current->data; 2972 int rc = SEPOL_ERR; 2973 enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; 2974 struct cil_list_item *item; 2975 2976 if (new_call->args == NULL) { 2977 rc = SEPOL_OK; 2978 goto exit; 2979 } 2980 2981 cil_list_for_each(item, new_call->args) { 2982 struct cil_args *arg = item->data; 2983 if (arg->arg == NULL && arg->arg_str == NULL) { 2984 cil_log(CIL_ERR, "Arguments not created correctly\n"); 2985 rc = SEPOL_ERR; 2986 goto exit; 2987 } 2988 2989 switch (arg->flavor) { 2990 case CIL_NAME: 2991 if (arg->arg != NULL) { 2992 continue; /* No need to resolve */ 2993 } else { 2994 sym_index = CIL_SYM_NAMES; 2995 } 2996 break; 2997 case CIL_LEVEL: 2998 if (arg->arg_str == NULL && arg->arg != NULL) { 2999 continue; // anonymous, no need to resolve 3000 } else { 3001 sym_index = CIL_SYM_LEVELS; 3002 } 3003 break; 3004 case CIL_LEVELRANGE: 3005 if (arg->arg_str == NULL && arg->arg != NULL) { 3006 continue; // anonymous, no need to resolve 3007 } else { 3008 sym_index = CIL_SYM_LEVELRANGES; 3009 } 3010 break; 3011 case CIL_CATSET: 3012 if (arg->arg_str == NULL && arg->arg != NULL) { 3013 continue; // anonymous, no need to resolve 3014 } else { 3015 sym_index = CIL_SYM_CATS; 3016 } 3017 break; 3018 case CIL_IPADDR: 3019 if (arg->arg_str == NULL && arg->arg != NULL) { 3020 continue; // anonymous, no need to resolve 3021 } else { 3022 sym_index = CIL_SYM_IPADDRS; 3023 } 3024 break; 3025 case CIL_CLASSPERMISSION: 3026 if (arg->arg_str == NULL && arg->arg != NULL) { 3027 continue; 3028 } else { 3029 sym_index = CIL_SYM_CLASSPERMSETS; 3030 } 3031 break; 3032 case CIL_TYPE: 3033 if (arg->arg_str == NULL && arg->arg != NULL) { 3034 continue; // anonymous, no need to resolve 3035 } else { 3036 sym_index = CIL_SYM_TYPES; 3037 } 3038 break; 3039 case CIL_ROLE: 3040 sym_index = CIL_SYM_ROLES; 3041 break; 3042 case CIL_USER: 3043 sym_index = CIL_SYM_USERS; 3044 break; 3045 case CIL_SENS: 3046 sym_index = CIL_SYM_SENS; 3047 break; 3048 case CIL_CAT: 3049 sym_index = CIL_SYM_CATS; 3050 break; 3051 case CIL_CLASS: 3052 case CIL_MAP_CLASS: 3053 sym_index = CIL_SYM_CLASSES; 3054 break; 3055 case CIL_BOOL: 3056 sym_index = CIL_SYM_BOOLS; 3057 break; 3058 default: 3059 rc = SEPOL_ERR; 3060 goto exit; 3061 } 3062 3063 if (sym_index != CIL_SYM_UNKNOWN) { 3064 rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg)); 3065 if (rc != SEPOL_OK) { 3066 goto exit; 3067 } 3068 } 3069 } 3070 3071 return SEPOL_OK; 3072 3073 exit: 3074 return rc; 3075 } 3076 3077 int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) 3078 { 3079 struct cil_list_item *item; 3080 enum cil_sym_index param_index = CIL_SYM_UNKNOWN; 3081 int rc = SEPOL_ERR; 3082 3083 if (call == NULL || name == NULL) { 3084 goto exit; 3085 } 3086 3087 if (call->args == NULL) { 3088 goto exit; 3089 } 3090 3091 cil_list_for_each(item, call->args) { 3092 struct cil_args * arg = item->data; 3093 rc = cil_flavor_to_symtab_index(arg->flavor, ¶m_index); 3094 if (param_index == sym_index) { 3095 if (name == arg->param_str) { 3096 *datum = arg->arg; 3097 rc = SEPOL_OK; 3098 goto exit; 3099 } 3100 } 3101 } 3102 3103 return SEPOL_ERR; 3104 3105 exit: 3106 return rc; 3107 } 3108 3109 int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, void *extra_args) 3110 { 3111 int rc = SEPOL_ERR; 3112 struct cil_list_item *curr; 3113 struct cil_symtab_datum *res_datum = NULL; 3114 enum cil_sym_index sym_index = CIL_SYM_UNKNOWN; 3115 3116 switch (str_expr->flavor) { 3117 case CIL_BOOL: 3118 sym_index = CIL_SYM_BOOLS; 3119 break; 3120 case CIL_TUNABLE: 3121 sym_index = CIL_SYM_TUNABLES; 3122 break; 3123 case CIL_TYPE: 3124 sym_index = CIL_SYM_TYPES; 3125 break; 3126 case CIL_ROLE: 3127 sym_index = CIL_SYM_ROLES; 3128 break; 3129 case CIL_USER: 3130 sym_index = CIL_SYM_USERS; 3131 break; 3132 case CIL_CAT: 3133 sym_index = CIL_SYM_CATS; 3134 break; 3135 default: 3136 break; 3137 } 3138 3139 cil_list_init(datum_expr, str_expr->flavor); 3140 3141 cil_list_for_each(curr, str_expr) { 3142 switch (curr->flavor) { 3143 case CIL_STRING: 3144 rc = cil_resolve_name(parent, curr->data, sym_index, extra_args, &res_datum); 3145 if (rc != SEPOL_OK) { 3146 goto exit; 3147 } 3148 3149 if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) { 3150 cil_type_used(res_datum, CIL_ATTR_CONSTRAINT); 3151 } 3152 3153 cil_list_append(*datum_expr, CIL_DATUM, res_datum); 3154 break; 3155 case CIL_LIST: { 3156 struct cil_list *datum_sub_expr; 3157 rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, extra_args); 3158 if (rc != SEPOL_OK) { 3159 cil_list_destroy(&datum_sub_expr, CIL_TRUE); 3160 goto exit; 3161 } 3162 cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr); 3163 break; 3164 } 3165 default: 3166 cil_list_append(*datum_expr, curr->flavor, curr->data); 3167 break; 3168 } 3169 } 3170 return SEPOL_OK; 3171 3172 exit: 3173 return rc; 3174 } 3175 3176 int cil_resolve_boolif(struct cil_tree_node *current, void *extra_args) 3177 { 3178 int rc = SEPOL_ERR; 3179 struct cil_booleanif *bif = (struct cil_booleanif*)current->data; 3180 3181 rc = cil_resolve_expr(CIL_BOOLEANIF, bif->str_expr, &bif->datum_expr, current, extra_args); 3182 if (rc != SEPOL_OK) { 3183 goto exit; 3184 } 3185 3186 return SEPOL_OK; 3187 3188 exit: 3189 return rc; 3190 } 3191 3192 static int __cil_evaluate_tunable_expr(struct cil_list_item *curr); 3193 3194 static int __cil_evaluate_tunable_expr_helper(struct cil_list_item *curr) 3195 { 3196 if (curr == NULL) { 3197 return CIL_FALSE; 3198 } else if (curr->flavor == CIL_DATUM) { 3199 struct cil_tunable *tun = curr->data; 3200 return tun->value; 3201 } else if (curr->flavor == CIL_LIST) { 3202 struct cil_list *l = curr->data; 3203 return __cil_evaluate_tunable_expr(l->head); 3204 } else { 3205 return CIL_FALSE; 3206 } 3207 } 3208 3209 static int __cil_evaluate_tunable_expr(struct cil_list_item *curr) 3210 { 3211 /* Assumes expression is well-formed */ 3212 3213 if (curr == NULL) { 3214 return CIL_FALSE; 3215 } else if (curr->flavor == CIL_OP) { 3216 uint16_t v1, v2; 3217 enum cil_flavor op_flavor = (enum cil_flavor)curr->data; 3218 3219 v1 = __cil_evaluate_tunable_expr_helper(curr->next); 3220 3221 if (op_flavor == CIL_NOT) return !v1; 3222 3223 v2 = __cil_evaluate_tunable_expr_helper(curr->next->next); 3224 3225 if (op_flavor == CIL_AND) return (v1 && v2); 3226 else if (op_flavor == CIL_OR) return (v1 || v2); 3227 else if (op_flavor == CIL_XOR) return (v1 ^ v2); 3228 else if (op_flavor == CIL_EQ) return (v1 == v2); 3229 else if (op_flavor == CIL_NEQ) return (v1 != v2); 3230 else return CIL_FALSE; 3231 } else { 3232 uint16_t v; 3233 for (;curr; curr = curr->next) { 3234 v = __cil_evaluate_tunable_expr_helper(curr); 3235 if (v) return v; 3236 } 3237 return CIL_FALSE; 3238 } 3239 } 3240 3241 int cil_resolve_tunif(struct cil_tree_node *current, void *extra_args) 3242 { 3243 struct cil_args_resolve *args = extra_args; 3244 struct cil_db *db = NULL; 3245 int rc = SEPOL_ERR; 3246 struct cil_tunableif *tif = (struct cil_tunableif*)current->data; 3247 uint16_t result = CIL_FALSE; 3248 struct cil_tree_node *true_node = NULL; 3249 struct cil_tree_node *false_node = NULL; 3250 struct cil_condblock *cb = NULL; 3251 3252 if (args != NULL) { 3253 db = args->db; 3254 } 3255 3256 rc = cil_resolve_expr(CIL_TUNABLEIF, tif->str_expr, &tif->datum_expr, current, extra_args); 3257 if (rc != SEPOL_OK) { 3258 goto exit; 3259 } 3260 3261 result = __cil_evaluate_tunable_expr(tif->datum_expr->head); 3262 3263 if (current->cl_head != NULL && current->cl_head->flavor == CIL_CONDBLOCK) { 3264 cb = current->cl_head->data; 3265 if (cb->flavor == CIL_CONDTRUE) { 3266 true_node = current->cl_head; 3267 } else if (cb->flavor == CIL_CONDFALSE) { 3268 false_node = current->cl_head; 3269 } 3270 } 3271 3272 if (current->cl_head != NULL && current->cl_head->next != NULL && current->cl_head->next->flavor == CIL_CONDBLOCK) { 3273 cb = current->cl_head->next->data; 3274 if (cb->flavor == CIL_CONDTRUE) { 3275 true_node = current->cl_head->next; 3276 } else if (cb->flavor == CIL_CONDFALSE) { 3277 false_node = current->cl_head->next; 3278 } 3279 } 3280 3281 if (result == CIL_TRUE) { 3282 if (true_node != NULL) { 3283 rc = cil_copy_ast(db, true_node, current->parent); 3284 if (rc != SEPOL_OK) { 3285 goto exit; 3286 } 3287 } 3288 } else { 3289 if (false_node != NULL) { 3290 rc = cil_copy_ast(db, false_node, current->parent); 3291 if (rc != SEPOL_OK) { 3292 goto exit; 3293 } 3294 } 3295 } 3296 3297 cil_tree_children_destroy(current); 3298 current->cl_head = NULL; 3299 current->cl_tail = NULL; 3300 3301 return SEPOL_OK; 3302 3303 exit: 3304 return rc; 3305 } 3306 3307 int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args) 3308 { 3309 int rc = SEPOL_ERR; 3310 struct cil_userattributeset *attrusers = current->data; 3311 struct cil_symtab_datum *attr_datum = NULL; 3312 struct cil_tree_node *attr_node = NULL; 3313 struct cil_userattribute *attr = NULL; 3314 3315 rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, extra_args, &attr_datum); 3316 if (rc != SEPOL_OK) { 3317 goto exit; 3318 } 3319 attr_node = attr_datum->nodes->head->data; 3320 3321 if (attr_node->flavor != CIL_USERATTRIBUTE) { 3322 rc = SEPOL_ERR; 3323 cil_log(CIL_ERR, "Attribute user not an attribute\n"); 3324 goto exit; 3325 } 3326 attr = (struct cil_userattribute*)attr_datum; 3327 3328 rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, extra_args); 3329 if (rc != SEPOL_OK) { 3330 goto exit; 3331 } 3332 3333 rc = cil_verify_no_self_reference(attr_datum, attrusers->datum_expr); 3334 if (rc != SEPOL_OK) { 3335 goto exit; 3336 } 3337 3338 if (attr->expr_list == NULL) { 3339 cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE); 3340 } 3341 3342 cil_list_append(attr->expr_list, CIL_LIST, attrusers->datum_expr); 3343 3344 return SEPOL_OK; 3345 3346 exit: 3347 return rc; 3348 } 3349 3350 int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) 3351 { 3352 int rc = SEPOL_OK; 3353 struct cil_args_resolve *args = extra_args; 3354 enum cil_pass pass = 0; 3355 struct cil_list *ins; 3356 3357 if (node == NULL || args == NULL) { 3358 goto exit; 3359 } 3360 ins = args->in_list; 3361 3362 pass = args->pass; 3363 switch (pass) { 3364 case CIL_PASS_TIF: 3365 if (node->flavor == CIL_TUNABLEIF) { 3366 rc = cil_resolve_tunif(node, args); 3367 } 3368 break; 3369 case CIL_PASS_IN: 3370 if (node->flavor == CIL_IN) { 3371 // due to ordering issues, in statements are just gathered here and 3372 // resolved together in cil_resolve_in_list once all are found 3373 cil_list_prepend(ins, CIL_NODE, node); 3374 } 3375 break; 3376 case CIL_PASS_BLKIN_LINK: 3377 if (node->flavor == CIL_BLOCKINHERIT) { 3378 rc = cil_resolve_blockinherit_link(node, args); 3379 } 3380 break; 3381 case CIL_PASS_BLKIN_COPY: 3382 if (node->flavor == CIL_BLOCK) { 3383 rc = cil_resolve_blockinherit_copy(node, args); 3384 } 3385 break; 3386 case CIL_PASS_BLKABS: 3387 if (node->flavor == CIL_BLOCKABSTRACT) { 3388 rc = cil_resolve_blockabstract(node, args); 3389 } 3390 break; 3391 case CIL_PASS_MACRO: 3392 if (node->flavor == CIL_CALL && args->macro != NULL) { 3393 rc = cil_resolve_call1(node, args); 3394 } 3395 break; 3396 case CIL_PASS_CALL1: 3397 if (node->flavor == CIL_CALL) { 3398 rc = cil_resolve_call1(node, args); 3399 } 3400 break; 3401 case CIL_PASS_CALL2: 3402 if (node->flavor == CIL_CALL) { 3403 rc = cil_resolve_call2(node, args); 3404 } 3405 break; 3406 case CIL_PASS_ALIAS1: 3407 switch (node->flavor) { 3408 case CIL_TYPEALIASACTUAL: 3409 rc = cil_resolve_aliasactual(node, args, CIL_TYPE, CIL_TYPEALIAS); 3410 break; 3411 case CIL_SENSALIASACTUAL: 3412 rc = cil_resolve_aliasactual(node, args, CIL_SENS, CIL_SENSALIAS); 3413 break; 3414 case CIL_CATALIASACTUAL: 3415 rc = cil_resolve_aliasactual(node, args, CIL_CAT, CIL_CATALIAS); 3416 break; 3417 default: 3418 break; 3419 } 3420 break; 3421 case CIL_PASS_ALIAS2: 3422 switch (node->flavor) { 3423 case CIL_TYPEALIAS: 3424 rc = cil_resolve_alias_to_actual(node, CIL_TYPE); 3425 break; 3426 case CIL_SENSALIAS: 3427 rc = cil_resolve_alias_to_actual(node, CIL_SENS); 3428 break; 3429 case CIL_CATALIAS: 3430 rc = cil_resolve_alias_to_actual(node, CIL_CAT); 3431 break; 3432 default: 3433 break; 3434 } 3435 break; 3436 case CIL_PASS_MISC1: 3437 switch (node->flavor) { 3438 case CIL_SIDORDER: 3439 rc = cil_resolve_sidorder(node, args); 3440 break; 3441 case CIL_CLASSORDER: 3442 rc = cil_resolve_classorder(node, args); 3443 break; 3444 case CIL_CATORDER: 3445 rc = cil_resolve_catorder(node, args); 3446 break; 3447 case CIL_SENSITIVITYORDER: 3448 rc = cil_resolve_sensitivityorder(node, args); 3449 break; 3450 case CIL_BOOLEANIF: 3451 rc = cil_resolve_boolif(node, args); 3452 break; 3453 default: 3454 break; 3455 } 3456 break; 3457 case CIL_PASS_MLS: 3458 switch (node->flavor) { 3459 case CIL_CATSET: 3460 rc = cil_resolve_catset(node, (struct cil_catset*)node->data, args); 3461 break; 3462 default: 3463 break; 3464 } 3465 break; 3466 case CIL_PASS_MISC2: 3467 switch (node->flavor) { 3468 case CIL_SENSCAT: 3469 rc = cil_resolve_senscat(node, args); 3470 break; 3471 case CIL_CLASSCOMMON: 3472 rc = cil_resolve_classcommon(node, args); 3473 break; 3474 default: 3475 break; 3476 } 3477 break; 3478 case CIL_PASS_MISC3: 3479 switch (node->flavor) { 3480 case CIL_TYPEATTRIBUTESET: 3481 rc = cil_resolve_typeattributeset(node, args); 3482 break; 3483 case CIL_EXPANDTYPEATTRIBUTE: 3484 rc = cil_resolve_expandtypeattribute(node, args); 3485 break; 3486 case CIL_TYPEBOUNDS: 3487 rc = cil_resolve_bounds(node, args, CIL_TYPE, CIL_TYPEATTRIBUTE); 3488 break; 3489 case CIL_TYPEPERMISSIVE: 3490 rc = cil_resolve_typepermissive(node, args); 3491 break; 3492 case CIL_NAMETYPETRANSITION: 3493 rc = cil_resolve_nametypetransition(node, args); 3494 break; 3495 case CIL_RANGETRANSITION: 3496 rc = cil_resolve_rangetransition(node, args); 3497 break; 3498 case CIL_CLASSPERMISSIONSET: 3499 rc = cil_resolve_classpermissionset(node, (struct cil_classpermissionset*)node->data, args); 3500 break; 3501 case CIL_CLASSMAPPING: 3502 rc = cil_resolve_classmapping(node, args); 3503 break; 3504 case CIL_AVRULE: 3505 case CIL_AVRULEX: 3506 rc = cil_resolve_avrule(node, args); 3507 break; 3508 case CIL_PERMISSIONX: 3509 rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, args); 3510 break; 3511 case CIL_TYPE_RULE: 3512 rc = cil_resolve_type_rule(node, args); 3513 break; 3514 case CIL_USERROLE: 3515 rc = cil_resolve_userrole(node, args); 3516 break; 3517 case CIL_USERLEVEL: 3518 rc = cil_resolve_userlevel(node, args); 3519 break; 3520 case CIL_USERRANGE: 3521 rc = cil_resolve_userrange(node, args); 3522 break; 3523 case CIL_USERBOUNDS: 3524 rc = cil_resolve_bounds(node, args, CIL_USER, CIL_USERATTRIBUTE); 3525 break; 3526 case CIL_USERPREFIX: 3527 rc = cil_resolve_userprefix(node, args); 3528 break; 3529 case CIL_SELINUXUSER: 3530 case CIL_SELINUXUSERDEFAULT: 3531 rc = cil_resolve_selinuxuser(node, args); 3532 break; 3533 case CIL_ROLEATTRIBUTESET: 3534 rc = cil_resolve_roleattributeset(node, args); 3535 break; 3536 case CIL_ROLETYPE: 3537 rc = cil_resolve_roletype(node, args); 3538 break; 3539 case CIL_ROLETRANSITION: 3540 rc = cil_resolve_roletransition(node, args); 3541 break; 3542 case CIL_ROLEALLOW: 3543 rc = cil_resolve_roleallow(node, args); 3544 break; 3545 case CIL_ROLEBOUNDS: 3546 rc = cil_resolve_bounds(node, args, CIL_ROLE, CIL_ROLEATTRIBUTE); 3547 break; 3548 case CIL_LEVEL: 3549 rc = cil_resolve_level(node, (struct cil_level*)node->data, args); 3550 break; 3551 case CIL_LEVELRANGE: 3552 rc = cil_resolve_levelrange(node, (struct cil_levelrange*)node->data, args); 3553 break; 3554 case CIL_CONSTRAIN: 3555 rc = cil_resolve_constrain(node, args); 3556 break; 3557 case CIL_MLSCONSTRAIN: 3558 rc = cil_resolve_constrain(node, args); 3559 break; 3560 case CIL_VALIDATETRANS: 3561 case CIL_MLSVALIDATETRANS: 3562 rc = cil_resolve_validatetrans(node, args); 3563 break; 3564 case CIL_CONTEXT: 3565 rc = cil_resolve_context(node, (struct cil_context*)node->data, args); 3566 break; 3567 case CIL_FILECON: 3568 rc = cil_resolve_filecon(node, args); 3569 break; 3570 case CIL_PORTCON: 3571 rc = cil_resolve_portcon(node, args); 3572 break; 3573 case CIL_NODECON: 3574 rc = cil_resolve_nodecon(node, args); 3575 break; 3576 case CIL_GENFSCON: 3577 rc = cil_resolve_genfscon(node, args); 3578 break; 3579 case CIL_NETIFCON: 3580 rc = cil_resolve_netifcon(node, args); 3581 break; 3582 case CIL_PIRQCON: 3583 rc = cil_resolve_pirqcon(node, args); 3584 break; 3585 case CIL_IOMEMCON: 3586 rc = cil_resolve_iomemcon(node, args); 3587 break; 3588 case CIL_IOPORTCON: 3589 rc = cil_resolve_ioportcon(node, args); 3590 break; 3591 case CIL_PCIDEVICECON: 3592 rc = cil_resolve_pcidevicecon(node, args); 3593 break; 3594 case CIL_DEVICETREECON: 3595 rc = cil_resolve_devicetreecon(node, args); 3596 break; 3597 case CIL_FSUSE: 3598 rc = cil_resolve_fsuse(node, args); 3599 break; 3600 case CIL_SIDCONTEXT: 3601 rc = cil_resolve_sidcontext(node, args); 3602 break; 3603 case CIL_DEFAULTUSER: 3604 case CIL_DEFAULTROLE: 3605 case CIL_DEFAULTTYPE: 3606 rc = cil_resolve_default(node, args); 3607 break; 3608 case CIL_DEFAULTRANGE: 3609 rc = cil_resolve_defaultrange(node, args); 3610 break; 3611 case CIL_USERATTRIBUTESET: 3612 rc = cil_resolve_userattributeset(node, args); 3613 break; 3614 default: 3615 break; 3616 } 3617 break; 3618 default: 3619 break; 3620 } 3621 3622 return rc; 3623 3624 exit: 3625 return rc; 3626 } 3627 3628 int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 3629 { 3630 int rc = SEPOL_ERR; 3631 struct cil_args_resolve *args = extra_args; 3632 enum cil_pass pass = args->pass; 3633 struct cil_tree_node *optstack = args->optstack; 3634 struct cil_tree_node *boolif = args->boolif; 3635 struct cil_tree_node *blockstack = args->blockstack; 3636 struct cil_tree_node *macro = args->macro; 3637 3638 if (node == NULL) { 3639 goto exit; 3640 } 3641 3642 if (optstack != NULL) { 3643 if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) { 3644 /* tuanbles and macros are not allowed in optionals*/ 3645 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node)); 3646 rc = SEPOL_ERR; 3647 goto exit; 3648 } 3649 } 3650 3651 if (blockstack != NULL) { 3652 if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) { 3653 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node)); 3654 rc = SEPOL_ERR; 3655 goto exit; 3656 } 3657 } 3658 3659 if (macro != NULL) { 3660 if (node->flavor == CIL_BLOCKINHERIT || 3661 node->flavor == CIL_BLOCK || 3662 node->flavor == CIL_BLOCKABSTRACT || 3663 node->flavor == CIL_MACRO) { 3664 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node)); 3665 rc = SEPOL_ERR; 3666 goto exit; 3667 } 3668 } 3669 3670 if (boolif != NULL) { 3671 if (!(node->flavor == CIL_CONDBLOCK || 3672 node->flavor == CIL_AVRULE || 3673 node->flavor == CIL_TYPE_RULE || 3674 node->flavor == CIL_CALL || 3675 node->flavor == CIL_TUNABLEIF || 3676 node->flavor == CIL_NAMETYPETRANSITION)) { 3677 if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { 3678 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif)", cil_node_to_string(node)); 3679 } else { 3680 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node)); 3681 } 3682 rc = SEPOL_ERR; 3683 goto exit; 3684 } 3685 } 3686 3687 if (node->flavor == CIL_MACRO) { 3688 if (pass != CIL_PASS_TIF && pass != CIL_PASS_MACRO) { 3689 *finished = CIL_TREE_SKIP_HEAD; 3690 rc = SEPOL_OK; 3691 goto exit; 3692 } 3693 } 3694 3695 if (node->flavor == CIL_BLOCK && ((((struct cil_block*)node->data)->is_abstract == CIL_TRUE) && (pass > CIL_PASS_BLKABS))) { 3696 *finished = CIL_TREE_SKIP_HEAD; 3697 rc = SEPOL_OK; 3698 goto exit; 3699 } 3700 3701 rc = __cil_resolve_ast_node(node, extra_args); 3702 if (rc == SEPOL_ENOENT) { 3703 enum cil_log_level lvl = CIL_ERR; 3704 3705 if (optstack != NULL) { 3706 lvl = CIL_WARN; 3707 3708 struct cil_optional *opt = (struct cil_optional *)optstack->data; 3709 struct cil_tree_node *opt_node = opt->datum.nodes->head->data; 3710 cil_tree_log(opt_node, lvl, "Disabling optional '%s'", opt->datum.name); 3711 /* disable an optional if something failed to resolve */ 3712 opt->enabled = CIL_FALSE; 3713 rc = SEPOL_OK; 3714 } 3715 3716 cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node)); 3717 goto exit; 3718 } 3719 3720 return rc; 3721 3722 exit: 3723 return rc; 3724 } 3725 3726 int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *extra_args) 3727 { 3728 int rc = SEPOL_ERR; 3729 struct cil_args_resolve *args = extra_args; 3730 struct cil_tree_node *optstack = NULL; 3731 struct cil_tree_node *parent = NULL; 3732 struct cil_tree_node *blockstack = NULL; 3733 struct cil_tree_node *new = NULL; 3734 3735 if (current == NULL || extra_args == NULL) { 3736 goto exit; 3737 } 3738 3739 optstack = args->optstack; 3740 parent = current->parent; 3741 blockstack = args->blockstack; 3742 3743 if (parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) { 3744 /* push this node onto a stack */ 3745 cil_tree_node_init(&new); 3746 3747 new->data = parent->data; 3748 new->flavor = parent->flavor; 3749 3750 if (parent->flavor == CIL_OPTIONAL) { 3751 if (optstack != NULL) { 3752 optstack->parent = new; 3753 new->cl_head = optstack; 3754 } 3755 args->optstack = new; 3756 } else if (parent->flavor == CIL_BLOCK) { 3757 if (blockstack != NULL) { 3758 blockstack->parent = new; 3759 new->cl_head = blockstack; 3760 } 3761 args->blockstack = new; 3762 } 3763 } else if (parent->flavor == CIL_BOOLEANIF) { 3764 args->boolif = parent; 3765 } else if (parent->flavor == CIL_MACRO) { 3766 args->macro = parent; 3767 } 3768 3769 return SEPOL_OK; 3770 3771 exit: 3772 return rc; 3773 3774 } 3775 3776 int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *extra_args) 3777 { 3778 int rc = SEPOL_ERR; 3779 struct cil_args_resolve *args = extra_args; 3780 struct cil_tree_node *parent = NULL; 3781 struct cil_tree_node *blockstack = NULL; 3782 3783 if (current == NULL || extra_args == NULL) { 3784 goto exit; 3785 } 3786 3787 parent = current->parent; 3788 3789 if (parent->flavor == CIL_MACRO) { 3790 args->macro = NULL; 3791 } else if (parent->flavor == CIL_OPTIONAL) { 3792 struct cil_tree_node *optstack; 3793 3794 if (((struct cil_optional *)parent->data)->enabled == CIL_FALSE) { 3795 *(args->changed) = CIL_TRUE; 3796 cil_tree_children_destroy(parent); 3797 } 3798 3799 /* pop off the stack */ 3800 optstack = args->optstack; 3801 args->optstack = optstack->cl_head; 3802 if (optstack->cl_head) { 3803 optstack->cl_head->parent = NULL; 3804 } 3805 free(optstack); 3806 } else if (parent->flavor == CIL_BOOLEANIF) { 3807 args->boolif = NULL; 3808 } else if (parent->flavor == CIL_BLOCK) { 3809 /* pop off the stack */ 3810 blockstack = args->blockstack; 3811 args->blockstack = blockstack->cl_head; 3812 if (blockstack->cl_head) { 3813 blockstack->cl_head->parent = NULL; 3814 } 3815 free(blockstack); 3816 } 3817 3818 return SEPOL_OK; 3819 3820 exit: 3821 return rc; 3822 } 3823 3824 static void cil_destroy_tree_node_stack(struct cil_tree_node *curr) 3825 { 3826 struct cil_tree_node *next; 3827 while (curr != NULL) { 3828 next = curr->cl_head; 3829 free(curr); 3830 curr = next; 3831 } 3832 } 3833 3834 int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) 3835 { 3836 int rc = SEPOL_ERR; 3837 struct cil_args_resolve extra_args; 3838 enum cil_pass pass = CIL_PASS_TIF; 3839 uint32_t changed = 0; 3840 3841 if (db == NULL || current == NULL) { 3842 return rc; 3843 } 3844 3845 extra_args.db = db; 3846 extra_args.pass = pass; 3847 extra_args.changed = &changed; 3848 extra_args.last_resolved_name = NULL; 3849 extra_args.optstack = NULL; 3850 extra_args.boolif= NULL; 3851 extra_args.macro = NULL; 3852 extra_args.sidorder_lists = NULL; 3853 extra_args.classorder_lists = NULL; 3854 extra_args.unordered_classorder_lists = NULL; 3855 extra_args.catorder_lists = NULL; 3856 extra_args.sensitivityorder_lists = NULL; 3857 extra_args.in_list = NULL; 3858 extra_args.blockstack = NULL; 3859 3860 cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM); 3861 cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM); 3862 cil_list_init(&extra_args.unordered_classorder_lists, CIL_LIST_ITEM); 3863 cil_list_init(&extra_args.catorder_lists, CIL_LIST_ITEM); 3864 cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM); 3865 cil_list_init(&extra_args.in_list, CIL_IN); 3866 for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) { 3867 extra_args.pass = pass; 3868 rc = cil_tree_walk(current, __cil_resolve_ast_node_helper, __cil_resolve_ast_first_child_helper, __cil_resolve_ast_last_child_helper, &extra_args); 3869 if (rc != SEPOL_OK) { 3870 cil_log(CIL_INFO, "Pass %i of resolution failed\n", pass); 3871 goto exit; 3872 } 3873 3874 if (pass == CIL_PASS_IN) { 3875 rc = cil_resolve_in_list(&extra_args); 3876 if (rc != SEPOL_OK) { 3877 goto exit; 3878 } 3879 cil_list_destroy(&extra_args.in_list, CIL_FALSE); 3880 } 3881 3882 if (pass == CIL_PASS_MISC1) { 3883 db->sidorder = __cil_ordered_lists_merge_all(&extra_args.sidorder_lists, NULL); 3884 if (db->sidorder == NULL) { 3885 rc = SEPOL_ERR; 3886 goto exit; 3887 } 3888 db->classorder = __cil_ordered_lists_merge_all(&extra_args.classorder_lists, &extra_args.unordered_classorder_lists); 3889 if (db->classorder == NULL) { 3890 rc = SEPOL_ERR; 3891 goto exit; 3892 } 3893 db->catorder = __cil_ordered_lists_merge_all(&extra_args.catorder_lists, NULL); 3894 if (db->catorder == NULL) { 3895 rc = SEPOL_ERR; 3896 goto exit; 3897 } 3898 cil_set_cat_values(db->catorder, db); 3899 db->sensitivityorder = __cil_ordered_lists_merge_all(&extra_args.sensitivityorder_lists, NULL); 3900 if (db->sensitivityorder == NULL) { 3901 rc = SEPOL_ERR; 3902 goto exit; 3903 } 3904 3905 rc = __cil_verify_ordered(current, CIL_SID); 3906 if (rc != SEPOL_OK) { 3907 goto exit; 3908 } 3909 3910 rc = __cil_verify_ordered(current, CIL_CLASS); 3911 if (rc != SEPOL_OK) { 3912 goto exit; 3913 } 3914 3915 rc = __cil_verify_ordered(current, CIL_CAT); 3916 if (rc != SEPOL_OK) { 3917 goto exit; 3918 } 3919 3920 rc = __cil_verify_ordered(current, CIL_SENS); 3921 if (rc != SEPOL_OK) { 3922 goto exit; 3923 } 3924 } 3925 3926 if (changed && (pass > CIL_PASS_CALL1)) { 3927 /* Need to re-resolve because an optional was disabled that contained 3928 * one or more declarations. We only need to reset to the call1 pass 3929 * because things done in the preceeding passes aren't allowed in 3930 * optionals, and thus can't be disabled. 3931 * Note: set pass to CIL_PASS_CALL1 because the pass++ will increment 3932 * it to CIL_PASS_CALL2 3933 */ 3934 cil_log(CIL_INFO, "Resetting declarations\n"); 3935 3936 if (pass >= CIL_PASS_MISC1) { 3937 __cil_ordered_lists_reset(&extra_args.sidorder_lists); 3938 __cil_ordered_lists_reset(&extra_args.classorder_lists); 3939 __cil_ordered_lists_reset(&extra_args.unordered_classorder_lists); 3940 __cil_ordered_lists_reset(&extra_args.catorder_lists); 3941 __cil_ordered_lists_reset(&extra_args.sensitivityorder_lists); 3942 cil_list_destroy(&db->sidorder, CIL_FALSE); 3943 cil_list_destroy(&db->classorder, CIL_FALSE); 3944 cil_list_destroy(&db->catorder, CIL_FALSE); 3945 cil_list_destroy(&db->sensitivityorder, CIL_FALSE); 3946 } 3947 3948 pass = CIL_PASS_CALL1; 3949 3950 rc = cil_reset_ast(current); 3951 if (rc != SEPOL_OK) { 3952 cil_log(CIL_ERR, "Failed to reset declarations\n"); 3953 goto exit; 3954 } 3955 } 3956 3957 /* reset the arguments */ 3958 changed = 0; 3959 while (extra_args.optstack != NULL) { 3960 cil_destroy_tree_node_stack(extra_args.optstack); 3961 extra_args.optstack = NULL; 3962 } 3963 while (extra_args.blockstack!= NULL) { 3964 cil_destroy_tree_node_stack(extra_args.blockstack); 3965 extra_args.blockstack = NULL; 3966 } 3967 } 3968 3969 rc = __cil_verify_initsids(db->sidorder); 3970 if (rc != SEPOL_OK) { 3971 goto exit; 3972 } 3973 3974 rc = SEPOL_OK; 3975 exit: 3976 cil_destroy_tree_node_stack(extra_args.optstack); 3977 cil_destroy_tree_node_stack(extra_args.blockstack); 3978 __cil_ordered_lists_destroy(&extra_args.sidorder_lists); 3979 __cil_ordered_lists_destroy(&extra_args.classorder_lists); 3980 __cil_ordered_lists_destroy(&extra_args.catorder_lists); 3981 __cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists); 3982 __cil_ordered_lists_destroy(&extra_args.unordered_classorder_lists); 3983 cil_list_destroy(&extra_args.in_list, CIL_FALSE); 3984 3985 return rc; 3986 } 3987 3988 static int __cil_resolve_name_with_root(struct cil_db *db, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) 3989 { 3990 symtab_t *symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index]; 3991 3992 return cil_symtab_get_datum(symtab, name, datum); 3993 } 3994 3995 static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) 3996 { 3997 int rc = SEPOL_ERR; 3998 symtab_t *symtab = NULL; 3999 4000 while (node != NULL && rc != SEPOL_OK) { 4001 switch (node->flavor) { 4002 case CIL_ROOT: 4003 goto exit; 4004 break; 4005 case CIL_BLOCK: 4006 symtab = &((struct cil_block*)node->data)->symtab[sym_index]; 4007 rc = cil_symtab_get_datum(symtab, name, datum); 4008 break; 4009 case CIL_BLOCKINHERIT: { 4010 struct cil_blockinherit *inherit = node->data; 4011 rc = __cil_resolve_name_with_parents(node->parent, name, sym_index, datum); 4012 if (rc != SEPOL_OK) { 4013 /* Continue search in original block's parent */ 4014 rc = __cil_resolve_name_with_parents(NODE(inherit->block), name, sym_index, datum); 4015 goto exit; 4016 } 4017 } 4018 break; 4019 case CIL_MACRO: { 4020 struct cil_macro *macro = node->data; 4021 symtab = ¯o->symtab[sym_index]; 4022 rc = cil_symtab_get_datum(symtab, name, datum); 4023 } 4024 break; 4025 case CIL_CALL: { 4026 struct cil_call *call = node->data; 4027 rc = cil_resolve_name_call_args(call, name, sym_index, datum); 4028 if (rc != SEPOL_OK) { 4029 /* Continue search in macro's parent */ 4030 rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum); 4031 } 4032 } 4033 break; 4034 case CIL_IN: 4035 /* In block symtabs only exist before resolving the AST */ 4036 case CIL_CONDBLOCK: 4037 /* Cond block symtabs only exist before resolving the AST */ 4038 default: 4039 break; 4040 } 4041 4042 node = node->parent; 4043 } 4044 4045 exit: 4046 return rc; 4047 } 4048 4049 static int __cil_resolve_name_helper(struct cil_db *db, struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum) 4050 { 4051 int rc = SEPOL_ERR; 4052 4053 rc = __cil_resolve_name_with_parents(node, name, sym_index, datum); 4054 if (rc != SEPOL_OK) { 4055 rc = __cil_resolve_name_with_root(db, name, sym_index, datum); 4056 } 4057 return rc; 4058 } 4059 4060 int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum) 4061 { 4062 int rc = SEPOL_ERR; 4063 struct cil_args_resolve *args = extra_args; 4064 struct cil_db *db = args->db; 4065 struct cil_tree_node *node = NULL; 4066 4067 if (name == NULL) { 4068 cil_log(CIL_ERR, "Invalid call to cil_resolve_name\n"); 4069 goto exit; 4070 } 4071 4072 *datum = NULL; 4073 4074 if (strchr(name,'.') == NULL) { 4075 /* No '.' in name */ 4076 rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum); 4077 if (rc != SEPOL_OK) { 4078 goto exit; 4079 } 4080 } else { 4081 char *sp = NULL; 4082 char *name_dup = cil_strdup(name); 4083 char *current = strtok_r(name_dup, ".", &sp); 4084 char *next = strtok_r(NULL, ".", &sp); 4085 symtab_t *symtab = NULL; 4086 4087 if (current == NULL) { 4088 /* Only dots */ 4089 cil_tree_log(ast_node, CIL_ERR, "Invalid name %s", name); 4090 free(name_dup); 4091 goto exit; 4092 } 4093 4094 node = ast_node; 4095 if (*name == '.') { 4096 /* Leading '.' */ 4097 symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_BLOCKS]; 4098 } else { 4099 rc = __cil_resolve_name_helper(db, node->parent, current, CIL_SYM_BLOCKS, datum); 4100 if (rc != SEPOL_OK) { 4101 free(name_dup); 4102 goto exit; 4103 } 4104 symtab = (*datum)->symtab; 4105 } 4106 /* Keep looking up blocks by name until only last part of name remains */ 4107 while (next != NULL) { 4108 rc = cil_symtab_get_datum(symtab, current, datum); 4109 if (rc != SEPOL_OK) { 4110 free(name_dup); 4111 goto exit; 4112 } 4113 node = NODE(*datum); 4114 if (node->flavor == CIL_BLOCK) { 4115 symtab = &((struct cil_block*)node->data)->symtab[CIL_SYM_BLOCKS]; 4116 } else { 4117 if (ast_node->flavor != CIL_IN) { 4118 cil_log(CIL_WARN, "Can only use %s name for name resolution in \"in\" blocks\n", cil_node_to_string(node)); 4119 free(name_dup); 4120 rc = SEPOL_ERR; 4121 goto exit; 4122 } 4123 if (node->flavor == CIL_MACRO) { 4124 struct cil_macro *macro = node->data; 4125 symtab = ¯o->symtab[sym_index]; 4126 } else { 4127 /* optional */ 4128 symtab = (*datum)->symtab; 4129 } 4130 } 4131 current = next; 4132 next = strtok_r(NULL, ".", &sp); 4133 } 4134 symtab = &(symtab[sym_index]); 4135 rc = cil_symtab_get_datum(symtab, current, datum); 4136 free(name_dup); 4137 if (rc != SEPOL_OK) { 4138 goto exit; 4139 } 4140 } 4141 4142 rc = SEPOL_OK; 4143 4144 exit: 4145 if (rc != SEPOL_OK) { 4146 *datum = NULL; 4147 } 4148 4149 if (*datum != NULL) { 4150 /* If this datum is an alias, then return the actual node 4151 * This depends on aliases already being processed 4152 */ 4153 node = NODE(*datum); 4154 if (node->flavor == CIL_TYPEALIAS || node->flavor == CIL_SENSALIAS 4155 || node->flavor == CIL_CATALIAS) { 4156 struct cil_alias *alias = (struct cil_alias *)(*datum); 4157 if (alias->actual) { 4158 *datum = alias->actual; 4159 } 4160 } 4161 } 4162 4163 args->last_resolved_name = name; 4164 4165 return rc; 4166 } 4167