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