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