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