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