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