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