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 #include <stdint.h> 34 #include <unistd.h> 35 36 #include <sepol/policydb/conditional.h> 37 #include <sepol/errcodes.h> 38 39 #include "cil_internal.h" 40 #include "cil_flavor.h" 41 #include "cil_log.h" 42 #include "cil_mem.h" 43 #include "cil_tree.h" 44 #include "cil_list.h" 45 #include "cil_post.h" 46 #include "cil_policy.h" 47 #include "cil_verify.h" 48 #include "cil_symtab.h" 49 50 #define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/src/module_to_cil.c */ 51 #define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/src/module_to_cil.c */ 52 53 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db); 54 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db); 55 56 static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor) 57 { 58 struct cil_list_item *curr; 59 60 cil_list_for_each(curr, list) { 61 switch (curr->flavor) { 62 case CIL_LIST: 63 return CIL_FALSE; 64 break; 65 case CIL_OP: 66 return CIL_FALSE; 67 break; 68 default: 69 if (flavor == CIL_CAT) { 70 struct cil_symtab_datum *d = curr->data; 71 struct cil_tree_node *n = d->nodes->head->data; 72 if (n->flavor == CIL_CATSET) { 73 return CIL_FALSE; 74 } 75 } 76 break; 77 } 78 } 79 return CIL_TRUE; 80 } 81 82 void cil_post_fc_fill_data(struct fc_data *fc, char *path) 83 { 84 int c = 0; 85 fc->meta = 0; 86 fc->stem_len = 0; 87 fc->str_len = 0; 88 89 while (path[c] != '\0') { 90 switch (path[c]) { 91 case '.': 92 case '^': 93 case '$': 94 case '?': 95 case '*': 96 case '+': 97 case '|': 98 case '[': 99 case '(': 100 case '{': 101 fc->meta = 1; 102 break; 103 case '\\': 104 c++; 105 default: 106 if (!fc->meta) { 107 fc->stem_len++; 108 } 109 break; 110 } 111 fc->str_len++; 112 c++; 113 } 114 } 115 116 int cil_post_filecon_compare(const void *a, const void *b) 117 { 118 int rc = 0; 119 struct cil_filecon *a_filecon = *(struct cil_filecon**)a; 120 struct cil_filecon *b_filecon = *(struct cil_filecon**)b; 121 struct fc_data *a_data = cil_malloc(sizeof(*a_data)); 122 struct fc_data *b_data = cil_malloc(sizeof(*b_data)); 123 char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1); 124 a_path[0] = '\0'; 125 char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1); 126 b_path[0] = '\0'; 127 strcat(a_path, a_filecon->path_str); 128 strcat(b_path, b_filecon->path_str); 129 cil_post_fc_fill_data(a_data, a_path); 130 cil_post_fc_fill_data(b_data, b_path); 131 if (a_data->meta && !b_data->meta) { 132 rc = -1; 133 } else if (b_data->meta && !a_data->meta) { 134 rc = 1; 135 } else if (a_data->stem_len < b_data->stem_len) { 136 rc = -1; 137 } else if (b_data->stem_len < a_data->stem_len) { 138 rc = 1; 139 } else if (a_data->str_len < b_data->str_len) { 140 rc = -1; 141 } else if (b_data->str_len < a_data->str_len) { 142 rc = 1; 143 } else if (a_filecon->type < b_filecon->type) { 144 rc = -1; 145 } else if (b_filecon->type < a_filecon->type) { 146 rc = 1; 147 } 148 149 free(a_path); 150 free(b_path); 151 free(a_data); 152 free(b_data); 153 154 return rc; 155 } 156 157 int cil_post_portcon_compare(const void *a, const void *b) 158 { 159 int rc = SEPOL_ERR; 160 struct cil_portcon *aportcon = *(struct cil_portcon**)a; 161 struct cil_portcon *bportcon = *(struct cil_portcon**)b; 162 163 rc = (aportcon->port_high - aportcon->port_low) 164 - (bportcon->port_high - bportcon->port_low); 165 if (rc == 0) { 166 if (aportcon->port_low < bportcon->port_low) { 167 rc = -1; 168 } else if (bportcon->port_low < aportcon->port_low) { 169 rc = 1; 170 } 171 } 172 173 return rc; 174 } 175 176 int cil_post_genfscon_compare(const void *a, const void *b) 177 { 178 int rc = SEPOL_ERR; 179 struct cil_genfscon *agenfscon = *(struct cil_genfscon**)a; 180 struct cil_genfscon *bgenfscon = *(struct cil_genfscon**)b; 181 182 rc = strcmp(agenfscon->fs_str, bgenfscon->fs_str); 183 if (rc == 0) { 184 rc = strcmp(agenfscon->path_str, bgenfscon->path_str); 185 } 186 187 return rc; 188 } 189 190 int cil_post_netifcon_compare(const void *a, const void *b) 191 { 192 struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a; 193 struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b; 194 195 return strcmp(anetifcon->interface_str, bnetifcon->interface_str); 196 } 197 198 int cil_post_nodecon_compare(const void *a, const void *b) 199 { 200 struct cil_nodecon *anodecon; 201 struct cil_nodecon *bnodecon; 202 anodecon = *(struct cil_nodecon**)a; 203 bnodecon = *(struct cil_nodecon**)b; 204 205 /* sort ipv4 before ipv6 */ 206 if (anodecon->addr->family != bnodecon->addr->family) { 207 if (anodecon->addr->family == AF_INET) { 208 return -1; 209 } else { 210 return 1; 211 } 212 } 213 214 /* most specific netmask goes first, then order by ip addr */ 215 if (anodecon->addr->family == AF_INET) { 216 int rc = memcmp(&anodecon->mask->ip.v4, &bnodecon->mask->ip.v4, sizeof(anodecon->mask->ip.v4)); 217 if (rc != 0) { 218 return -1 * rc; 219 } 220 return memcmp(&anodecon->addr->ip.v4, &bnodecon->addr->ip.v4, sizeof(anodecon->addr->ip.v4)); 221 } else { 222 int rc = memcmp(&anodecon->mask->ip.v6, &bnodecon->mask->ip.v6, sizeof(anodecon->mask->ip.v6)); 223 if (rc != 0) { 224 return -1 * rc; 225 } 226 return memcmp(&anodecon->addr->ip.v6, &bnodecon->addr->ip.v6, sizeof(anodecon->addr->ip.v6)); 227 } 228 } 229 230 int cil_post_pirqcon_compare(const void *a, const void *b) 231 { 232 int rc = SEPOL_ERR; 233 struct cil_pirqcon *apirqcon = *(struct cil_pirqcon**)a; 234 struct cil_pirqcon *bpirqcon = *(struct cil_pirqcon**)b; 235 236 if (apirqcon->pirq < bpirqcon->pirq) { 237 rc = -1; 238 } else if (bpirqcon->pirq < apirqcon->pirq) { 239 rc = 1; 240 } else { 241 rc = 0; 242 } 243 244 return rc; 245 } 246 247 int cil_post_iomemcon_compare(const void *a, const void *b) 248 { 249 int rc = SEPOL_ERR; 250 struct cil_iomemcon *aiomemcon = *(struct cil_iomemcon**)a; 251 struct cil_iomemcon *biomemcon = *(struct cil_iomemcon**)b; 252 253 rc = (aiomemcon->iomem_high - aiomemcon->iomem_low) 254 - (biomemcon->iomem_high - biomemcon->iomem_low); 255 if (rc == 0) { 256 if (aiomemcon->iomem_low < biomemcon->iomem_low) { 257 rc = -1; 258 } else if (biomemcon->iomem_low < aiomemcon->iomem_low) { 259 rc = 1; 260 } 261 } 262 263 return rc; 264 } 265 266 int cil_post_ioportcon_compare(const void *a, const void *b) 267 { 268 int rc = SEPOL_ERR; 269 struct cil_ioportcon *aioportcon = *(struct cil_ioportcon**)a; 270 struct cil_ioportcon *bioportcon = *(struct cil_ioportcon**)b; 271 272 rc = (aioportcon->ioport_high - aioportcon->ioport_low) 273 - (bioportcon->ioport_high - bioportcon->ioport_low); 274 if (rc == 0) { 275 if (aioportcon->ioport_low < bioportcon->ioport_low) { 276 rc = -1; 277 } else if (bioportcon->ioport_low < aioportcon->ioport_low) { 278 rc = 1; 279 } 280 } 281 282 return rc; 283 } 284 285 int cil_post_pcidevicecon_compare(const void *a, const void *b) 286 { 287 int rc = SEPOL_ERR; 288 struct cil_pcidevicecon *apcidevicecon = *(struct cil_pcidevicecon**)a; 289 struct cil_pcidevicecon *bpcidevicecon = *(struct cil_pcidevicecon**)b; 290 291 if (apcidevicecon->dev < bpcidevicecon->dev) { 292 rc = -1; 293 } else if (bpcidevicecon->dev < apcidevicecon->dev) { 294 rc = 1; 295 } else { 296 rc = 0; 297 } 298 299 return rc; 300 } 301 302 int cil_post_devicetreecon_compare(const void *a, const void *b) 303 { 304 int rc = SEPOL_ERR; 305 struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a; 306 struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b; 307 308 rc = strcmp(adevicetreecon->path, bdevicetreecon->path); 309 310 return rc; 311 } 312 313 int cil_post_fsuse_compare(const void *a, const void *b) 314 { 315 int rc; 316 struct cil_fsuse *afsuse; 317 struct cil_fsuse *bfsuse; 318 afsuse = *(struct cil_fsuse**)a; 319 bfsuse = *(struct cil_fsuse**)b; 320 if (afsuse->type < bfsuse->type) { 321 rc = -1; 322 } else if (bfsuse->type < afsuse->type) { 323 rc = 1; 324 } else { 325 rc = strcmp(afsuse->fs_str, bfsuse->fs_str); 326 } 327 return rc; 328 } 329 330 static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 331 { 332 struct cil_db *db = extra_args; 333 334 switch(node->flavor) { 335 case CIL_BLOCK: { 336 struct cil_block *blk = node->data; 337 if (blk->is_abstract == CIL_TRUE) { 338 *finished = CIL_TREE_SKIP_HEAD; 339 } 340 break; 341 } 342 case CIL_MACRO: 343 *finished = CIL_TREE_SKIP_HEAD; 344 break; 345 case CIL_CLASS: { 346 struct cil_class *class = node->data; 347 if (class->datum.nodes->head->data == node) { 348 // Multiple nodes can point to the same datum. Only count once. 349 db->num_classes++; 350 } 351 break; 352 } 353 case CIL_TYPE: { 354 struct cil_type *type = node->data; 355 if (type->datum.nodes->head->data == node) { 356 // Multiple nodes can point to the same datum. Only count once. 357 type->value = db->num_types; 358 db->num_types++; 359 db->num_types_and_attrs++; 360 } 361 break; 362 } 363 case CIL_TYPEATTRIBUTE: { 364 struct cil_typeattribute *attr = node->data; 365 if (attr->datum.nodes->head->data == node) { 366 // Multiple nodes can point to the same datum. Only count once. 367 db->num_types_and_attrs++; 368 } 369 break; 370 } 371 372 case CIL_ROLE: { 373 struct cil_role *role = node->data; 374 if (role->datum.nodes->head->data == node) { 375 // Multiple nodes can point to the same datum. Only count once. 376 role->value = db->num_roles; 377 db->num_roles++; 378 } 379 break; 380 } 381 case CIL_USER: { 382 struct cil_user *user = node->data; 383 if (user->datum.nodes->head->data == node) { 384 // multiple AST nodes can point to the same cil_user data (like if 385 // copied from a macro). This check ensures we only count the 386 // duplicates once 387 user->value = db->num_users; 388 db->num_users++; 389 } 390 break; 391 } 392 case CIL_NETIFCON: 393 db->netifcon->count++; 394 break; 395 case CIL_GENFSCON: 396 db->genfscon->count++; 397 break; 398 case CIL_FILECON: 399 db->filecon->count++; 400 break; 401 case CIL_NODECON: 402 db->nodecon->count++; 403 break; 404 case CIL_PORTCON: 405 db->portcon->count++; 406 break; 407 case CIL_PIRQCON: 408 db->pirqcon->count++; 409 break; 410 case CIL_IOMEMCON: 411 db->iomemcon->count++; 412 break; 413 case CIL_IOPORTCON: 414 db->ioportcon->count++; 415 break; 416 case CIL_PCIDEVICECON: 417 db->pcidevicecon->count++; 418 break; 419 case CIL_DEVICETREECON: 420 db->devicetreecon->count++; 421 break; 422 case CIL_FSUSE: 423 db->fsuse->count++; 424 break; 425 default: 426 break; 427 } 428 429 return SEPOL_OK; 430 } 431 432 static int __cil_post_db_array_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 433 { 434 struct cil_db *db = extra_args; 435 436 switch(node->flavor) { 437 case CIL_BLOCK: { 438 struct cil_block *blk = node->data; 439 if (blk->is_abstract == CIL_TRUE) { 440 *finished = CIL_TREE_SKIP_HEAD; 441 } 442 break; 443 } 444 case CIL_MACRO: 445 *finished = CIL_TREE_SKIP_HEAD; 446 break; 447 case CIL_TYPE: { 448 struct cil_type *type = node->data; 449 if (db->val_to_type == NULL) { 450 db->val_to_type = cil_malloc(sizeof(*db->val_to_type) * db->num_types); 451 } 452 db->val_to_type[type->value] = type; 453 break; 454 } 455 case CIL_ROLE: { 456 struct cil_role *role = node->data; 457 if (db->val_to_role == NULL) { 458 db->val_to_role = cil_malloc(sizeof(*db->val_to_role) * db->num_roles); 459 } 460 db->val_to_role[role->value] = role; 461 break; 462 } 463 case CIL_USER: { 464 struct cil_user *user= node->data; 465 if (db->val_to_user == NULL) { 466 db->val_to_user = cil_malloc(sizeof(*db->val_to_user) * db->num_users); 467 } 468 db->val_to_user[user->value] = user; 469 break; 470 } 471 case CIL_USERPREFIX: { 472 cil_list_append(db->userprefixes, CIL_USERPREFIX, node->data); 473 break; 474 } 475 case CIL_SELINUXUSER: { 476 cil_list_prepend(db->selinuxusers, CIL_SELINUXUSER, node->data); 477 break; 478 } 479 case CIL_SELINUXUSERDEFAULT: { 480 cil_list_append(db->selinuxusers, CIL_SELINUXUSERDEFAULT, node->data); 481 break; 482 } 483 case CIL_NETIFCON: { 484 struct cil_sort *sort = db->netifcon; 485 uint32_t count = sort->count; 486 uint32_t i = sort->index; 487 if (sort->array == NULL) { 488 sort->array = cil_malloc(sizeof(*sort->array)*count); 489 } 490 sort->array[i] = node->data; 491 sort->index++; 492 break; 493 } 494 case CIL_FSUSE: { 495 struct cil_sort *sort = db->fsuse; 496 uint32_t count = sort->count; 497 uint32_t i = sort->index; 498 if (sort->array == NULL) { 499 sort->array = cil_malloc(sizeof(*sort->array)*count); 500 } 501 sort->array[i] = node->data; 502 sort->index++; 503 break; 504 } 505 case CIL_GENFSCON: { 506 struct cil_sort *sort = db->genfscon; 507 uint32_t count = sort->count; 508 uint32_t i = sort->index; 509 if (sort->array == NULL) { 510 sort->array = cil_malloc(sizeof(*sort->array)*count); 511 } 512 sort->array[i] = node->data; 513 sort->index++; 514 break; 515 } 516 case CIL_FILECON: { 517 struct cil_sort *sort = db->filecon; 518 uint32_t count = sort->count; 519 uint32_t i = sort->index; 520 if (sort->array == NULL) { 521 sort->array = cil_malloc(sizeof(*sort->array)*count); 522 } 523 sort->array[i] = node->data; 524 sort->index++; 525 break; 526 } 527 case CIL_NODECON: { 528 struct cil_sort *sort = db->nodecon; 529 uint32_t count = sort->count; 530 uint32_t i = sort->index; 531 if (sort->array == NULL) { 532 sort->array = cil_malloc(sizeof(*sort->array)*count); 533 } 534 sort->array[i] = node->data; 535 sort->index++; 536 break; 537 } 538 case CIL_PORTCON: { 539 struct cil_sort *sort = db->portcon; 540 uint32_t count = sort->count; 541 uint32_t i = sort->index; 542 if (sort->array == NULL) { 543 sort->array = cil_malloc(sizeof(*sort->array)*count); 544 } 545 sort->array[i] = node->data; 546 sort->index++; 547 break; 548 } 549 case CIL_PIRQCON: { 550 struct cil_sort *sort = db->pirqcon; 551 uint32_t count = sort->count; 552 uint32_t i = sort->index; 553 if (sort->array == NULL) { 554 sort->array = cil_malloc(sizeof(*sort->array)*count); 555 } 556 sort->array[i] = node->data; 557 sort->index++; 558 break; 559 } 560 case CIL_IOMEMCON: { 561 struct cil_sort *sort = db->iomemcon; 562 uint32_t count = sort->count; 563 uint32_t i = sort->index; 564 if (sort->array == NULL) { 565 sort->array = cil_malloc(sizeof(*sort->array)*count); 566 } 567 sort->array[i] = node->data; 568 sort->index++; 569 break; 570 } 571 case CIL_IOPORTCON: { 572 struct cil_sort *sort = db->ioportcon; 573 uint32_t count = sort->count; 574 uint32_t i = sort->index; 575 if (sort->array == NULL) { 576 sort->array = cil_malloc(sizeof(*sort->array)*count); 577 } 578 sort->array[i] = node->data; 579 sort->index++; 580 break; 581 } 582 case CIL_PCIDEVICECON: { 583 struct cil_sort *sort = db->pcidevicecon; 584 uint32_t count = sort->count; 585 uint32_t i = sort->index; 586 if (sort->array == NULL) { 587 sort->array = cil_malloc(sizeof(*sort->array)*count); 588 } 589 sort->array[i] = node->data; 590 sort->index++; 591 break; 592 } 593 case CIL_DEVICETREECON: { 594 struct cil_sort *sort = db->devicetreecon; 595 uint32_t count = sort->count; 596 uint32_t i = sort->index; 597 if (sort->array == NULL) { 598 sort->array = cil_malloc(sizeof(*sort->array)*count); 599 } 600 sort->array[i] = node->data; 601 sort->index++; 602 break; 603 } 604 default: 605 break; 606 } 607 608 return SEPOL_OK; 609 } 610 611 static int __evaluate_type_expression(struct cil_typeattribute *attr, struct cil_db *db) 612 { 613 int rc; 614 615 attr->types = cil_malloc(sizeof(*attr->types)); 616 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->types, db->num_types, db); 617 if (rc != SEPOL_OK) { 618 cil_log(CIL_ERR, "Failed to expand type attribute to bitmap\n"); 619 ebitmap_destroy(attr->types); 620 free(attr->types); 621 attr->types = NULL; 622 } 623 return rc; 624 } 625 626 static int __cil_type_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 627 { 628 int rc = SEPOL_ERR; 629 struct cil_tree_node *node = datum->nodes->head->data; 630 631 ebitmap_init(bitmap); 632 633 if (node->flavor == CIL_TYPEATTRIBUTE) { 634 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 635 if (attr->types == NULL) { 636 rc = __evaluate_type_expression(attr, db); 637 if (rc != SEPOL_OK) goto exit; 638 } 639 ebitmap_union(bitmap, attr->types); 640 } else if (node->flavor == CIL_TYPEALIAS) { 641 struct cil_alias *alias = (struct cil_alias *)datum; 642 struct cil_type *type = alias->actual; 643 if (ebitmap_set_bit(bitmap, type->value, 1)) { 644 cil_log(CIL_ERR, "Failed to set type bit\n"); 645 ebitmap_destroy(bitmap); 646 goto exit; 647 } 648 } else { 649 struct cil_type *type = (struct cil_type *)datum; 650 if (ebitmap_set_bit(bitmap, type->value, 1)) { 651 cil_log(CIL_ERR, "Failed to set type bit\n"); 652 ebitmap_destroy(bitmap); 653 goto exit; 654 } 655 } 656 657 return SEPOL_OK; 658 659 exit: 660 return rc; 661 } 662 663 static int __evaluate_user_expression(struct cil_userattribute *attr, struct cil_db *db) 664 { 665 int rc; 666 667 attr->users = cil_malloc(sizeof(*attr->users)); 668 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->users, db->num_users, db); 669 if (rc != SEPOL_OK) { 670 cil_log(CIL_ERR, "Failed to expand user attribute to bitmap\n"); 671 ebitmap_destroy(attr->users); 672 free(attr->users); 673 attr->users = NULL; 674 } 675 return rc; 676 } 677 678 static int __cil_user_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 679 { 680 int rc = SEPOL_ERR; 681 struct cil_tree_node *node = datum->nodes->head->data; 682 struct cil_userattribute *attr = NULL; 683 struct cil_user *user = NULL; 684 685 ebitmap_init(bitmap); 686 687 if (node->flavor == CIL_USERATTRIBUTE) { 688 attr = (struct cil_userattribute *)datum; 689 if (attr->users == NULL) { 690 rc = __evaluate_user_expression(attr, db); 691 if (rc != SEPOL_OK) { 692 goto exit; 693 } 694 } 695 ebitmap_union(bitmap, attr->users); 696 } else { 697 user = (struct cil_user *)datum; 698 if (ebitmap_set_bit(bitmap, user->value, 1)) { 699 cil_log(CIL_ERR, "Failed to set user bit\n"); 700 ebitmap_destroy(bitmap); 701 goto exit; 702 } 703 } 704 705 return SEPOL_OK; 706 707 exit: 708 return rc; 709 } 710 711 static int __evaluate_role_expression(struct cil_roleattribute *attr, struct cil_db *db) 712 { 713 int rc; 714 715 attr->roles = cil_malloc(sizeof(*attr->roles)); 716 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->roles, db->num_roles, db); 717 if (rc != SEPOL_OK) { 718 cil_log(CIL_ERR, "Failed to expand role attribute to bitmap\n"); 719 ebitmap_destroy(attr->roles); 720 free(attr->roles); 721 attr->roles = NULL; 722 } 723 return rc; 724 } 725 726 static int __cil_role_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 727 { 728 int rc = SEPOL_ERR; 729 struct cil_tree_node *node = datum->nodes->head->data; 730 731 ebitmap_init(bitmap); 732 733 if (node->flavor == CIL_ROLEATTRIBUTE) { 734 struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; 735 if (attr->roles == NULL) { 736 rc = __evaluate_role_expression(attr, db); 737 if (rc != SEPOL_OK) goto exit; 738 } 739 ebitmap_union(bitmap, attr->roles); 740 } else { 741 struct cil_role *role = (struct cil_role *)datum; 742 if (ebitmap_set_bit(bitmap, role->value, 1)) { 743 cil_log(CIL_ERR, "Failed to set role bit\n"); 744 ebitmap_destroy(bitmap); 745 goto exit; 746 } 747 } 748 749 return SEPOL_OK; 750 751 exit: 752 return rc; 753 } 754 755 static int __evaluate_permissionx_expression(struct cil_permissionx *permx, struct cil_db *db) 756 { 757 int rc; 758 759 permx->perms = cil_malloc(sizeof(*permx->perms)); 760 ebitmap_init(permx->perms); 761 762 rc = __cil_expr_to_bitmap(permx->expr_str, permx->perms, 0x10000, db); // max is one more than 0xFFFF 763 if (rc != SEPOL_OK) { 764 cil_log(CIL_ERR, "Failed to expand permissionx expression\n"); 765 ebitmap_destroy(permx->perms); 766 free(permx->perms); 767 permx->perms = NULL; 768 } 769 770 return rc; 771 } 772 773 static int __cil_permx_str_to_int(char *permx_str, uint16_t *val) 774 { 775 char *endptr = NULL; 776 long lval = strtol(permx_str, &endptr, 0); 777 778 if (*endptr != '\0') { 779 cil_log(CIL_ERR, "permissionx value %s not valid number\n", permx_str); 780 goto exit; 781 } 782 if (lval < 0x0000 || lval > 0xFFFF) { 783 cil_log(CIL_ERR, "permissionx value %s must be between 0x0000 and 0xFFFF\n", permx_str); 784 goto exit; 785 } 786 787 *val = (uint16_t)lval; 788 789 return SEPOL_OK; 790 791 exit: 792 return SEPOL_ERR; 793 } 794 795 static int __cil_permx_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db) 796 { 797 int rc = SEPOL_ERR; 798 uint16_t val; 799 800 rc = __cil_permx_str_to_int((char*)datum, &val); 801 if (rc != SEPOL_OK) { 802 goto exit; 803 } 804 805 ebitmap_init(bitmap); 806 if (ebitmap_set_bit(bitmap, (unsigned int)val, 1)) { 807 cil_log(CIL_ERR, "Failed to set permissionx bit\n"); 808 ebitmap_destroy(bitmap); 809 goto exit; 810 } 811 812 return SEPOL_OK; 813 814 exit: 815 return rc; 816 } 817 818 static int __cil_perm_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db) 819 { 820 struct cil_perm *perm = (struct cil_perm *)datum; 821 unsigned int value = perm->value; 822 823 ebitmap_init(bitmap); 824 if (ebitmap_set_bit(bitmap, value, 1)) { 825 cil_log(CIL_INFO, "Failed to set perm bit\n"); 826 ebitmap_destroy(bitmap); 827 return SEPOL_ERR; 828 } 829 830 return SEPOL_OK; 831 } 832 833 static int __evaluate_cat_expression(struct cil_cats *cats, struct cil_db *db) 834 { 835 int rc = SEPOL_ERR; 836 ebitmap_t bitmap; 837 struct cil_list *new; 838 struct cil_list_item *curr; 839 840 if (cats->evaluated == CIL_TRUE) { 841 return SEPOL_OK; 842 } 843 844 if (cil_verify_is_list(cats->datum_expr, CIL_CAT)) { 845 return SEPOL_OK; 846 } 847 848 ebitmap_init(&bitmap); 849 rc = __cil_expr_to_bitmap(cats->datum_expr, &bitmap, db->num_cats, db); 850 if (rc != SEPOL_OK) { 851 cil_log(CIL_ERR, "Failed to expand category expression to bitmap\n"); 852 ebitmap_destroy(&bitmap); 853 goto exit; 854 } 855 856 cil_list_init(&new, CIL_CAT); 857 858 cil_list_for_each(curr, db->catorder) { 859 struct cil_cat *cat = curr->data; 860 if (ebitmap_get_bit(&bitmap, cat->value)) { 861 cil_list_append(new, CIL_DATUM, cat); 862 } 863 } 864 865 ebitmap_destroy(&bitmap); 866 cil_list_destroy(&cats->datum_expr, CIL_FALSE); 867 cats->datum_expr = new; 868 869 cats->evaluated = CIL_TRUE; 870 871 return SEPOL_OK; 872 873 exit: 874 return rc; 875 } 876 877 static int __cil_cat_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 878 { 879 int rc = SEPOL_ERR; 880 struct cil_tree_node *node = datum->nodes->head->data; 881 882 ebitmap_init(bitmap); 883 884 if (node->flavor == CIL_CATSET) { 885 struct cil_catset *catset = (struct cil_catset *)datum; 886 struct cil_list_item *curr; 887 if (catset->cats->evaluated == CIL_FALSE) { 888 rc = __evaluate_cat_expression(catset->cats, db); 889 if (rc != SEPOL_OK) goto exit; 890 } 891 for (curr = catset->cats->datum_expr->head; curr; curr = curr->next) { 892 struct cil_cat *cat = (struct cil_cat *)curr->data; 893 if (ebitmap_set_bit(bitmap, cat->value, 1)) { 894 cil_log(CIL_ERR, "Failed to set cat bit\n"); 895 ebitmap_destroy(bitmap); 896 goto exit; 897 } 898 } 899 } else if (node->flavor == CIL_CATALIAS) { 900 struct cil_alias *alias = (struct cil_alias *)datum; 901 struct cil_cat *cat = alias->actual; 902 if (ebitmap_set_bit(bitmap, cat->value, 1)) { 903 cil_log(CIL_ERR, "Failed to set cat bit\n"); 904 ebitmap_destroy(bitmap); 905 goto exit; 906 } 907 } else { 908 struct cil_cat *cat = (struct cil_cat *)datum; 909 if (ebitmap_set_bit(bitmap, cat->value, 1)) { 910 cil_log(CIL_ERR, "Failed to set cat bit\n"); 911 ebitmap_destroy(bitmap); 912 goto exit; 913 } 914 } 915 916 return SEPOL_OK; 917 918 exit: 919 return rc; 920 } 921 922 static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap) 923 { 924 int rc = SEPOL_ERR; 925 struct cil_symtab_datum *d1 = i1->data; 926 struct cil_symtab_datum *d2 = i2->data; 927 struct cil_tree_node *n1 = d1->nodes->head->data; 928 struct cil_tree_node *n2 = d2->nodes->head->data; 929 struct cil_cat *c1 = (struct cil_cat *)d1; 930 struct cil_cat *c2 = (struct cil_cat *)d2; 931 int i; 932 933 if (n1->flavor == CIL_CATSET || n2->flavor == CIL_CATSET) { 934 cil_log(CIL_ERR, "Category sets cannont be used in a category range\n"); 935 goto exit; 936 } 937 938 if (n1->flavor == CIL_CATALIAS) { 939 struct cil_alias *alias = (struct cil_alias *)d1; 940 c1 = alias->actual; 941 } 942 943 if (n2->flavor == CIL_CATALIAS) { 944 struct cil_alias *alias = (struct cil_alias *)d2; 945 c2 = alias->actual; 946 } 947 948 if (c1->value > c2->value) { 949 cil_log(CIL_ERR, "Invalid category range\n"); 950 goto exit; 951 } 952 953 for (i = c1->value; i <= c2->value; i++) { 954 if (ebitmap_set_bit(bitmap, i, 1)) { 955 cil_log(CIL_ERR, "Failed to set cat bit\n"); 956 ebitmap_destroy(bitmap); 957 goto exit; 958 } 959 } 960 961 return SEPOL_OK; 962 963 exit: 964 return rc; 965 } 966 967 static int __cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap) 968 { 969 int rc = SEPOL_ERR; 970 char *p1 = i1->data; 971 char *p2 = i2->data; 972 uint16_t v1; 973 uint16_t v2; 974 uint32_t i; 975 976 rc = __cil_permx_str_to_int(p1, &v1); 977 if (rc != SEPOL_OK) { 978 goto exit; 979 } 980 981 rc = __cil_permx_str_to_int(p2, &v2); 982 if (rc != SEPOL_OK) { 983 goto exit; 984 } 985 986 for (i = v1; i <= v2; i++) { 987 if (ebitmap_set_bit(bitmap, i, 1)) { 988 cil_log(CIL_ERR, "Failed to set permissionx bit\n"); 989 ebitmap_destroy(bitmap); 990 goto exit; 991 } 992 } 993 994 return SEPOL_OK; 995 996 exit: 997 return rc; 998 } 999 1000 static int __cil_expr_to_bitmap_helper(struct cil_list_item *curr, enum cil_flavor flavor, ebitmap_t *bitmap, int max, struct cil_db *db) 1001 { 1002 int rc = SEPOL_ERR; 1003 1004 if (curr->flavor == CIL_DATUM) { 1005 switch (flavor) { 1006 case CIL_TYPE: 1007 rc = __cil_type_to_bitmap(curr->data, bitmap, db); 1008 break; 1009 case CIL_ROLE: 1010 rc = __cil_role_to_bitmap(curr->data, bitmap, db); 1011 break; 1012 case CIL_USER: 1013 rc = __cil_user_to_bitmap(curr->data, bitmap, db); 1014 break; 1015 case CIL_PERM: 1016 rc = __cil_perm_to_bitmap(curr->data, bitmap, db); 1017 break; 1018 case CIL_CAT: 1019 rc = __cil_cat_to_bitmap(curr->data, bitmap, db); 1020 break; 1021 default: 1022 rc = SEPOL_ERR; 1023 } 1024 } else if (curr->flavor == CIL_LIST) { 1025 struct cil_list *l = curr->data; 1026 ebitmap_init(bitmap); 1027 rc = __cil_expr_to_bitmap(l, bitmap, max, db); 1028 if (rc != SEPOL_OK) { 1029 ebitmap_destroy(bitmap); 1030 } 1031 } else if (flavor == CIL_PERMISSIONX) { 1032 // permissionx expressions aren't resolved into anything, so curr->flavor 1033 // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those 1034 rc = __cil_permx_to_bitmap(curr->data, bitmap, db); 1035 } 1036 1037 return rc; 1038 } 1039 1040 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db) 1041 { 1042 int rc = SEPOL_ERR; 1043 struct cil_list_item *curr; 1044 enum cil_flavor flavor; 1045 ebitmap_t tmp, b1, b2; 1046 1047 if (expr == NULL || expr->head == NULL) { 1048 return SEPOL_OK; 1049 } 1050 1051 curr = expr->head; 1052 flavor = expr->flavor; 1053 1054 if (curr->flavor == CIL_OP) { 1055 enum cil_flavor op = (enum cil_flavor)curr->data; 1056 1057 if (op == CIL_ALL) { 1058 ebitmap_init(&b1); /* all zeros */ 1059 rc = ebitmap_not(&tmp, &b1, max); 1060 ebitmap_destroy(&b1); 1061 if (rc != SEPOL_OK) { 1062 cil_log(CIL_INFO, "Failed to expand 'all' operator\n"); 1063 ebitmap_destroy(&tmp); 1064 goto exit; 1065 } 1066 } else if (op == CIL_RANGE) { 1067 if (flavor == CIL_CAT) { 1068 ebitmap_init(&tmp); 1069 rc = __cil_cat_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp); 1070 if (rc != SEPOL_OK) { 1071 cil_log(CIL_INFO, "Failed to expand category range\n"); 1072 ebitmap_destroy(&tmp); 1073 goto exit; 1074 } 1075 } else if (flavor == CIL_PERMISSIONX) { 1076 ebitmap_init(&tmp); 1077 rc = __cil_permissionx_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp); 1078 if (rc != SEPOL_OK) { 1079 cil_log(CIL_INFO, "Failed to expand category range\n"); 1080 ebitmap_destroy(&tmp); 1081 goto exit; 1082 } 1083 } else { 1084 cil_log(CIL_INFO, "Range operation only supported for categories permissionx\n"); 1085 rc = SEPOL_ERR; 1086 goto exit; 1087 } 1088 } else { 1089 rc = __cil_expr_to_bitmap_helper(curr->next, flavor, &b1, max, db); 1090 if (rc != SEPOL_OK) { 1091 cil_log(CIL_INFO, "Failed to get first operand bitmap\n"); 1092 goto exit; 1093 } 1094 1095 if (op == CIL_NOT) { 1096 rc = ebitmap_not(&tmp, &b1, max); 1097 ebitmap_destroy(&b1); 1098 if (rc != SEPOL_OK) { 1099 cil_log(CIL_INFO, "Failed to NOT bitmap\n"); 1100 ebitmap_destroy(&tmp); 1101 goto exit; 1102 } 1103 } else { 1104 rc = __cil_expr_to_bitmap_helper(curr->next->next, flavor, &b2, max, db); 1105 if (rc != SEPOL_OK) { 1106 cil_log(CIL_INFO, "Failed to get second operand bitmap\n"); 1107 ebitmap_destroy(&b1); 1108 goto exit; 1109 } 1110 1111 if (op == CIL_OR) { 1112 rc = ebitmap_or(&tmp, &b1, &b2); 1113 } else if (op == CIL_AND) { 1114 rc = ebitmap_and(&tmp, &b1, &b2); 1115 } else if (op == CIL_XOR) { 1116 rc = ebitmap_xor(&tmp, &b1, &b2); 1117 } else { 1118 rc = SEPOL_ERR; 1119 } 1120 ebitmap_destroy(&b1); 1121 ebitmap_destroy(&b2); 1122 if (rc != SEPOL_OK) { 1123 cil_log(CIL_INFO, "Failed to apply operator to bitmaps\n"); 1124 ebitmap_destroy(&tmp); 1125 goto exit; 1126 } 1127 } 1128 } 1129 } else { 1130 ebitmap_init(&tmp); 1131 for (;curr; curr = curr->next) { 1132 rc = __cil_expr_to_bitmap_helper(curr, flavor, &b2, max, db); 1133 if (rc != SEPOL_OK) { 1134 cil_log(CIL_INFO, "Failed to get operand in list\n"); 1135 ebitmap_destroy(&tmp); 1136 goto exit; 1137 } 1138 b1 = tmp; 1139 rc = ebitmap_or(&tmp, &b1, &b2); 1140 ebitmap_destroy(&b1); 1141 ebitmap_destroy(&b2); 1142 if (rc != SEPOL_OK) { 1143 cil_log(CIL_INFO, "Failed to OR operands in list\n"); 1144 ebitmap_destroy(&tmp); 1145 goto exit; 1146 } 1147 1148 } 1149 } 1150 1151 ebitmap_union(out, &tmp); 1152 ebitmap_destroy(&tmp); 1153 1154 return SEPOL_OK; 1155 1156 exit: 1157 return rc; 1158 } 1159 1160 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db) 1161 { 1162 int rc = SEPOL_ERR; 1163 struct cil_list_item *expr; 1164 1165 ebitmap_init(out); 1166 1167 if (expr_list == NULL) { 1168 return SEPOL_OK; 1169 } 1170 1171 cil_list_for_each(expr, expr_list) { 1172 ebitmap_t bitmap; 1173 struct cil_list *l = (struct cil_list *)expr->data; 1174 ebitmap_init(&bitmap); 1175 rc = __cil_expr_to_bitmap(l, &bitmap, max, db); 1176 if (rc != SEPOL_OK) { 1177 cil_log(CIL_INFO, "Failed to expand expression list to bitmap\n"); 1178 ebitmap_destroy(&bitmap); 1179 goto exit; 1180 } 1181 ebitmap_union(out, &bitmap); 1182 ebitmap_destroy(&bitmap); 1183 } 1184 1185 return SEPOL_OK; 1186 1187 exit: 1188 return SEPOL_ERR; 1189 } 1190 1191 static int cil_typeattribute_used(struct cil_typeattribute *attr, struct cil_db *db) 1192 { 1193 if (!attr->used) { 1194 return CIL_FALSE; 1195 } 1196 1197 if (attr->used & CIL_ATTR_EXPAND_FALSE) { 1198 return CIL_TRUE; 1199 } 1200 1201 if (attr->used & CIL_ATTR_EXPAND_TRUE) { 1202 return CIL_FALSE; 1203 } 1204 1205 if (attr->used & CIL_ATTR_CONSTRAINT) { 1206 return CIL_TRUE; 1207 } 1208 1209 if (db->attrs_expand_generated || attr->used == CIL_ATTR_NEVERALLOW) { 1210 if (strcmp(DATUM(attr)->name, GEN_REQUIRE_ATTR) == 0) { 1211 return CIL_FALSE; 1212 } else if (strstr(DATUM(attr)->name, TYPEATTR_INFIX) != NULL) { 1213 return CIL_FALSE; 1214 } 1215 1216 if (attr->used == CIL_ATTR_NEVERALLOW) { 1217 return CIL_TRUE; 1218 } 1219 } 1220 1221 if (attr->used == CIL_ATTR_AVRULE) { 1222 if (ebitmap_cardinality(attr->types) < db->attrs_expand_size) { 1223 return CIL_FALSE; 1224 } 1225 } 1226 1227 return CIL_TRUE; 1228 } 1229 1230 static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1231 { 1232 int rc = SEPOL_ERR; 1233 struct cil_db *db = extra_args; 1234 1235 switch (node->flavor) { 1236 case CIL_BLOCK: { 1237 struct cil_block *blk = node->data; 1238 if (blk->is_abstract == CIL_TRUE) { 1239 *finished = CIL_TREE_SKIP_HEAD; 1240 } 1241 break; 1242 } 1243 case CIL_MACRO: { 1244 *finished = CIL_TREE_SKIP_HEAD; 1245 break; 1246 } 1247 case CIL_TYPEATTRIBUTE: { 1248 struct cil_typeattribute *attr = node->data; 1249 if (attr->types == NULL) { 1250 rc = __evaluate_type_expression(attr, db); 1251 if (rc != SEPOL_OK) goto exit; 1252 } 1253 attr->used = cil_typeattribute_used(attr, db); 1254 break; 1255 } 1256 case CIL_ROLEATTRIBUTE: { 1257 struct cil_roleattribute *attr = node->data; 1258 if (attr->roles == NULL) { 1259 rc = __evaluate_role_expression(attr, db); 1260 if (rc != SEPOL_OK) goto exit; 1261 } 1262 break; 1263 } 1264 case CIL_AVRULEX: { 1265 struct cil_avrule *rule = node->data; 1266 if (rule->perms.x.permx_str == NULL) { 1267 rc = __evaluate_permissionx_expression(rule->perms.x.permx, db); 1268 if (rc != SEPOL_OK) goto exit; 1269 } 1270 break; 1271 } 1272 case CIL_PERMISSIONX: { 1273 struct cil_permissionx *permx = node->data; 1274 rc = __evaluate_permissionx_expression(permx, db); 1275 if (rc != SEPOL_OK) goto exit; 1276 break; 1277 } 1278 case CIL_USERATTRIBUTE: { 1279 struct cil_userattribute *attr = node->data; 1280 if (attr->users == NULL) { 1281 rc = __evaluate_user_expression(attr, db); 1282 if (rc != SEPOL_OK) { 1283 goto exit; 1284 } 1285 } 1286 break; 1287 } 1288 default: 1289 break; 1290 } 1291 1292 return SEPOL_OK; 1293 1294 exit: 1295 return rc; 1296 } 1297 1298 static int __cil_role_assign_types(struct cil_role *role, struct cil_symtab_datum *datum) 1299 { 1300 struct cil_tree_node *node = datum->nodes->head->data; 1301 1302 if (role->types == NULL) { 1303 role->types = cil_malloc(sizeof(*role->types)); 1304 ebitmap_init(role->types); 1305 } 1306 1307 if (node->flavor == CIL_TYPE) { 1308 struct cil_type *type = (struct cil_type *)datum; 1309 if (ebitmap_set_bit(role->types, type->value, 1)) { 1310 cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n"); 1311 goto exit; 1312 } 1313 } else if (node->flavor == CIL_TYPEALIAS) { 1314 struct cil_alias *alias = (struct cil_alias *)datum; 1315 struct cil_type *type = alias->actual; 1316 if (ebitmap_set_bit(role->types, type->value, 1)) { 1317 cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n"); 1318 goto exit; 1319 } 1320 } else if (node->flavor == CIL_TYPEATTRIBUTE) { 1321 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 1322 ebitmap_union(role->types, attr->types); 1323 } 1324 1325 return SEPOL_OK; 1326 1327 exit: 1328 return SEPOL_ERR; 1329 } 1330 1331 static int __cil_post_db_roletype_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1332 { 1333 int rc = SEPOL_ERR; 1334 struct cil_db *db = extra_args; 1335 1336 switch (node->flavor) { 1337 case CIL_BLOCK: { 1338 struct cil_block *blk = node->data; 1339 if (blk->is_abstract == CIL_TRUE) { 1340 *finished = CIL_TREE_SKIP_HEAD; 1341 } 1342 break; 1343 } 1344 case CIL_MACRO: { 1345 *finished = CIL_TREE_SKIP_HEAD; 1346 break; 1347 } 1348 case CIL_ROLETYPE: { 1349 struct cil_roletype *roletype = node->data; 1350 struct cil_symtab_datum *role_datum = roletype->role; 1351 struct cil_symtab_datum *type_datum = roletype->type; 1352 struct cil_tree_node *role_node = role_datum->nodes->head->data; 1353 1354 if (role_node->flavor == CIL_ROLEATTRIBUTE) { 1355 struct cil_roleattribute *attr = roletype->role; 1356 ebitmap_node_t *rnode; 1357 unsigned int i; 1358 1359 ebitmap_for_each_bit(attr->roles, rnode, i) { 1360 struct cil_role *role = NULL; 1361 1362 if (!ebitmap_get_bit(attr->roles, i)) { 1363 continue; 1364 } 1365 1366 role = db->val_to_role[i]; 1367 1368 rc = __cil_role_assign_types(role, type_datum); 1369 if (rc != SEPOL_OK) { 1370 goto exit; 1371 } 1372 } 1373 } else { 1374 struct cil_role *role = roletype->role; 1375 1376 rc = __cil_role_assign_types(role, type_datum); 1377 if (rc != SEPOL_OK) { 1378 goto exit; 1379 } 1380 } 1381 break; 1382 } 1383 default: 1384 break; 1385 } 1386 1387 return SEPOL_OK; 1388 exit: 1389 cil_log(CIL_INFO, "cil_post_db_roletype_helper failed\n"); 1390 return rc; 1391 } 1392 1393 static int __cil_user_assign_roles(struct cil_user *user, struct cil_symtab_datum *datum) 1394 { 1395 struct cil_tree_node *node = datum->nodes->head->data; 1396 struct cil_role *role = NULL; 1397 struct cil_roleattribute *attr = NULL; 1398 1399 if (user->roles == NULL) { 1400 user->roles = cil_malloc(sizeof(*user->roles)); 1401 ebitmap_init(user->roles); 1402 } 1403 1404 if (node->flavor == CIL_ROLE) { 1405 role = (struct cil_role *)datum; 1406 if (ebitmap_set_bit(user->roles, role->value, 1)) { 1407 cil_log(CIL_INFO, "Failed to set bit in user roles bitmap\n"); 1408 goto exit; 1409 } 1410 } else if (node->flavor == CIL_ROLEATTRIBUTE) { 1411 attr = (struct cil_roleattribute *)datum; 1412 ebitmap_union(user->roles, attr->roles); 1413 } 1414 1415 return SEPOL_OK; 1416 1417 exit: 1418 return SEPOL_ERR; 1419 } 1420 1421 static int __cil_post_db_userrole_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1422 { 1423 int rc = SEPOL_ERR; 1424 struct cil_db *db = extra_args; 1425 struct cil_block *blk = NULL; 1426 struct cil_userrole *userrole = NULL; 1427 struct cil_symtab_datum *user_datum = NULL; 1428 struct cil_symtab_datum *role_datum = NULL; 1429 struct cil_tree_node *user_node = NULL; 1430 struct cil_userattribute *u_attr = NULL; 1431 unsigned int i; 1432 struct cil_user *user = NULL; 1433 ebitmap_node_t *unode = NULL; 1434 1435 switch (node->flavor) { 1436 case CIL_BLOCK: { 1437 blk = node->data; 1438 if (blk->is_abstract == CIL_TRUE) { 1439 *finished = CIL_TREE_SKIP_HEAD; 1440 } 1441 break; 1442 } 1443 case CIL_MACRO: { 1444 *finished = CIL_TREE_SKIP_HEAD; 1445 break; 1446 } 1447 case CIL_USERROLE: { 1448 userrole = node->data; 1449 user_datum = userrole->user; 1450 role_datum = userrole->role; 1451 user_node = user_datum->nodes->head->data; 1452 1453 if (user_node->flavor == CIL_USERATTRIBUTE) { 1454 u_attr = userrole->user; 1455 1456 ebitmap_for_each_bit(u_attr->users, unode, i) { 1457 if (!ebitmap_get_bit(u_attr->users, i)) { 1458 continue; 1459 } 1460 1461 user = db->val_to_user[i]; 1462 1463 rc = __cil_user_assign_roles(user, role_datum); 1464 if (rc != SEPOL_OK) { 1465 goto exit; 1466 } 1467 } 1468 } else { 1469 user = userrole->user; 1470 1471 rc = __cil_user_assign_roles(user, role_datum); 1472 if (rc != SEPOL_OK) { 1473 goto exit; 1474 } 1475 } 1476 1477 break; 1478 } 1479 default: 1480 break; 1481 } 1482 1483 return SEPOL_OK; 1484 exit: 1485 cil_log(CIL_INFO, "cil_post_db_userrole_helper failed\n"); 1486 return rc; 1487 } 1488 1489 static int __evaluate_level_expression(struct cil_level *level, struct cil_db *db) 1490 { 1491 if (level->cats != NULL) { 1492 return __evaluate_cat_expression(level->cats, db); 1493 } 1494 1495 return SEPOL_OK; 1496 } 1497 1498 static int __evaluate_levelrange_expression(struct cil_levelrange *levelrange, struct cil_db *db) 1499 { 1500 int rc = SEPOL_OK; 1501 1502 if (levelrange->low != NULL && levelrange->low->cats != NULL) { 1503 rc = __evaluate_cat_expression(levelrange->low->cats, db); 1504 if (rc != SEPOL_OK) { 1505 goto exit; 1506 } 1507 } 1508 if (levelrange->high != NULL && levelrange->high->cats != NULL) { 1509 rc = __evaluate_cat_expression(levelrange->high->cats, db); 1510 if (rc != SEPOL_OK) { 1511 goto exit; 1512 } 1513 } 1514 1515 exit: 1516 return rc; 1517 } 1518 1519 static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1520 { 1521 int rc = SEPOL_ERR; 1522 struct cil_db *db = extra_args; 1523 1524 switch (node->flavor) { 1525 case CIL_BLOCK: { 1526 struct cil_block *blk = node->data; 1527 if (blk->is_abstract == CIL_TRUE) { 1528 *finished = CIL_TREE_SKIP_HEAD; 1529 } 1530 break; 1531 } 1532 case CIL_MACRO: { 1533 *finished = CIL_TREE_SKIP_HEAD; 1534 break; 1535 } 1536 case CIL_CATSET: { 1537 struct cil_catset *catset = node->data; 1538 rc = __evaluate_cat_expression(catset->cats, db); 1539 if (rc != SEPOL_OK) { 1540 goto exit; 1541 } 1542 break; 1543 } 1544 case CIL_SENSCAT: { 1545 struct cil_senscat *senscat = node->data; 1546 rc = __evaluate_cat_expression(senscat->cats, db); 1547 if (rc != SEPOL_OK) { 1548 goto exit; 1549 } 1550 break; 1551 } 1552 case CIL_LEVEL: { 1553 rc = __evaluate_level_expression(node->data, db); 1554 if (rc != SEPOL_OK) { 1555 goto exit; 1556 } 1557 break; 1558 } 1559 case CIL_LEVELRANGE: { 1560 rc = __evaluate_levelrange_expression(node->data, db); 1561 if (rc != SEPOL_OK) { 1562 goto exit; 1563 } 1564 break; 1565 } 1566 case CIL_USER: { 1567 struct cil_user *user = node->data; 1568 rc = __evaluate_level_expression(user->dftlevel, db); 1569 if (rc != SEPOL_OK) { 1570 goto exit; 1571 } 1572 rc = __evaluate_levelrange_expression(user->range, db); 1573 if (rc != SEPOL_OK) { 1574 goto exit; 1575 } 1576 break; 1577 } 1578 case CIL_SELINUXUSERDEFAULT: 1579 case CIL_SELINUXUSER: { 1580 struct cil_selinuxuser *selinuxuser = node->data; 1581 rc = __evaluate_levelrange_expression(selinuxuser->range, db); 1582 if (rc != SEPOL_OK) { 1583 goto exit; 1584 } 1585 break; 1586 } 1587 case CIL_RANGETRANSITION: { 1588 struct cil_rangetransition *rangetrans = node->data; 1589 rc = __evaluate_levelrange_expression(rangetrans->range, db); 1590 if (rc != SEPOL_OK) { 1591 goto exit; 1592 } 1593 break; 1594 } 1595 case CIL_CONTEXT: { 1596 struct cil_context *context = node->data; 1597 rc = __evaluate_levelrange_expression(context->range, db); 1598 if (rc != SEPOL_OK) { 1599 goto exit; 1600 } 1601 break; 1602 } 1603 case CIL_SIDCONTEXT: { 1604 struct cil_sidcontext *sidcontext = node->data; 1605 rc = __evaluate_levelrange_expression(sidcontext->context->range, db); 1606 if (rc != SEPOL_OK) { 1607 goto exit; 1608 } 1609 break; 1610 } 1611 case CIL_FILECON: { 1612 struct cil_filecon *filecon = node->data; 1613 if (filecon->context) { 1614 rc = __evaluate_levelrange_expression(filecon->context->range, db); 1615 if (rc != SEPOL_OK) { 1616 goto exit; 1617 } 1618 } 1619 break; 1620 } 1621 case CIL_PORTCON: { 1622 struct cil_portcon *portcon = node->data; 1623 rc = __evaluate_levelrange_expression(portcon->context->range, db); 1624 if (rc != SEPOL_OK) { 1625 goto exit; 1626 } 1627 break; 1628 } 1629 case CIL_NODECON: { 1630 struct cil_nodecon *nodecon = node->data; 1631 rc = __evaluate_levelrange_expression(nodecon->context->range, db); 1632 if (rc != SEPOL_OK) { 1633 goto exit; 1634 } 1635 break; 1636 } 1637 case CIL_GENFSCON: { 1638 struct cil_genfscon *genfscon = node->data; 1639 rc = __evaluate_levelrange_expression(genfscon->context->range, db); 1640 if (rc != SEPOL_OK) { 1641 goto exit; 1642 } 1643 break; 1644 } 1645 case CIL_NETIFCON: { 1646 struct cil_netifcon *netifcon = node->data; 1647 rc = __evaluate_levelrange_expression(netifcon->if_context->range, db); 1648 if (rc != SEPOL_OK) { 1649 goto exit; 1650 } 1651 rc = __evaluate_levelrange_expression(netifcon->packet_context->range, db); 1652 if (rc != SEPOL_OK) { 1653 goto exit; 1654 } 1655 break; 1656 } 1657 case CIL_PIRQCON: { 1658 struct cil_pirqcon *pirqcon = node->data; 1659 rc = __evaluate_levelrange_expression(pirqcon->context->range, db); 1660 if (rc != SEPOL_OK) { 1661 goto exit; 1662 } 1663 break; 1664 } 1665 case CIL_IOMEMCON: { 1666 struct cil_iomemcon *iomemcon = node->data; 1667 rc = __evaluate_levelrange_expression(iomemcon->context->range, db); 1668 if (rc != SEPOL_OK) { 1669 goto exit; 1670 } 1671 break; 1672 } 1673 case CIL_IOPORTCON: { 1674 struct cil_ioportcon *ioportcon = node->data; 1675 rc = __evaluate_levelrange_expression(ioportcon->context->range, db); 1676 if (rc != SEPOL_OK) { 1677 goto exit; 1678 } 1679 break; 1680 } 1681 case CIL_PCIDEVICECON: { 1682 struct cil_pcidevicecon *pcidevicecon = node->data; 1683 rc = __evaluate_levelrange_expression(pcidevicecon->context->range, db); 1684 if (rc != SEPOL_OK) { 1685 goto exit; 1686 } 1687 break; 1688 } 1689 case CIL_DEVICETREECON: { 1690 struct cil_devicetreecon *devicetreecon = node->data; 1691 rc = __evaluate_levelrange_expression(devicetreecon->context->range, db); 1692 if (rc != SEPOL_OK) { 1693 goto exit; 1694 } 1695 break; 1696 } 1697 case CIL_FSUSE: { 1698 struct cil_fsuse *fsuse = node->data; 1699 rc = __evaluate_levelrange_expression(fsuse->context->range, db); 1700 if (rc != SEPOL_OK) { 1701 goto exit; 1702 } 1703 break; 1704 } 1705 default: 1706 break; 1707 } 1708 1709 return SEPOL_OK; 1710 1711 exit: 1712 return rc; 1713 } 1714 1715 struct perm_to_list { 1716 enum cil_flavor flavor; 1717 ebitmap_t *perms; 1718 struct cil_list *new_list; 1719 }; 1720 1721 static int __perm_bits_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 1722 { 1723 struct perm_to_list *perm_args = (struct perm_to_list *)args; 1724 ebitmap_t *perms = perm_args->perms; 1725 struct cil_list *new_list = perm_args->new_list; 1726 struct cil_perm *perm = (struct cil_perm *)d; 1727 unsigned int value = perm->value; 1728 1729 if (!ebitmap_get_bit(perms, value)) { 1730 return SEPOL_OK; 1731 } 1732 1733 cil_list_append(new_list, CIL_DATUM, d); 1734 1735 return SEPOL_OK; 1736 } 1737 1738 static int __evaluate_perm_expression(struct cil_list *perms, enum cil_flavor flavor, symtab_t *class_symtab, symtab_t *common_symtab, unsigned int num_perms, struct cil_list **new_list, struct cil_db *db) 1739 { 1740 int rc = SEPOL_ERR; 1741 struct perm_to_list args; 1742 ebitmap_t bitmap; 1743 1744 if (cil_verify_is_list(perms, CIL_PERM)) { 1745 return SEPOL_OK; 1746 } 1747 1748 ebitmap_init(&bitmap); 1749 rc = __cil_expr_to_bitmap(perms, &bitmap, num_perms, db); 1750 if (rc != SEPOL_OK) { 1751 ebitmap_destroy(&bitmap); 1752 goto exit; 1753 } 1754 1755 cil_list_init(new_list, flavor); 1756 1757 args.flavor = flavor; 1758 args.perms = &bitmap; 1759 args.new_list = *new_list; 1760 1761 cil_symtab_map(class_symtab, __perm_bits_to_list, &args); 1762 1763 if (common_symtab != NULL) { 1764 cil_symtab_map(common_symtab, __perm_bits_to_list, &args); 1765 } 1766 1767 ebitmap_destroy(&bitmap); 1768 return SEPOL_OK; 1769 1770 exit: 1771 return rc; 1772 } 1773 1774 static int __evaluate_classperms(struct cil_classperms *cp, struct cil_db *db) 1775 { 1776 int rc = SEPOL_ERR; 1777 struct cil_class *class = cp->class; 1778 struct cil_class *common = class->common; 1779 symtab_t *common_symtab = NULL; 1780 struct cil_list *new_list = NULL; 1781 1782 if (common) { 1783 common_symtab = &common->perms; 1784 } 1785 1786 rc = __evaluate_perm_expression(cp->perms, CIL_PERM, &class->perms, common_symtab, class->num_perms, &new_list, db); 1787 if (rc != SEPOL_OK) { 1788 goto exit; 1789 } 1790 1791 if (new_list == NULL) { 1792 return SEPOL_OK; 1793 } 1794 1795 cil_list_destroy(&cp->perms, CIL_FALSE); 1796 1797 cp->perms = new_list; 1798 1799 return SEPOL_OK; 1800 1801 exit: 1802 return rc; 1803 } 1804 1805 static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db *db) 1806 { 1807 int rc = SEPOL_ERR; 1808 struct cil_list_item *curr; 1809 1810 cil_list_for_each(curr, classperms) { 1811 if (curr->flavor == CIL_CLASSPERMS) { 1812 struct cil_classperms *cp = curr->data; 1813 if (FLAVOR(cp->class) == CIL_CLASS) { 1814 rc = __evaluate_classperms(cp, db); 1815 if (rc != SEPOL_OK) { 1816 goto exit; 1817 } 1818 } else { /* MAP */ 1819 struct cil_list_item *i = NULL; 1820 cil_list_for_each(i, cp->perms) { 1821 struct cil_perm *cmp = i->data; 1822 rc = __evaluate_classperms_list(cmp->classperms, db); 1823 if (rc != SEPOL_OK) { 1824 goto exit; 1825 } 1826 } 1827 } 1828 } else { /* SET */ 1829 struct cil_classperms_set *cp_set = curr->data; 1830 struct cil_classpermission *cp = cp_set->set; 1831 rc = __evaluate_classperms_list(cp->classperms, db); 1832 if (rc != SEPOL_OK) { 1833 goto exit; 1834 } 1835 } 1836 } 1837 1838 return SEPOL_OK; 1839 1840 exit: 1841 return rc; 1842 } 1843 1844 struct class_map_args { 1845 struct cil_db *db; 1846 int rc; 1847 }; 1848 1849 static int __evaluate_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 1850 { 1851 struct class_map_args *map_args = args; 1852 struct cil_perm *cmp = (struct cil_perm *)d; 1853 1854 int rc = __evaluate_classperms_list(cmp->classperms, map_args->db); 1855 1856 if (rc != SEPOL_OK) { 1857 map_args->rc = rc; 1858 } 1859 1860 return SEPOL_OK; 1861 } 1862 1863 static int __evaluate_map_class(struct cil_class *mc, struct cil_db *db) 1864 { 1865 struct class_map_args map_args; 1866 1867 map_args.db = db; 1868 map_args.rc = SEPOL_OK; 1869 cil_symtab_map(&mc->perms, __evaluate_map_perm_classperms, &map_args); 1870 1871 return map_args.rc; 1872 } 1873 1874 static int __cil_post_db_classperms_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1875 { 1876 int rc = SEPOL_ERR; 1877 struct cil_db *db = extra_args; 1878 1879 switch (node->flavor) { 1880 case CIL_BLOCK: { 1881 struct cil_block *blk = node->data; 1882 if (blk->is_abstract == CIL_TRUE) { 1883 *finished = CIL_TREE_SKIP_HEAD; 1884 } 1885 break; 1886 } 1887 case CIL_MACRO: 1888 *finished = CIL_TREE_SKIP_HEAD; 1889 break; 1890 case CIL_MAP_CLASS: { 1891 rc = __evaluate_map_class(node->data, db); 1892 if (rc != SEPOL_OK) { 1893 goto exit; 1894 } 1895 break; 1896 } 1897 case CIL_CLASSPERMISSION: { 1898 struct cil_classpermission *cp = node->data; 1899 rc = __evaluate_classperms_list(cp->classperms, db); 1900 if (rc != SEPOL_OK) { 1901 goto exit; 1902 } 1903 break; 1904 } 1905 case CIL_AVRULE: { 1906 struct cil_avrule *avrule = node->data; 1907 rc = __evaluate_classperms_list(avrule->perms.classperms, db); 1908 if (rc != SEPOL_OK) { 1909 goto exit; 1910 } 1911 break; 1912 } 1913 case CIL_CONSTRAIN: 1914 case CIL_MLSCONSTRAIN: { 1915 struct cil_constrain *constrain = node->data; 1916 rc = __evaluate_classperms_list(constrain->classperms, db); 1917 if (rc != SEPOL_OK) { 1918 goto exit; 1919 } 1920 break; 1921 } 1922 default: 1923 break; 1924 } 1925 1926 return SEPOL_OK; 1927 1928 exit: 1929 return rc; 1930 } 1931 1932 static int cil_post_db(struct cil_db *db) 1933 { 1934 int rc = SEPOL_ERR; 1935 1936 rc = cil_tree_walk(db->ast->root, __cil_post_db_count_helper, NULL, NULL, db); 1937 if (rc != SEPOL_OK) { 1938 cil_log(CIL_INFO, "Failure during cil databse count helper\n"); 1939 goto exit; 1940 } 1941 1942 rc = cil_tree_walk(db->ast->root, __cil_post_db_array_helper, NULL, NULL, db); 1943 if (rc != SEPOL_OK) { 1944 cil_log(CIL_INFO, "Failure during cil database array helper\n"); 1945 goto exit; 1946 } 1947 1948 rc = cil_tree_walk(db->ast->root, __cil_post_db_attr_helper, NULL, NULL, db); 1949 if (rc != SEPOL_OK) { 1950 cil_log(CIL_INFO, "Failed to create attribute bitmaps\n"); 1951 goto exit; 1952 } 1953 1954 rc = cil_tree_walk(db->ast->root, __cil_post_db_roletype_helper, NULL, NULL, db); 1955 if (rc != SEPOL_OK) { 1956 cil_log(CIL_INFO, "Failed during roletype association\n"); 1957 goto exit; 1958 } 1959 1960 rc = cil_tree_walk(db->ast->root, __cil_post_db_userrole_helper, NULL, NULL, db); 1961 if (rc != SEPOL_OK) { 1962 cil_log(CIL_INFO, "Failed during userrole association\n"); 1963 goto exit; 1964 } 1965 1966 rc = cil_tree_walk(db->ast->root, __cil_post_db_classperms_helper, NULL, NULL, db); 1967 if (rc != SEPOL_OK) { 1968 cil_log(CIL_INFO, "Failed to evaluate class mapping permissions expressions\n"); 1969 goto exit; 1970 } 1971 1972 rc = cil_tree_walk(db->ast->root, __cil_post_db_cat_helper, NULL, NULL, db); 1973 if (rc != SEPOL_OK) { 1974 cil_log(CIL_INFO, "Failed to evaluate category expressions\n"); 1975 goto exit; 1976 } 1977 1978 qsort(db->netifcon->array, db->netifcon->count, sizeof(db->netifcon->array), cil_post_netifcon_compare); 1979 qsort(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare); 1980 qsort(db->portcon->array, db->portcon->count, sizeof(db->portcon->array), cil_post_portcon_compare); 1981 qsort(db->nodecon->array, db->nodecon->count, sizeof(db->nodecon->array), cil_post_nodecon_compare); 1982 qsort(db->fsuse->array, db->fsuse->count, sizeof(db->fsuse->array), cil_post_fsuse_compare); 1983 qsort(db->filecon->array, db->filecon->count, sizeof(db->filecon->array), cil_post_filecon_compare); 1984 qsort(db->pirqcon->array, db->pirqcon->count, sizeof(db->pirqcon->array), cil_post_pirqcon_compare); 1985 qsort(db->iomemcon->array, db->iomemcon->count, sizeof(db->iomemcon->array), cil_post_iomemcon_compare); 1986 qsort(db->ioportcon->array, db->ioportcon->count, sizeof(db->ioportcon->array), cil_post_ioportcon_compare); 1987 qsort(db->pcidevicecon->array, db->pcidevicecon->count, sizeof(db->pcidevicecon->array), cil_post_pcidevicecon_compare); 1988 qsort(db->devicetreecon->array, db->devicetreecon->count, sizeof(db->devicetreecon->array), cil_post_devicetreecon_compare); 1989 1990 exit: 1991 return rc; 1992 } 1993 1994 static int cil_post_verify(struct cil_db *db) 1995 { 1996 int rc = SEPOL_ERR; 1997 int avrule_cnt = 0; 1998 int handleunknown = -1; 1999 int mls = -1; 2000 int nseuserdflt = 0; 2001 int pass = 0; 2002 struct cil_args_verify extra_args; 2003 struct cil_complex_symtab csymtab; 2004 2005 cil_complex_symtab_init(&csymtab, CIL_CLASS_SYM_SIZE); 2006 2007 extra_args.db = db; 2008 extra_args.csymtab = &csymtab; 2009 extra_args.avrule_cnt = &avrule_cnt; 2010 extra_args.handleunknown = &handleunknown; 2011 extra_args.mls = &mls; 2012 extra_args.nseuserdflt = &nseuserdflt; 2013 extra_args.pass = &pass; 2014 2015 for (pass = 0; pass < 2; pass++) { 2016 rc = cil_tree_walk(db->ast->root, __cil_verify_helper, NULL, NULL, &extra_args); 2017 if (rc != SEPOL_OK) { 2018 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2019 goto exit; 2020 } 2021 } 2022 2023 if (db->handle_unknown == -1) { 2024 if (handleunknown == -1) { 2025 db->handle_unknown = SEPOL_DENY_UNKNOWN; 2026 } else { 2027 db->handle_unknown = handleunknown; 2028 } 2029 } 2030 2031 if (db->mls == -1) { 2032 if (mls == -1) { 2033 db->mls = CIL_FALSE; 2034 } else { 2035 db->mls = mls; 2036 } 2037 } 2038 2039 if (avrule_cnt == 0) { 2040 cil_log(CIL_ERR, "Policy must include at least one avrule\n"); 2041 rc = SEPOL_ERR; 2042 goto exit; 2043 } 2044 2045 if (nseuserdflt > 1) { 2046 cil_log(CIL_ERR, "Policy cannot contain more than one selinuxuserdefault, found: %d\n", nseuserdflt); 2047 rc = SEPOL_ERR; 2048 goto exit; 2049 } 2050 2051 exit: 2052 cil_complex_symtab_destroy(&csymtab); 2053 return rc; 2054 } 2055 2056 static int cil_pre_verify(struct cil_db *db) 2057 { 2058 int rc = SEPOL_ERR; 2059 struct cil_args_verify extra_args; 2060 2061 extra_args.db = db; 2062 2063 rc = cil_tree_walk(db->ast->root, __cil_pre_verify_helper, NULL, NULL, &extra_args); 2064 if (rc != SEPOL_OK) { 2065 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2066 goto exit; 2067 } 2068 2069 exit: 2070 return rc; 2071 } 2072 2073 int cil_post_process(struct cil_db *db) 2074 { 2075 int rc = SEPOL_ERR; 2076 2077 rc = cil_pre_verify(db); 2078 if (rc != SEPOL_OK) { 2079 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2080 goto exit; 2081 } 2082 2083 rc = cil_post_db(db); 2084 if (rc != SEPOL_OK) { 2085 cil_log(CIL_ERR, "Failed post db handling\n"); 2086 goto exit; 2087 } 2088 2089 rc = cil_post_verify(db); 2090 if (rc != SEPOL_OK) { 2091 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2092 goto exit; 2093 } 2094 2095 exit: 2096 return rc; 2097 2098 } 2099