1 /* 2 * Copyright 2011 Tresys Technology, LLC. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * The views and conclusions contained in the software and documentation are those 26 * of the authors and should not be interpreted as representing official policies, 27 * either expressed or implied, of Tresys Technology, LLC. 28 */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <stdint.h> 34 #include <unistd.h> 35 36 #include <sepol/policydb/conditional.h> 37 #include <sepol/errcodes.h> 38 39 #include "cil_internal.h" 40 #include "cil_flavor.h" 41 #include "cil_log.h" 42 #include "cil_mem.h" 43 #include "cil_tree.h" 44 #include "cil_list.h" 45 #include "cil_post.h" 46 #include "cil_policy.h" 47 #include "cil_verify.h" 48 #include "cil_symtab.h" 49 50 #define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/src/module_to_cil.c */ 51 #define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/src/module_to_cil.c */ 52 53 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db); 54 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db); 55 56 static int cats_compare(struct cil_cats *a, struct cil_cats *b) 57 { 58 struct cil_list_item *i, *j; 59 int rc; 60 61 if (a == b) return 0; 62 if (!a) return -1; 63 if (!b) return 1; 64 65 /* Expects cat expression to have been evaluated */ 66 cil_list_for_each(i, a->datum_expr) { 67 cil_list_for_each(j, b->datum_expr) { 68 rc = strcmp(DATUM(i->data)->fqn, DATUM(j->data)->fqn); 69 if (!rc) return rc; 70 } 71 } 72 return 0; 73 } 74 75 static int level_compare(struct cil_level *a, struct cil_level *b) 76 { 77 int rc; 78 79 if (a == b) return 0; 80 if (!a) return -1; 81 if (!b) return 1; 82 83 if (a->sens != b->sens) { 84 rc = strcmp(DATUM(a->sens)->fqn, DATUM(b->sens)->fqn); 85 if (rc != 0) return rc; 86 } 87 if (a->cats != b->cats) { 88 return cats_compare(a->cats, b->cats); 89 } 90 return 0; 91 } 92 93 static int range_compare(struct cil_levelrange *a, struct cil_levelrange *b) 94 { 95 int rc; 96 97 if (a == b) return 0; 98 if (!a) return -1; 99 if (!b) return 1; 100 101 if (a->low != b->low) { 102 rc = level_compare(a->low, b->low); 103 if (rc != 0) return rc; 104 } 105 if (a->high != b->high) { 106 return level_compare(a->high, b->high); 107 } 108 return 0; 109 } 110 111 static int context_compare(struct cil_context *a, struct cil_context *b) 112 { 113 int rc; 114 115 if (a->user != b->user) { 116 rc = strcmp(DATUM(a->user)->fqn, DATUM(b->user)->fqn); 117 if (rc != 0) return rc; 118 } 119 if (a->role != b->role) { 120 rc = strcmp(DATUM(a->role)->fqn, DATUM(b->role)->fqn); 121 if (rc != 0) return rc; 122 } 123 if (a->type != b->type) { 124 rc = strcmp(DATUM(a->type)->fqn, DATUM(b->type)->fqn); 125 if (rc != 0) return rc; 126 } 127 if (a->range != b->range) { 128 return range_compare(a->range, b->range); 129 } 130 return 0; 131 } 132 133 static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor) 134 { 135 struct cil_list_item *curr; 136 137 cil_list_for_each(curr, list) { 138 switch (curr->flavor) { 139 case CIL_LIST: 140 return CIL_FALSE; 141 break; 142 case CIL_OP: 143 return CIL_FALSE; 144 break; 145 default: 146 if (flavor == CIL_CAT) { 147 struct cil_symtab_datum *d = curr->data; 148 struct cil_tree_node *n = d->nodes->head->data; 149 if (n->flavor == CIL_CATSET) { 150 return CIL_FALSE; 151 } 152 } 153 break; 154 } 155 } 156 return CIL_TRUE; 157 } 158 159 void cil_post_fc_fill_data(struct fc_data *fc, char *path) 160 { 161 int c = 0; 162 fc->meta = 0; 163 fc->stem_len = 0; 164 fc->str_len = 0; 165 166 while (path[c] != '\0') { 167 switch (path[c]) { 168 case '.': 169 case '^': 170 case '$': 171 case '?': 172 case '*': 173 case '+': 174 case '|': 175 case '[': 176 case '(': 177 case '{': 178 fc->meta = 1; 179 break; 180 case '\\': 181 c++; 182 /* FALLTHRU */ 183 default: 184 if (!fc->meta) { 185 fc->stem_len++; 186 } 187 break; 188 } 189 fc->str_len++; 190 c++; 191 } 192 } 193 194 int cil_post_filecon_compare(const void *a, const void *b) 195 { 196 int rc = 0; 197 struct cil_filecon *a_filecon = *(struct cil_filecon**)a; 198 struct cil_filecon *b_filecon = *(struct cil_filecon**)b; 199 struct fc_data *a_data = cil_malloc(sizeof(*a_data)); 200 struct fc_data *b_data = cil_malloc(sizeof(*b_data)); 201 char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1); 202 a_path[0] = '\0'; 203 char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1); 204 b_path[0] = '\0'; 205 strcat(a_path, a_filecon->path_str); 206 strcat(b_path, b_filecon->path_str); 207 cil_post_fc_fill_data(a_data, a_path); 208 cil_post_fc_fill_data(b_data, b_path); 209 if (a_data->meta && !b_data->meta) { 210 rc = -1; 211 } else if (b_data->meta && !a_data->meta) { 212 rc = 1; 213 } else if (a_data->stem_len < b_data->stem_len) { 214 rc = -1; 215 } else if (b_data->stem_len < a_data->stem_len) { 216 rc = 1; 217 } else if (a_data->str_len < b_data->str_len) { 218 rc = -1; 219 } else if (b_data->str_len < a_data->str_len) { 220 rc = 1; 221 } else if (a_filecon->type < b_filecon->type) { 222 rc = -1; 223 } else if (b_filecon->type < a_filecon->type) { 224 rc = 1; 225 } else { 226 rc = strcmp(a_filecon->path_str, b_filecon->path_str); 227 } 228 229 free(a_path); 230 free(b_path); 231 free(a_data); 232 free(b_data); 233 234 return rc; 235 } 236 237 int cil_post_ibpkeycon_compare(const void *a, const void *b) 238 { 239 int rc = SEPOL_ERR; 240 struct cil_ibpkeycon *aibpkeycon = *(struct cil_ibpkeycon **)a; 241 struct cil_ibpkeycon *bibpkeycon = *(struct cil_ibpkeycon **)b; 242 243 rc = strcmp(aibpkeycon->subnet_prefix_str, bibpkeycon->subnet_prefix_str); 244 if (rc) 245 return rc; 246 247 rc = (aibpkeycon->pkey_high - aibpkeycon->pkey_low) 248 - (bibpkeycon->pkey_high - bibpkeycon->pkey_low); 249 if (rc == 0) { 250 if (aibpkeycon->pkey_low < bibpkeycon->pkey_low) 251 rc = -1; 252 else if (bibpkeycon->pkey_low < aibpkeycon->pkey_low) 253 rc = 1; 254 } 255 256 return rc; 257 } 258 259 int cil_post_portcon_compare(const void *a, const void *b) 260 { 261 int rc = SEPOL_ERR; 262 struct cil_portcon *aportcon = *(struct cil_portcon**)a; 263 struct cil_portcon *bportcon = *(struct cil_portcon**)b; 264 265 rc = (aportcon->port_high - aportcon->port_low) 266 - (bportcon->port_high - bportcon->port_low); 267 if (rc == 0) { 268 if (aportcon->port_low < bportcon->port_low) { 269 rc = -1; 270 } else if (bportcon->port_low < aportcon->port_low) { 271 rc = 1; 272 } else if (aportcon->proto < bportcon->proto) { 273 rc = -1; 274 } else if (aportcon->proto > bportcon->proto) { 275 rc = 1; 276 } 277 } 278 279 return rc; 280 } 281 282 int cil_post_genfscon_compare(const void *a, const void *b) 283 { 284 int rc = SEPOL_ERR; 285 struct cil_genfscon *agenfscon = *(struct cil_genfscon**)a; 286 struct cil_genfscon *bgenfscon = *(struct cil_genfscon**)b; 287 288 rc = strcmp(agenfscon->fs_str, bgenfscon->fs_str); 289 if (rc == 0) { 290 rc = strcmp(agenfscon->path_str, bgenfscon->path_str); 291 } 292 293 return rc; 294 } 295 296 int cil_post_netifcon_compare(const void *a, const void *b) 297 { 298 struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a; 299 struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b; 300 301 return strcmp(anetifcon->interface_str, bnetifcon->interface_str); 302 } 303 304 int cil_post_ibendportcon_compare(const void *a, const void *b) 305 { 306 int rc = SEPOL_ERR; 307 308 struct cil_ibendportcon *aibendportcon = *(struct cil_ibendportcon **)a; 309 struct cil_ibendportcon *bibendportcon = *(struct cil_ibendportcon **)b; 310 311 rc = strcmp(aibendportcon->dev_name_str, bibendportcon->dev_name_str); 312 if (rc) 313 return rc; 314 315 if (aibendportcon->port < bibendportcon->port) 316 return -1; 317 else if (bibendportcon->port < aibendportcon->port) 318 return 1; 319 320 return rc; 321 } 322 323 int cil_post_nodecon_compare(const void *a, const void *b) 324 { 325 struct cil_nodecon *anodecon; 326 struct cil_nodecon *bnodecon; 327 anodecon = *(struct cil_nodecon**)a; 328 bnodecon = *(struct cil_nodecon**)b; 329 330 /* sort ipv4 before ipv6 */ 331 if (anodecon->addr->family != bnodecon->addr->family) { 332 if (anodecon->addr->family == AF_INET) { 333 return -1; 334 } else { 335 return 1; 336 } 337 } 338 339 /* most specific netmask goes first, then order by ip addr */ 340 if (anodecon->addr->family == AF_INET) { 341 int rc = memcmp(&anodecon->mask->ip.v4, &bnodecon->mask->ip.v4, sizeof(anodecon->mask->ip.v4)); 342 if (rc != 0) { 343 return -1 * rc; 344 } 345 return memcmp(&anodecon->addr->ip.v4, &bnodecon->addr->ip.v4, sizeof(anodecon->addr->ip.v4)); 346 } else { 347 int rc = memcmp(&anodecon->mask->ip.v6, &bnodecon->mask->ip.v6, sizeof(anodecon->mask->ip.v6)); 348 if (rc != 0) { 349 return -1 * rc; 350 } 351 return memcmp(&anodecon->addr->ip.v6, &bnodecon->addr->ip.v6, sizeof(anodecon->addr->ip.v6)); 352 } 353 } 354 355 int cil_post_pirqcon_compare(const void *a, const void *b) 356 { 357 int rc = SEPOL_ERR; 358 struct cil_pirqcon *apirqcon = *(struct cil_pirqcon**)a; 359 struct cil_pirqcon *bpirqcon = *(struct cil_pirqcon**)b; 360 361 if (apirqcon->pirq < bpirqcon->pirq) { 362 rc = -1; 363 } else if (bpirqcon->pirq < apirqcon->pirq) { 364 rc = 1; 365 } else { 366 rc = 0; 367 } 368 369 return rc; 370 } 371 372 int cil_post_iomemcon_compare(const void *a, const void *b) 373 { 374 int rc = SEPOL_ERR; 375 struct cil_iomemcon *aiomemcon = *(struct cil_iomemcon**)a; 376 struct cil_iomemcon *biomemcon = *(struct cil_iomemcon**)b; 377 378 rc = (aiomemcon->iomem_high - aiomemcon->iomem_low) 379 - (biomemcon->iomem_high - biomemcon->iomem_low); 380 if (rc == 0) { 381 if (aiomemcon->iomem_low < biomemcon->iomem_low) { 382 rc = -1; 383 } else if (biomemcon->iomem_low < aiomemcon->iomem_low) { 384 rc = 1; 385 } 386 } 387 388 return rc; 389 } 390 391 int cil_post_ioportcon_compare(const void *a, const void *b) 392 { 393 int rc = SEPOL_ERR; 394 struct cil_ioportcon *aioportcon = *(struct cil_ioportcon**)a; 395 struct cil_ioportcon *bioportcon = *(struct cil_ioportcon**)b; 396 397 rc = (aioportcon->ioport_high - aioportcon->ioport_low) 398 - (bioportcon->ioport_high - bioportcon->ioport_low); 399 if (rc == 0) { 400 if (aioportcon->ioport_low < bioportcon->ioport_low) { 401 rc = -1; 402 } else if (bioportcon->ioport_low < aioportcon->ioport_low) { 403 rc = 1; 404 } 405 } 406 407 return rc; 408 } 409 410 int cil_post_pcidevicecon_compare(const void *a, const void *b) 411 { 412 int rc = SEPOL_ERR; 413 struct cil_pcidevicecon *apcidevicecon = *(struct cil_pcidevicecon**)a; 414 struct cil_pcidevicecon *bpcidevicecon = *(struct cil_pcidevicecon**)b; 415 416 if (apcidevicecon->dev < bpcidevicecon->dev) { 417 rc = -1; 418 } else if (bpcidevicecon->dev < apcidevicecon->dev) { 419 rc = 1; 420 } else { 421 rc = 0; 422 } 423 424 return rc; 425 } 426 427 int cil_post_devicetreecon_compare(const void *a, const void *b) 428 { 429 int rc = SEPOL_ERR; 430 struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a; 431 struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b; 432 433 rc = strcmp(adevicetreecon->path, bdevicetreecon->path); 434 435 return rc; 436 } 437 438 int cil_post_fsuse_compare(const void *a, const void *b) 439 { 440 int rc; 441 struct cil_fsuse *afsuse; 442 struct cil_fsuse *bfsuse; 443 afsuse = *(struct cil_fsuse**)a; 444 bfsuse = *(struct cil_fsuse**)b; 445 if (afsuse->type < bfsuse->type) { 446 rc = -1; 447 } else if (bfsuse->type < afsuse->type) { 448 rc = 1; 449 } else { 450 rc = strcmp(afsuse->fs_str, bfsuse->fs_str); 451 } 452 return rc; 453 } 454 455 int cil_post_filecon_context_compare(const void *a, const void *b) 456 { 457 struct cil_filecon *a_filecon = *(struct cil_filecon**)a; 458 struct cil_filecon *b_filecon = *(struct cil_filecon**)b; 459 return context_compare(a_filecon->context, b_filecon->context); 460 } 461 462 int cil_post_ibpkeycon_context_compare(const void *a, const void *b) 463 { 464 struct cil_ibpkeycon *a_ibpkeycon = *(struct cil_ibpkeycon **)a; 465 struct cil_ibpkeycon *b_ibpkeycon = *(struct cil_ibpkeycon **)b; 466 return context_compare(a_ibpkeycon->context, b_ibpkeycon->context); 467 } 468 469 int cil_post_portcon_context_compare(const void *a, const void *b) 470 { 471 struct cil_portcon *a_portcon = *(struct cil_portcon**)a; 472 struct cil_portcon *b_portcon = *(struct cil_portcon**)b; 473 return context_compare(a_portcon->context, b_portcon->context); 474 } 475 476 int cil_post_genfscon_context_compare(const void *a, const void *b) 477 { 478 struct cil_genfscon *a_genfscon = *(struct cil_genfscon**)a; 479 struct cil_genfscon *b_genfscon = *(struct cil_genfscon**)b; 480 return context_compare(a_genfscon->context, b_genfscon->context); 481 } 482 483 int cil_post_netifcon_context_compare(const void *a, const void *b) 484 { 485 int rc; 486 struct cil_netifcon *a_netifcon = *(struct cil_netifcon**)a; 487 struct cil_netifcon *b_netifcon = *(struct cil_netifcon**)b; 488 rc = context_compare(a_netifcon->if_context, b_netifcon->if_context); 489 if (rc != 0) { 490 return rc; 491 } 492 return context_compare(a_netifcon->packet_context, b_netifcon->packet_context); 493 } 494 495 int cil_post_ibendportcon_context_compare(const void *a, const void *b) 496 { 497 struct cil_ibendportcon *a_ibendportcon = *(struct cil_ibendportcon **)a; 498 struct cil_ibendportcon *b_ibendportcon = *(struct cil_ibendportcon **)b; 499 return context_compare(a_ibendportcon->context, b_ibendportcon->context); 500 } 501 502 int cil_post_nodecon_context_compare(const void *a, const void *b) 503 { 504 struct cil_nodecon *a_nodecon = *(struct cil_nodecon **)a; 505 struct cil_nodecon *b_nodecon = *(struct cil_nodecon **)b; 506 return context_compare(a_nodecon->context, b_nodecon->context); 507 } 508 509 int cil_post_pirqcon_context_compare(const void *a, const void *b) 510 { 511 struct cil_pirqcon *a_pirqcon = *(struct cil_pirqcon**)a; 512 struct cil_pirqcon *b_pirqcon = *(struct cil_pirqcon**)b; 513 return context_compare(a_pirqcon->context, b_pirqcon->context); 514 } 515 516 int cil_post_iomemcon_context_compare(const void *a, const void *b) 517 { 518 struct cil_iomemcon *a_iomemcon = *(struct cil_iomemcon**)a; 519 struct cil_iomemcon *b_iomemcon = *(struct cil_iomemcon**)b; 520 return context_compare(a_iomemcon->context, b_iomemcon->context); 521 } 522 523 int cil_post_ioportcon_context_compare(const void *a, const void *b) 524 { 525 struct cil_ioportcon *a_ioportcon = *(struct cil_ioportcon**)a; 526 struct cil_ioportcon *b_ioportcon = *(struct cil_ioportcon**)b; 527 return context_compare(a_ioportcon->context, b_ioportcon->context); 528 } 529 530 int cil_post_pcidevicecon_context_compare(const void *a, const void *b) 531 { 532 struct cil_pcidevicecon *a_pcidevicecon = *(struct cil_pcidevicecon**)a; 533 struct cil_pcidevicecon *b_pcidevicecon = *(struct cil_pcidevicecon**)b; 534 return context_compare(a_pcidevicecon->context, b_pcidevicecon->context); 535 } 536 537 int cil_post_devicetreecon_context_compare(const void *a, const void *b) 538 { 539 struct cil_devicetreecon *a_devicetreecon = *(struct cil_devicetreecon**)a; 540 struct cil_devicetreecon *b_devicetreecon = *(struct cil_devicetreecon**)b; 541 return context_compare(a_devicetreecon->context, b_devicetreecon->context); 542 } 543 544 int cil_post_fsuse_context_compare(const void *a, const void *b) 545 { 546 struct cil_fsuse *a_fsuse = *(struct cil_fsuse**)a; 547 struct cil_fsuse *b_fsuse = *(struct cil_fsuse**)b; 548 return context_compare(a_fsuse->context, b_fsuse->context); 549 } 550 551 static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 552 { 553 struct cil_db *db = extra_args; 554 555 switch(node->flavor) { 556 case CIL_BLOCK: { 557 struct cil_block *blk = node->data; 558 if (blk->is_abstract == CIL_TRUE) { 559 *finished = CIL_TREE_SKIP_HEAD; 560 } 561 break; 562 } 563 case CIL_MACRO: 564 *finished = CIL_TREE_SKIP_HEAD; 565 break; 566 case CIL_CLASS: { 567 struct cil_class *class = node->data; 568 if (class->datum.nodes->head->data == node) { 569 // Multiple nodes can point to the same datum. Only count once. 570 db->num_classes++; 571 } 572 break; 573 } 574 case CIL_TYPE: { 575 struct cil_type *type = node->data; 576 if (type->datum.nodes->head->data == node) { 577 // Multiple nodes can point to the same datum. Only count once. 578 type->value = db->num_types; 579 db->num_types++; 580 db->num_types_and_attrs++; 581 } 582 break; 583 } 584 case CIL_TYPEATTRIBUTE: { 585 struct cil_typeattribute *attr = node->data; 586 if (attr->datum.nodes->head->data == node) { 587 // Multiple nodes can point to the same datum. Only count once. 588 db->num_types_and_attrs++; 589 } 590 break; 591 } 592 593 case CIL_ROLE: { 594 struct cil_role *role = node->data; 595 if (role->datum.nodes->head->data == node) { 596 // Multiple nodes can point to the same datum. Only count once. 597 role->value = db->num_roles; 598 db->num_roles++; 599 } 600 break; 601 } 602 case CIL_USER: { 603 struct cil_user *user = node->data; 604 if (user->datum.nodes->head->data == node) { 605 // multiple AST nodes can point to the same cil_user data (like if 606 // copied from a macro). This check ensures we only count the 607 // duplicates once 608 user->value = db->num_users; 609 db->num_users++; 610 } 611 break; 612 } 613 case CIL_NETIFCON: 614 db->netifcon->count++; 615 break; 616 case CIL_GENFSCON: 617 db->genfscon->count++; 618 break; 619 case CIL_FILECON: 620 db->filecon->count++; 621 break; 622 case CIL_NODECON: 623 db->nodecon->count++; 624 break; 625 case CIL_IBPKEYCON: 626 db->ibpkeycon->count++; 627 break; 628 case CIL_IBENDPORTCON: 629 db->ibendportcon->count++; 630 break; 631 case CIL_PORTCON: 632 db->portcon->count++; 633 break; 634 case CIL_PIRQCON: 635 db->pirqcon->count++; 636 break; 637 case CIL_IOMEMCON: 638 db->iomemcon->count++; 639 break; 640 case CIL_IOPORTCON: 641 db->ioportcon->count++; 642 break; 643 case CIL_PCIDEVICECON: 644 db->pcidevicecon->count++; 645 break; 646 case CIL_DEVICETREECON: 647 db->devicetreecon->count++; 648 break; 649 case CIL_FSUSE: 650 db->fsuse->count++; 651 break; 652 default: 653 break; 654 } 655 656 return SEPOL_OK; 657 } 658 659 static int __cil_post_db_array_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 660 { 661 struct cil_db *db = extra_args; 662 663 switch(node->flavor) { 664 case CIL_BLOCK: { 665 struct cil_block *blk = node->data; 666 if (blk->is_abstract == CIL_TRUE) { 667 *finished = CIL_TREE_SKIP_HEAD; 668 } 669 break; 670 } 671 case CIL_MACRO: 672 *finished = CIL_TREE_SKIP_HEAD; 673 break; 674 case CIL_TYPE: { 675 struct cil_type *type = node->data; 676 if (db->val_to_type == NULL) { 677 db->val_to_type = cil_malloc(sizeof(*db->val_to_type) * db->num_types); 678 } 679 db->val_to_type[type->value] = type; 680 break; 681 } 682 case CIL_ROLE: { 683 struct cil_role *role = node->data; 684 if (db->val_to_role == NULL) { 685 db->val_to_role = cil_malloc(sizeof(*db->val_to_role) * db->num_roles); 686 } 687 db->val_to_role[role->value] = role; 688 break; 689 } 690 case CIL_USER: { 691 struct cil_user *user= node->data; 692 if (db->val_to_user == NULL) { 693 db->val_to_user = cil_malloc(sizeof(*db->val_to_user) * db->num_users); 694 } 695 db->val_to_user[user->value] = user; 696 break; 697 } 698 case CIL_USERPREFIX: { 699 cil_list_append(db->userprefixes, CIL_USERPREFIX, node->data); 700 break; 701 } 702 case CIL_SELINUXUSER: { 703 cil_list_prepend(db->selinuxusers, CIL_SELINUXUSER, node->data); 704 break; 705 } 706 case CIL_SELINUXUSERDEFAULT: { 707 cil_list_append(db->selinuxusers, CIL_SELINUXUSERDEFAULT, node->data); 708 break; 709 } 710 case CIL_NETIFCON: { 711 struct cil_sort *sort = db->netifcon; 712 uint32_t count = sort->count; 713 uint32_t i = sort->index; 714 if (sort->array == NULL) { 715 sort->array = cil_malloc(sizeof(*sort->array)*count); 716 } 717 sort->array[i] = node->data; 718 sort->index++; 719 break; 720 } 721 case CIL_IBENDPORTCON: { 722 struct cil_sort *sort = db->ibendportcon; 723 uint32_t count = sort->count; 724 uint32_t i = sort->index; 725 726 if (!sort->array) 727 sort->array = cil_malloc(sizeof(*sort->array) * count); 728 sort->array[i] = node->data; 729 sort->index++; 730 break; 731 } 732 case CIL_FSUSE: { 733 struct cil_sort *sort = db->fsuse; 734 uint32_t count = sort->count; 735 uint32_t i = sort->index; 736 if (sort->array == NULL) { 737 sort->array = cil_malloc(sizeof(*sort->array)*count); 738 } 739 sort->array[i] = node->data; 740 sort->index++; 741 break; 742 } 743 case CIL_GENFSCON: { 744 struct cil_sort *sort = db->genfscon; 745 uint32_t count = sort->count; 746 uint32_t i = sort->index; 747 if (sort->array == NULL) { 748 sort->array = cil_malloc(sizeof(*sort->array)*count); 749 } 750 sort->array[i] = node->data; 751 sort->index++; 752 break; 753 } 754 case CIL_FILECON: { 755 struct cil_sort *sort = db->filecon; 756 uint32_t count = sort->count; 757 uint32_t i = sort->index; 758 if (sort->array == NULL) { 759 sort->array = cil_malloc(sizeof(*sort->array)*count); 760 } 761 sort->array[i] = node->data; 762 sort->index++; 763 break; 764 } 765 case CIL_NODECON: { 766 struct cil_sort *sort = db->nodecon; 767 uint32_t count = sort->count; 768 uint32_t i = sort->index; 769 if (sort->array == NULL) { 770 sort->array = cil_malloc(sizeof(*sort->array)*count); 771 } 772 sort->array[i] = node->data; 773 sort->index++; 774 break; 775 } 776 case CIL_IBPKEYCON: { 777 struct cil_sort *sort = db->ibpkeycon; 778 uint32_t count = sort->count; 779 uint32_t i = sort->index; 780 781 if (!sort->array) 782 sort->array = cil_malloc(sizeof(*sort->array) * count); 783 sort->array[i] = node->data; 784 sort->index++; 785 break; 786 } 787 case CIL_PORTCON: { 788 struct cil_sort *sort = db->portcon; 789 uint32_t count = sort->count; 790 uint32_t i = sort->index; 791 if (sort->array == NULL) { 792 sort->array = cil_malloc(sizeof(*sort->array)*count); 793 } 794 sort->array[i] = node->data; 795 sort->index++; 796 break; 797 } 798 case CIL_PIRQCON: { 799 struct cil_sort *sort = db->pirqcon; 800 uint32_t count = sort->count; 801 uint32_t i = sort->index; 802 if (sort->array == NULL) { 803 sort->array = cil_malloc(sizeof(*sort->array)*count); 804 } 805 sort->array[i] = node->data; 806 sort->index++; 807 break; 808 } 809 case CIL_IOMEMCON: { 810 struct cil_sort *sort = db->iomemcon; 811 uint32_t count = sort->count; 812 uint32_t i = sort->index; 813 if (sort->array == NULL) { 814 sort->array = cil_malloc(sizeof(*sort->array)*count); 815 } 816 sort->array[i] = node->data; 817 sort->index++; 818 break; 819 } 820 case CIL_IOPORTCON: { 821 struct cil_sort *sort = db->ioportcon; 822 uint32_t count = sort->count; 823 uint32_t i = sort->index; 824 if (sort->array == NULL) { 825 sort->array = cil_malloc(sizeof(*sort->array)*count); 826 } 827 sort->array[i] = node->data; 828 sort->index++; 829 break; 830 } 831 case CIL_PCIDEVICECON: { 832 struct cil_sort *sort = db->pcidevicecon; 833 uint32_t count = sort->count; 834 uint32_t i = sort->index; 835 if (sort->array == NULL) { 836 sort->array = cil_malloc(sizeof(*sort->array)*count); 837 } 838 sort->array[i] = node->data; 839 sort->index++; 840 break; 841 } 842 case CIL_DEVICETREECON: { 843 struct cil_sort *sort = db->devicetreecon; 844 uint32_t count = sort->count; 845 uint32_t i = sort->index; 846 if (sort->array == NULL) { 847 sort->array = cil_malloc(sizeof(*sort->array)*count); 848 } 849 sort->array[i] = node->data; 850 sort->index++; 851 break; 852 } 853 default: 854 break; 855 } 856 857 return SEPOL_OK; 858 } 859 860 static int __evaluate_type_expression(struct cil_typeattribute *attr, struct cil_db *db) 861 { 862 int rc; 863 864 attr->types = cil_malloc(sizeof(*attr->types)); 865 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->types, db->num_types, db); 866 if (rc != SEPOL_OK) { 867 cil_log(CIL_ERR, "Failed to expand type attribute to bitmap\n"); 868 ebitmap_destroy(attr->types); 869 free(attr->types); 870 attr->types = NULL; 871 } 872 return rc; 873 } 874 875 static int __cil_type_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 876 { 877 int rc = SEPOL_ERR; 878 struct cil_tree_node *node = datum->nodes->head->data; 879 880 ebitmap_init(bitmap); 881 882 if (node->flavor == CIL_TYPEATTRIBUTE) { 883 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 884 if (attr->types == NULL) { 885 rc = __evaluate_type_expression(attr, db); 886 if (rc != SEPOL_OK) goto exit; 887 } 888 ebitmap_union(bitmap, attr->types); 889 } else if (node->flavor == CIL_TYPEALIAS) { 890 struct cil_alias *alias = (struct cil_alias *)datum; 891 struct cil_type *type = alias->actual; 892 if (ebitmap_set_bit(bitmap, type->value, 1)) { 893 cil_log(CIL_ERR, "Failed to set type bit\n"); 894 ebitmap_destroy(bitmap); 895 goto exit; 896 } 897 } else { 898 struct cil_type *type = (struct cil_type *)datum; 899 if (ebitmap_set_bit(bitmap, type->value, 1)) { 900 cil_log(CIL_ERR, "Failed to set type bit\n"); 901 ebitmap_destroy(bitmap); 902 goto exit; 903 } 904 } 905 906 return SEPOL_OK; 907 908 exit: 909 return rc; 910 } 911 912 static int __evaluate_user_expression(struct cil_userattribute *attr, struct cil_db *db) 913 { 914 int rc; 915 916 attr->users = cil_malloc(sizeof(*attr->users)); 917 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->users, db->num_users, db); 918 if (rc != SEPOL_OK) { 919 cil_log(CIL_ERR, "Failed to expand user attribute to bitmap\n"); 920 ebitmap_destroy(attr->users); 921 free(attr->users); 922 attr->users = NULL; 923 } 924 return rc; 925 } 926 927 static int __cil_user_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 928 { 929 int rc = SEPOL_ERR; 930 struct cil_tree_node *node = datum->nodes->head->data; 931 struct cil_userattribute *attr = NULL; 932 struct cil_user *user = NULL; 933 934 ebitmap_init(bitmap); 935 936 if (node->flavor == CIL_USERATTRIBUTE) { 937 attr = (struct cil_userattribute *)datum; 938 if (attr->users == NULL) { 939 rc = __evaluate_user_expression(attr, db); 940 if (rc != SEPOL_OK) { 941 goto exit; 942 } 943 } 944 ebitmap_union(bitmap, attr->users); 945 } else { 946 user = (struct cil_user *)datum; 947 if (ebitmap_set_bit(bitmap, user->value, 1)) { 948 cil_log(CIL_ERR, "Failed to set user bit\n"); 949 ebitmap_destroy(bitmap); 950 goto exit; 951 } 952 } 953 954 return SEPOL_OK; 955 956 exit: 957 return rc; 958 } 959 960 static int __evaluate_role_expression(struct cil_roleattribute *attr, struct cil_db *db) 961 { 962 int rc; 963 964 attr->roles = cil_malloc(sizeof(*attr->roles)); 965 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->roles, db->num_roles, db); 966 if (rc != SEPOL_OK) { 967 cil_log(CIL_ERR, "Failed to expand role attribute to bitmap\n"); 968 ebitmap_destroy(attr->roles); 969 free(attr->roles); 970 attr->roles = NULL; 971 } 972 return rc; 973 } 974 975 static int __cil_role_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 976 { 977 int rc = SEPOL_ERR; 978 struct cil_tree_node *node = datum->nodes->head->data; 979 980 ebitmap_init(bitmap); 981 982 if (node->flavor == CIL_ROLEATTRIBUTE) { 983 struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; 984 if (attr->roles == NULL) { 985 rc = __evaluate_role_expression(attr, db); 986 if (rc != SEPOL_OK) goto exit; 987 } 988 ebitmap_union(bitmap, attr->roles); 989 } else { 990 struct cil_role *role = (struct cil_role *)datum; 991 if (ebitmap_set_bit(bitmap, role->value, 1)) { 992 cil_log(CIL_ERR, "Failed to set role bit\n"); 993 ebitmap_destroy(bitmap); 994 goto exit; 995 } 996 } 997 998 return SEPOL_OK; 999 1000 exit: 1001 return rc; 1002 } 1003 1004 static int __evaluate_permissionx_expression(struct cil_permissionx *permx, struct cil_db *db) 1005 { 1006 int rc; 1007 1008 permx->perms = cil_malloc(sizeof(*permx->perms)); 1009 ebitmap_init(permx->perms); 1010 1011 rc = __cil_expr_to_bitmap(permx->expr_str, permx->perms, 0x10000, db); // max is one more than 0xFFFF 1012 if (rc != SEPOL_OK) { 1013 cil_log(CIL_ERR, "Failed to expand permissionx expression\n"); 1014 ebitmap_destroy(permx->perms); 1015 free(permx->perms); 1016 permx->perms = NULL; 1017 } 1018 1019 return rc; 1020 } 1021 1022 static int __cil_permx_str_to_int(char *permx_str, uint16_t *val) 1023 { 1024 char *endptr = NULL; 1025 long lval = strtol(permx_str, &endptr, 0); 1026 1027 if (*endptr != '\0') { 1028 cil_log(CIL_ERR, "permissionx value %s not valid number\n", permx_str); 1029 goto exit; 1030 } 1031 if (lval < 0x0000 || lval > 0xFFFF) { 1032 cil_log(CIL_ERR, "permissionx value %s must be between 0x0000 and 0xFFFF\n", permx_str); 1033 goto exit; 1034 } 1035 1036 *val = (uint16_t)lval; 1037 1038 return SEPOL_OK; 1039 1040 exit: 1041 return SEPOL_ERR; 1042 } 1043 1044 static int __cil_permx_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db) 1045 { 1046 int rc = SEPOL_ERR; 1047 uint16_t val; 1048 1049 rc = __cil_permx_str_to_int((char*)datum, &val); 1050 if (rc != SEPOL_OK) { 1051 goto exit; 1052 } 1053 1054 ebitmap_init(bitmap); 1055 if (ebitmap_set_bit(bitmap, (unsigned int)val, 1)) { 1056 cil_log(CIL_ERR, "Failed to set permissionx bit\n"); 1057 ebitmap_destroy(bitmap); 1058 goto exit; 1059 } 1060 1061 return SEPOL_OK; 1062 1063 exit: 1064 return rc; 1065 } 1066 1067 static int __cil_perm_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db) 1068 { 1069 struct cil_perm *perm = (struct cil_perm *)datum; 1070 unsigned int value = perm->value; 1071 1072 ebitmap_init(bitmap); 1073 if (ebitmap_set_bit(bitmap, value, 1)) { 1074 cil_log(CIL_INFO, "Failed to set perm bit\n"); 1075 ebitmap_destroy(bitmap); 1076 return SEPOL_ERR; 1077 } 1078 1079 return SEPOL_OK; 1080 } 1081 1082 static int __evaluate_cat_expression(struct cil_cats *cats, struct cil_db *db) 1083 { 1084 int rc = SEPOL_ERR; 1085 ebitmap_t bitmap; 1086 struct cil_list *new; 1087 struct cil_list_item *curr; 1088 1089 if (cats->evaluated == CIL_TRUE) { 1090 return SEPOL_OK; 1091 } 1092 1093 if (cil_verify_is_list(cats->datum_expr, CIL_CAT)) { 1094 return SEPOL_OK; 1095 } 1096 1097 ebitmap_init(&bitmap); 1098 rc = __cil_expr_to_bitmap(cats->datum_expr, &bitmap, db->num_cats, db); 1099 if (rc != SEPOL_OK) { 1100 cil_log(CIL_ERR, "Failed to expand category expression to bitmap\n"); 1101 ebitmap_destroy(&bitmap); 1102 goto exit; 1103 } 1104 1105 cil_list_init(&new, CIL_CAT); 1106 1107 cil_list_for_each(curr, db->catorder) { 1108 struct cil_cat *cat = curr->data; 1109 if (ebitmap_get_bit(&bitmap, cat->value)) { 1110 cil_list_append(new, CIL_DATUM, cat); 1111 } 1112 } 1113 1114 ebitmap_destroy(&bitmap); 1115 cil_list_destroy(&cats->datum_expr, CIL_FALSE); 1116 cats->datum_expr = new; 1117 1118 cats->evaluated = CIL_TRUE; 1119 1120 return SEPOL_OK; 1121 1122 exit: 1123 return rc; 1124 } 1125 1126 static int __cil_cat_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db) 1127 { 1128 int rc = SEPOL_ERR; 1129 struct cil_tree_node *node = datum->nodes->head->data; 1130 1131 ebitmap_init(bitmap); 1132 1133 if (node->flavor == CIL_CATSET) { 1134 struct cil_catset *catset = (struct cil_catset *)datum; 1135 struct cil_list_item *curr; 1136 if (catset->cats->evaluated == CIL_FALSE) { 1137 rc = __evaluate_cat_expression(catset->cats, db); 1138 if (rc != SEPOL_OK) goto exit; 1139 } 1140 for (curr = catset->cats->datum_expr->head; curr; curr = curr->next) { 1141 struct cil_cat *cat = (struct cil_cat *)curr->data; 1142 if (ebitmap_set_bit(bitmap, cat->value, 1)) { 1143 cil_log(CIL_ERR, "Failed to set cat bit\n"); 1144 ebitmap_destroy(bitmap); 1145 goto exit; 1146 } 1147 } 1148 } else if (node->flavor == CIL_CATALIAS) { 1149 struct cil_alias *alias = (struct cil_alias *)datum; 1150 struct cil_cat *cat = alias->actual; 1151 if (ebitmap_set_bit(bitmap, cat->value, 1)) { 1152 cil_log(CIL_ERR, "Failed to set cat bit\n"); 1153 ebitmap_destroy(bitmap); 1154 goto exit; 1155 } 1156 } else { 1157 struct cil_cat *cat = (struct cil_cat *)datum; 1158 if (ebitmap_set_bit(bitmap, cat->value, 1)) { 1159 cil_log(CIL_ERR, "Failed to set cat bit\n"); 1160 ebitmap_destroy(bitmap); 1161 goto exit; 1162 } 1163 } 1164 1165 return SEPOL_OK; 1166 1167 exit: 1168 return rc; 1169 } 1170 1171 static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap) 1172 { 1173 int rc = SEPOL_ERR; 1174 struct cil_symtab_datum *d1 = i1->data; 1175 struct cil_symtab_datum *d2 = i2->data; 1176 struct cil_tree_node *n1 = d1->nodes->head->data; 1177 struct cil_tree_node *n2 = d2->nodes->head->data; 1178 struct cil_cat *c1 = (struct cil_cat *)d1; 1179 struct cil_cat *c2 = (struct cil_cat *)d2; 1180 int i; 1181 1182 if (n1->flavor == CIL_CATSET || n2->flavor == CIL_CATSET) { 1183 cil_log(CIL_ERR, "Category sets cannont be used in a category range\n"); 1184 goto exit; 1185 } 1186 1187 if (n1->flavor == CIL_CATALIAS) { 1188 struct cil_alias *alias = (struct cil_alias *)d1; 1189 c1 = alias->actual; 1190 } 1191 1192 if (n2->flavor == CIL_CATALIAS) { 1193 struct cil_alias *alias = (struct cil_alias *)d2; 1194 c2 = alias->actual; 1195 } 1196 1197 if (c1->value > c2->value) { 1198 cil_log(CIL_ERR, "Invalid category range\n"); 1199 goto exit; 1200 } 1201 1202 for (i = c1->value; i <= c2->value; i++) { 1203 if (ebitmap_set_bit(bitmap, i, 1)) { 1204 cil_log(CIL_ERR, "Failed to set cat bit\n"); 1205 ebitmap_destroy(bitmap); 1206 goto exit; 1207 } 1208 } 1209 1210 return SEPOL_OK; 1211 1212 exit: 1213 return rc; 1214 } 1215 1216 static int __cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap) 1217 { 1218 int rc = SEPOL_ERR; 1219 char *p1 = i1->data; 1220 char *p2 = i2->data; 1221 uint16_t v1; 1222 uint16_t v2; 1223 uint32_t i; 1224 1225 rc = __cil_permx_str_to_int(p1, &v1); 1226 if (rc != SEPOL_OK) { 1227 goto exit; 1228 } 1229 1230 rc = __cil_permx_str_to_int(p2, &v2); 1231 if (rc != SEPOL_OK) { 1232 goto exit; 1233 } 1234 1235 for (i = v1; i <= v2; i++) { 1236 if (ebitmap_set_bit(bitmap, i, 1)) { 1237 cil_log(CIL_ERR, "Failed to set permissionx bit\n"); 1238 ebitmap_destroy(bitmap); 1239 goto exit; 1240 } 1241 } 1242 1243 return SEPOL_OK; 1244 1245 exit: 1246 return rc; 1247 } 1248 1249 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) 1250 { 1251 int rc = SEPOL_ERR; 1252 1253 if (curr->flavor == CIL_DATUM) { 1254 switch (flavor) { 1255 case CIL_TYPE: 1256 rc = __cil_type_to_bitmap(curr->data, bitmap, db); 1257 break; 1258 case CIL_ROLE: 1259 rc = __cil_role_to_bitmap(curr->data, bitmap, db); 1260 break; 1261 case CIL_USER: 1262 rc = __cil_user_to_bitmap(curr->data, bitmap, db); 1263 break; 1264 case CIL_PERM: 1265 rc = __cil_perm_to_bitmap(curr->data, bitmap, db); 1266 break; 1267 case CIL_CAT: 1268 rc = __cil_cat_to_bitmap(curr->data, bitmap, db); 1269 break; 1270 default: 1271 rc = SEPOL_ERR; 1272 } 1273 } else if (curr->flavor == CIL_LIST) { 1274 struct cil_list *l = curr->data; 1275 ebitmap_init(bitmap); 1276 rc = __cil_expr_to_bitmap(l, bitmap, max, db); 1277 if (rc != SEPOL_OK) { 1278 ebitmap_destroy(bitmap); 1279 } 1280 } else if (flavor == CIL_PERMISSIONX) { 1281 // permissionx expressions aren't resolved into anything, so curr->flavor 1282 // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those 1283 rc = __cil_permx_to_bitmap(curr->data, bitmap, db); 1284 } 1285 1286 return rc; 1287 } 1288 1289 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db) 1290 { 1291 int rc = SEPOL_ERR; 1292 struct cil_list_item *curr; 1293 enum cil_flavor flavor; 1294 ebitmap_t tmp, b1, b2; 1295 1296 if (expr == NULL || expr->head == NULL) { 1297 return SEPOL_OK; 1298 } 1299 1300 curr = expr->head; 1301 flavor = expr->flavor; 1302 1303 if (curr->flavor == CIL_OP) { 1304 enum cil_flavor op = (enum cil_flavor)curr->data; 1305 1306 if (op == CIL_ALL) { 1307 ebitmap_init(&b1); /* all zeros */ 1308 rc = ebitmap_not(&tmp, &b1, max); 1309 ebitmap_destroy(&b1); 1310 if (rc != SEPOL_OK) { 1311 cil_log(CIL_INFO, "Failed to expand 'all' operator\n"); 1312 ebitmap_destroy(&tmp); 1313 goto exit; 1314 } 1315 } else if (op == CIL_RANGE) { 1316 if (flavor == CIL_CAT) { 1317 ebitmap_init(&tmp); 1318 rc = __cil_cat_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp); 1319 if (rc != SEPOL_OK) { 1320 cil_log(CIL_INFO, "Failed to expand category range\n"); 1321 ebitmap_destroy(&tmp); 1322 goto exit; 1323 } 1324 } else if (flavor == CIL_PERMISSIONX) { 1325 ebitmap_init(&tmp); 1326 rc = __cil_permissionx_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp); 1327 if (rc != SEPOL_OK) { 1328 cil_log(CIL_INFO, "Failed to expand category range\n"); 1329 ebitmap_destroy(&tmp); 1330 goto exit; 1331 } 1332 } else { 1333 cil_log(CIL_INFO, "Range operation only supported for categories permissionx\n"); 1334 rc = SEPOL_ERR; 1335 goto exit; 1336 } 1337 } else { 1338 rc = __cil_expr_to_bitmap_helper(curr->next, flavor, &b1, max, db); 1339 if (rc != SEPOL_OK) { 1340 cil_log(CIL_INFO, "Failed to get first operand bitmap\n"); 1341 goto exit; 1342 } 1343 1344 if (op == CIL_NOT) { 1345 rc = ebitmap_not(&tmp, &b1, max); 1346 ebitmap_destroy(&b1); 1347 if (rc != SEPOL_OK) { 1348 cil_log(CIL_INFO, "Failed to NOT bitmap\n"); 1349 ebitmap_destroy(&tmp); 1350 goto exit; 1351 } 1352 } else { 1353 rc = __cil_expr_to_bitmap_helper(curr->next->next, flavor, &b2, max, db); 1354 if (rc != SEPOL_OK) { 1355 cil_log(CIL_INFO, "Failed to get second operand bitmap\n"); 1356 ebitmap_destroy(&b1); 1357 goto exit; 1358 } 1359 1360 if (op == CIL_OR) { 1361 rc = ebitmap_or(&tmp, &b1, &b2); 1362 } else if (op == CIL_AND) { 1363 rc = ebitmap_and(&tmp, &b1, &b2); 1364 } else if (op == CIL_XOR) { 1365 rc = ebitmap_xor(&tmp, &b1, &b2); 1366 } else { 1367 rc = SEPOL_ERR; 1368 } 1369 ebitmap_destroy(&b1); 1370 ebitmap_destroy(&b2); 1371 if (rc != SEPOL_OK) { 1372 cil_log(CIL_INFO, "Failed to apply operator to bitmaps\n"); 1373 ebitmap_destroy(&tmp); 1374 goto exit; 1375 } 1376 } 1377 } 1378 } else { 1379 ebitmap_init(&tmp); 1380 for (;curr; curr = curr->next) { 1381 rc = __cil_expr_to_bitmap_helper(curr, flavor, &b2, max, db); 1382 if (rc != SEPOL_OK) { 1383 cil_log(CIL_INFO, "Failed to get operand in list\n"); 1384 ebitmap_destroy(&tmp); 1385 goto exit; 1386 } 1387 b1 = tmp; 1388 rc = ebitmap_or(&tmp, &b1, &b2); 1389 ebitmap_destroy(&b1); 1390 ebitmap_destroy(&b2); 1391 if (rc != SEPOL_OK) { 1392 cil_log(CIL_INFO, "Failed to OR operands in list\n"); 1393 ebitmap_destroy(&tmp); 1394 goto exit; 1395 } 1396 1397 } 1398 } 1399 1400 ebitmap_union(out, &tmp); 1401 ebitmap_destroy(&tmp); 1402 1403 return SEPOL_OK; 1404 1405 exit: 1406 return rc; 1407 } 1408 1409 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db) 1410 { 1411 int rc = SEPOL_ERR; 1412 struct cil_list_item *expr; 1413 1414 ebitmap_init(out); 1415 1416 if (expr_list == NULL) { 1417 return SEPOL_OK; 1418 } 1419 1420 cil_list_for_each(expr, expr_list) { 1421 ebitmap_t bitmap; 1422 struct cil_list *l = (struct cil_list *)expr->data; 1423 ebitmap_init(&bitmap); 1424 rc = __cil_expr_to_bitmap(l, &bitmap, max, db); 1425 if (rc != SEPOL_OK) { 1426 cil_log(CIL_INFO, "Failed to expand expression list to bitmap\n"); 1427 ebitmap_destroy(&bitmap); 1428 goto exit; 1429 } 1430 ebitmap_union(out, &bitmap); 1431 ebitmap_destroy(&bitmap); 1432 } 1433 1434 return SEPOL_OK; 1435 1436 exit: 1437 return SEPOL_ERR; 1438 } 1439 1440 static int cil_typeattribute_used(struct cil_typeattribute *attr, struct cil_db *db) 1441 { 1442 if (!attr->used) { 1443 return CIL_FALSE; 1444 } 1445 1446 if (attr->used & CIL_ATTR_EXPAND_FALSE) { 1447 return CIL_TRUE; 1448 } 1449 1450 if (attr->used & CIL_ATTR_EXPAND_TRUE) { 1451 return CIL_FALSE; 1452 } 1453 1454 if (attr->used & CIL_ATTR_CONSTRAINT) { 1455 return CIL_TRUE; 1456 } 1457 1458 if (db->attrs_expand_generated || attr->used == CIL_ATTR_NEVERALLOW) { 1459 if (strcmp(DATUM(attr)->name, GEN_REQUIRE_ATTR) == 0) { 1460 return CIL_FALSE; 1461 } else if (strstr(DATUM(attr)->name, TYPEATTR_INFIX) != NULL) { 1462 return CIL_FALSE; 1463 } 1464 1465 if (attr->used == CIL_ATTR_NEVERALLOW) { 1466 return CIL_TRUE; 1467 } 1468 } 1469 1470 if (attr->used == CIL_ATTR_AVRULE) { 1471 if (ebitmap_cardinality(attr->types) < db->attrs_expand_size) { 1472 return CIL_FALSE; 1473 } 1474 } 1475 1476 return CIL_TRUE; 1477 } 1478 1479 static void __mark_neverallow_attrs(struct cil_list *expr_list) 1480 { 1481 struct cil_list_item *curr; 1482 1483 cil_list_for_each(curr, expr_list) { 1484 if (curr->flavor == CIL_DATUM) { 1485 if (NODE(curr->data)->flavor == CIL_TYPEATTRIBUTE) { 1486 struct cil_typeattribute *attr = curr->data; 1487 if (strstr(DATUM(attr)->name, TYPEATTR_INFIX)) { 1488 __mark_neverallow_attrs(attr->expr_list); 1489 } else { 1490 attr->used |= CIL_ATTR_NEVERALLOW; 1491 } 1492 } 1493 } else if (curr->flavor == CIL_LIST) { 1494 __mark_neverallow_attrs(curr->data); 1495 } 1496 } 1497 } 1498 1499 static int __cil_post_db_neverallow_attr_helper(struct cil_tree_node *node, uint32_t *finished, __attribute__((unused)) void *extra_args) 1500 { 1501 switch (node->flavor) { 1502 case CIL_BLOCK: { 1503 struct cil_block *blk = node->data; 1504 if (blk->is_abstract == CIL_TRUE) { 1505 *finished = CIL_TREE_SKIP_HEAD; 1506 } 1507 break; 1508 } 1509 case CIL_MACRO: { 1510 *finished = CIL_TREE_SKIP_HEAD; 1511 break; 1512 } 1513 case CIL_TYPEATTRIBUTE: { 1514 struct cil_typeattribute *attr = node->data; 1515 if ((attr->used & CIL_ATTR_NEVERALLOW) && 1516 strstr(DATUM(attr)->name, TYPEATTR_INFIX)) { 1517 __mark_neverallow_attrs(attr->expr_list); 1518 } 1519 break; 1520 } 1521 default: 1522 break; 1523 } 1524 1525 return SEPOL_OK; 1526 } 1527 1528 static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1529 { 1530 int rc = SEPOL_ERR; 1531 struct cil_db *db = extra_args; 1532 1533 switch (node->flavor) { 1534 case CIL_BLOCK: { 1535 struct cil_block *blk = node->data; 1536 if (blk->is_abstract == CIL_TRUE) { 1537 *finished = CIL_TREE_SKIP_HEAD; 1538 } 1539 break; 1540 } 1541 case CIL_MACRO: { 1542 *finished = CIL_TREE_SKIP_HEAD; 1543 break; 1544 } 1545 case CIL_TYPEATTRIBUTE: { 1546 struct cil_typeattribute *attr = node->data; 1547 if (attr->types == NULL) { 1548 rc = __evaluate_type_expression(attr, db); 1549 if (rc != SEPOL_OK) goto exit; 1550 } 1551 attr->keep = cil_typeattribute_used(attr, db); 1552 break; 1553 } 1554 case CIL_ROLEATTRIBUTE: { 1555 struct cil_roleattribute *attr = node->data; 1556 if (attr->roles == NULL) { 1557 rc = __evaluate_role_expression(attr, db); 1558 if (rc != SEPOL_OK) goto exit; 1559 } 1560 break; 1561 } 1562 case CIL_AVRULEX: { 1563 struct cil_avrule *rule = node->data; 1564 if (rule->perms.x.permx_str == NULL) { 1565 rc = __evaluate_permissionx_expression(rule->perms.x.permx, db); 1566 if (rc != SEPOL_OK) goto exit; 1567 } 1568 break; 1569 } 1570 case CIL_PERMISSIONX: { 1571 struct cil_permissionx *permx = node->data; 1572 rc = __evaluate_permissionx_expression(permx, db); 1573 if (rc != SEPOL_OK) goto exit; 1574 break; 1575 } 1576 case CIL_USERATTRIBUTE: { 1577 struct cil_userattribute *attr = node->data; 1578 if (attr->users == NULL) { 1579 rc = __evaluate_user_expression(attr, db); 1580 if (rc != SEPOL_OK) { 1581 goto exit; 1582 } 1583 } 1584 break; 1585 } 1586 default: 1587 break; 1588 } 1589 1590 return SEPOL_OK; 1591 1592 exit: 1593 return rc; 1594 } 1595 1596 static int __cil_role_assign_types(struct cil_role *role, struct cil_symtab_datum *datum) 1597 { 1598 struct cil_tree_node *node = datum->nodes->head->data; 1599 1600 if (role->types == NULL) { 1601 role->types = cil_malloc(sizeof(*role->types)); 1602 ebitmap_init(role->types); 1603 } 1604 1605 if (node->flavor == CIL_TYPE) { 1606 struct cil_type *type = (struct cil_type *)datum; 1607 if (ebitmap_set_bit(role->types, type->value, 1)) { 1608 cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n"); 1609 goto exit; 1610 } 1611 } else if (node->flavor == CIL_TYPEALIAS) { 1612 struct cil_alias *alias = (struct cil_alias *)datum; 1613 struct cil_type *type = alias->actual; 1614 if (ebitmap_set_bit(role->types, type->value, 1)) { 1615 cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n"); 1616 goto exit; 1617 } 1618 } else if (node->flavor == CIL_TYPEATTRIBUTE) { 1619 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 1620 ebitmap_union(role->types, attr->types); 1621 } 1622 1623 return SEPOL_OK; 1624 1625 exit: 1626 return SEPOL_ERR; 1627 } 1628 1629 static int __cil_post_db_roletype_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1630 { 1631 int rc = SEPOL_ERR; 1632 struct cil_db *db = extra_args; 1633 1634 switch (node->flavor) { 1635 case CIL_BLOCK: { 1636 struct cil_block *blk = node->data; 1637 if (blk->is_abstract == CIL_TRUE) { 1638 *finished = CIL_TREE_SKIP_HEAD; 1639 } 1640 break; 1641 } 1642 case CIL_MACRO: { 1643 *finished = CIL_TREE_SKIP_HEAD; 1644 break; 1645 } 1646 case CIL_ROLETYPE: { 1647 struct cil_roletype *roletype = node->data; 1648 struct cil_symtab_datum *role_datum = roletype->role; 1649 struct cil_symtab_datum *type_datum = roletype->type; 1650 struct cil_tree_node *role_node = role_datum->nodes->head->data; 1651 1652 if (role_node->flavor == CIL_ROLEATTRIBUTE) { 1653 struct cil_roleattribute *attr = roletype->role; 1654 ebitmap_node_t *rnode; 1655 unsigned int i; 1656 1657 ebitmap_for_each_bit(attr->roles, rnode, i) { 1658 struct cil_role *role = NULL; 1659 1660 if (!ebitmap_get_bit(attr->roles, i)) { 1661 continue; 1662 } 1663 1664 role = db->val_to_role[i]; 1665 1666 rc = __cil_role_assign_types(role, type_datum); 1667 if (rc != SEPOL_OK) { 1668 goto exit; 1669 } 1670 } 1671 } else { 1672 struct cil_role *role = roletype->role; 1673 1674 rc = __cil_role_assign_types(role, type_datum); 1675 if (rc != SEPOL_OK) { 1676 goto exit; 1677 } 1678 } 1679 break; 1680 } 1681 default: 1682 break; 1683 } 1684 1685 return SEPOL_OK; 1686 exit: 1687 cil_log(CIL_INFO, "cil_post_db_roletype_helper failed\n"); 1688 return rc; 1689 } 1690 1691 static int __cil_user_assign_roles(struct cil_user *user, struct cil_symtab_datum *datum) 1692 { 1693 struct cil_tree_node *node = datum->nodes->head->data; 1694 struct cil_role *role = NULL; 1695 struct cil_roleattribute *attr = NULL; 1696 1697 if (user->roles == NULL) { 1698 user->roles = cil_malloc(sizeof(*user->roles)); 1699 ebitmap_init(user->roles); 1700 } 1701 1702 if (node->flavor == CIL_ROLE) { 1703 role = (struct cil_role *)datum; 1704 if (ebitmap_set_bit(user->roles, role->value, 1)) { 1705 cil_log(CIL_INFO, "Failed to set bit in user roles bitmap\n"); 1706 goto exit; 1707 } 1708 } else if (node->flavor == CIL_ROLEATTRIBUTE) { 1709 attr = (struct cil_roleattribute *)datum; 1710 ebitmap_union(user->roles, attr->roles); 1711 } 1712 1713 return SEPOL_OK; 1714 1715 exit: 1716 return SEPOL_ERR; 1717 } 1718 1719 static int __cil_post_db_userrole_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1720 { 1721 int rc = SEPOL_ERR; 1722 struct cil_db *db = extra_args; 1723 struct cil_block *blk = NULL; 1724 struct cil_userrole *userrole = NULL; 1725 struct cil_symtab_datum *user_datum = NULL; 1726 struct cil_symtab_datum *role_datum = NULL; 1727 struct cil_tree_node *user_node = NULL; 1728 struct cil_userattribute *u_attr = NULL; 1729 unsigned int i; 1730 struct cil_user *user = NULL; 1731 ebitmap_node_t *unode = NULL; 1732 1733 switch (node->flavor) { 1734 case CIL_BLOCK: { 1735 blk = node->data; 1736 if (blk->is_abstract == CIL_TRUE) { 1737 *finished = CIL_TREE_SKIP_HEAD; 1738 } 1739 break; 1740 } 1741 case CIL_MACRO: { 1742 *finished = CIL_TREE_SKIP_HEAD; 1743 break; 1744 } 1745 case CIL_USERROLE: { 1746 userrole = node->data; 1747 user_datum = userrole->user; 1748 role_datum = userrole->role; 1749 user_node = user_datum->nodes->head->data; 1750 1751 if (user_node->flavor == CIL_USERATTRIBUTE) { 1752 u_attr = userrole->user; 1753 1754 ebitmap_for_each_bit(u_attr->users, unode, i) { 1755 if (!ebitmap_get_bit(u_attr->users, i)) { 1756 continue; 1757 } 1758 1759 user = db->val_to_user[i]; 1760 1761 rc = __cil_user_assign_roles(user, role_datum); 1762 if (rc != SEPOL_OK) { 1763 goto exit; 1764 } 1765 } 1766 } else { 1767 user = userrole->user; 1768 1769 rc = __cil_user_assign_roles(user, role_datum); 1770 if (rc != SEPOL_OK) { 1771 goto exit; 1772 } 1773 } 1774 1775 break; 1776 } 1777 default: 1778 break; 1779 } 1780 1781 return SEPOL_OK; 1782 exit: 1783 cil_log(CIL_INFO, "cil_post_db_userrole_helper failed\n"); 1784 return rc; 1785 } 1786 1787 static int __evaluate_level_expression(struct cil_level *level, struct cil_db *db) 1788 { 1789 if (level->cats != NULL) { 1790 return __evaluate_cat_expression(level->cats, db); 1791 } 1792 1793 return SEPOL_OK; 1794 } 1795 1796 static int __evaluate_levelrange_expression(struct cil_levelrange *levelrange, struct cil_db *db) 1797 { 1798 int rc = SEPOL_OK; 1799 1800 if (levelrange->low != NULL && levelrange->low->cats != NULL) { 1801 rc = __evaluate_cat_expression(levelrange->low->cats, db); 1802 if (rc != SEPOL_OK) { 1803 goto exit; 1804 } 1805 } 1806 if (levelrange->high != NULL && levelrange->high->cats != NULL) { 1807 rc = __evaluate_cat_expression(levelrange->high->cats, db); 1808 if (rc != SEPOL_OK) { 1809 goto exit; 1810 } 1811 } 1812 1813 exit: 1814 return rc; 1815 } 1816 1817 static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 1818 { 1819 int rc = SEPOL_ERR; 1820 struct cil_db *db = extra_args; 1821 1822 switch (node->flavor) { 1823 case CIL_BLOCK: { 1824 struct cil_block *blk = node->data; 1825 if (blk->is_abstract == CIL_TRUE) { 1826 *finished = CIL_TREE_SKIP_HEAD; 1827 } 1828 break; 1829 } 1830 case CIL_MACRO: { 1831 *finished = CIL_TREE_SKIP_HEAD; 1832 break; 1833 } 1834 case CIL_CATSET: { 1835 struct cil_catset *catset = node->data; 1836 rc = __evaluate_cat_expression(catset->cats, db); 1837 if (rc != SEPOL_OK) { 1838 goto exit; 1839 } 1840 break; 1841 } 1842 case CIL_SENSCAT: { 1843 struct cil_senscat *senscat = node->data; 1844 rc = __evaluate_cat_expression(senscat->cats, db); 1845 if (rc != SEPOL_OK) { 1846 goto exit; 1847 } 1848 break; 1849 } 1850 case CIL_LEVEL: { 1851 rc = __evaluate_level_expression(node->data, db); 1852 if (rc != SEPOL_OK) { 1853 goto exit; 1854 } 1855 break; 1856 } 1857 case CIL_LEVELRANGE: { 1858 rc = __evaluate_levelrange_expression(node->data, db); 1859 if (rc != SEPOL_OK) { 1860 goto exit; 1861 } 1862 break; 1863 } 1864 case CIL_USER: { 1865 struct cil_user *user = node->data; 1866 rc = __evaluate_level_expression(user->dftlevel, db); 1867 if (rc != SEPOL_OK) { 1868 goto exit; 1869 } 1870 rc = __evaluate_levelrange_expression(user->range, db); 1871 if (rc != SEPOL_OK) { 1872 goto exit; 1873 } 1874 break; 1875 } 1876 case CIL_SELINUXUSERDEFAULT: 1877 case CIL_SELINUXUSER: { 1878 struct cil_selinuxuser *selinuxuser = node->data; 1879 rc = __evaluate_levelrange_expression(selinuxuser->range, db); 1880 if (rc != SEPOL_OK) { 1881 goto exit; 1882 } 1883 break; 1884 } 1885 case CIL_RANGETRANSITION: { 1886 struct cil_rangetransition *rangetrans = node->data; 1887 rc = __evaluate_levelrange_expression(rangetrans->range, db); 1888 if (rc != SEPOL_OK) { 1889 goto exit; 1890 } 1891 break; 1892 } 1893 case CIL_CONTEXT: { 1894 struct cil_context *context = node->data; 1895 rc = __evaluate_levelrange_expression(context->range, db); 1896 if (rc != SEPOL_OK) { 1897 goto exit; 1898 } 1899 break; 1900 } 1901 case CIL_SIDCONTEXT: { 1902 struct cil_sidcontext *sidcontext = node->data; 1903 rc = __evaluate_levelrange_expression(sidcontext->context->range, db); 1904 if (rc != SEPOL_OK) { 1905 goto exit; 1906 } 1907 break; 1908 } 1909 case CIL_FILECON: { 1910 struct cil_filecon *filecon = node->data; 1911 if (filecon->context) { 1912 rc = __evaluate_levelrange_expression(filecon->context->range, db); 1913 if (rc != SEPOL_OK) { 1914 goto exit; 1915 } 1916 } 1917 break; 1918 } 1919 case CIL_IBPKEYCON: { 1920 struct cil_ibpkeycon *ibpkeycon = node->data; 1921 1922 rc = __evaluate_levelrange_expression(ibpkeycon->context->range, db); 1923 if (rc != SEPOL_OK) 1924 goto exit; 1925 break; 1926 } 1927 case CIL_IBENDPORTCON: { 1928 struct cil_ibendportcon *ibendportcon = node->data; 1929 1930 rc = __evaluate_levelrange_expression(ibendportcon->context->range, db); 1931 if (rc != SEPOL_OK) 1932 goto exit; 1933 break; 1934 } 1935 case CIL_PORTCON: { 1936 struct cil_portcon *portcon = node->data; 1937 rc = __evaluate_levelrange_expression(portcon->context->range, db); 1938 if (rc != SEPOL_OK) { 1939 goto exit; 1940 } 1941 break; 1942 } 1943 case CIL_NODECON: { 1944 struct cil_nodecon *nodecon = node->data; 1945 rc = __evaluate_levelrange_expression(nodecon->context->range, db); 1946 if (rc != SEPOL_OK) { 1947 goto exit; 1948 } 1949 break; 1950 } 1951 case CIL_GENFSCON: { 1952 struct cil_genfscon *genfscon = node->data; 1953 rc = __evaluate_levelrange_expression(genfscon->context->range, db); 1954 if (rc != SEPOL_OK) { 1955 goto exit; 1956 } 1957 break; 1958 } 1959 case CIL_NETIFCON: { 1960 struct cil_netifcon *netifcon = node->data; 1961 rc = __evaluate_levelrange_expression(netifcon->if_context->range, db); 1962 if (rc != SEPOL_OK) { 1963 goto exit; 1964 } 1965 rc = __evaluate_levelrange_expression(netifcon->packet_context->range, db); 1966 if (rc != SEPOL_OK) { 1967 goto exit; 1968 } 1969 break; 1970 } 1971 case CIL_PIRQCON: { 1972 struct cil_pirqcon *pirqcon = node->data; 1973 rc = __evaluate_levelrange_expression(pirqcon->context->range, db); 1974 if (rc != SEPOL_OK) { 1975 goto exit; 1976 } 1977 break; 1978 } 1979 case CIL_IOMEMCON: { 1980 struct cil_iomemcon *iomemcon = node->data; 1981 rc = __evaluate_levelrange_expression(iomemcon->context->range, db); 1982 if (rc != SEPOL_OK) { 1983 goto exit; 1984 } 1985 break; 1986 } 1987 case CIL_IOPORTCON: { 1988 struct cil_ioportcon *ioportcon = node->data; 1989 rc = __evaluate_levelrange_expression(ioportcon->context->range, db); 1990 if (rc != SEPOL_OK) { 1991 goto exit; 1992 } 1993 break; 1994 } 1995 case CIL_PCIDEVICECON: { 1996 struct cil_pcidevicecon *pcidevicecon = node->data; 1997 rc = __evaluate_levelrange_expression(pcidevicecon->context->range, db); 1998 if (rc != SEPOL_OK) { 1999 goto exit; 2000 } 2001 break; 2002 } 2003 case CIL_DEVICETREECON: { 2004 struct cil_devicetreecon *devicetreecon = node->data; 2005 rc = __evaluate_levelrange_expression(devicetreecon->context->range, db); 2006 if (rc != SEPOL_OK) { 2007 goto exit; 2008 } 2009 break; 2010 } 2011 case CIL_FSUSE: { 2012 struct cil_fsuse *fsuse = node->data; 2013 rc = __evaluate_levelrange_expression(fsuse->context->range, db); 2014 if (rc != SEPOL_OK) { 2015 goto exit; 2016 } 2017 break; 2018 } 2019 default: 2020 break; 2021 } 2022 2023 return SEPOL_OK; 2024 2025 exit: 2026 return rc; 2027 } 2028 2029 struct perm_to_list { 2030 enum cil_flavor flavor; 2031 ebitmap_t *perms; 2032 struct cil_list *new_list; 2033 }; 2034 2035 static int __perm_bits_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 2036 { 2037 struct perm_to_list *perm_args = (struct perm_to_list *)args; 2038 ebitmap_t *perms = perm_args->perms; 2039 struct cil_list *new_list = perm_args->new_list; 2040 struct cil_perm *perm = (struct cil_perm *)d; 2041 unsigned int value = perm->value; 2042 2043 if (!ebitmap_get_bit(perms, value)) { 2044 return SEPOL_OK; 2045 } 2046 2047 cil_list_append(new_list, CIL_DATUM, d); 2048 2049 return SEPOL_OK; 2050 } 2051 2052 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) 2053 { 2054 int rc = SEPOL_ERR; 2055 struct perm_to_list args; 2056 ebitmap_t bitmap; 2057 2058 if (cil_verify_is_list(perms, CIL_PERM)) { 2059 return SEPOL_OK; 2060 } 2061 2062 ebitmap_init(&bitmap); 2063 rc = __cil_expr_to_bitmap(perms, &bitmap, num_perms, db); 2064 if (rc != SEPOL_OK) { 2065 ebitmap_destroy(&bitmap); 2066 goto exit; 2067 } 2068 2069 cil_list_init(new_list, flavor); 2070 2071 args.flavor = flavor; 2072 args.perms = &bitmap; 2073 args.new_list = *new_list; 2074 2075 cil_symtab_map(class_symtab, __perm_bits_to_list, &args); 2076 2077 if (common_symtab != NULL) { 2078 cil_symtab_map(common_symtab, __perm_bits_to_list, &args); 2079 } 2080 2081 ebitmap_destroy(&bitmap); 2082 return SEPOL_OK; 2083 2084 exit: 2085 return rc; 2086 } 2087 2088 static int __evaluate_classperms(struct cil_classperms *cp, struct cil_db *db) 2089 { 2090 int rc = SEPOL_ERR; 2091 struct cil_class *class = cp->class; 2092 struct cil_class *common = class->common; 2093 symtab_t *common_symtab = NULL; 2094 struct cil_list *new_list = NULL; 2095 2096 if (common) { 2097 common_symtab = &common->perms; 2098 } 2099 2100 rc = __evaluate_perm_expression(cp->perms, CIL_PERM, &class->perms, common_symtab, class->num_perms, &new_list, db); 2101 if (rc != SEPOL_OK) { 2102 goto exit; 2103 } 2104 2105 if (new_list == NULL) { 2106 return SEPOL_OK; 2107 } 2108 2109 cil_list_destroy(&cp->perms, CIL_FALSE); 2110 2111 cp->perms = new_list; 2112 2113 return SEPOL_OK; 2114 2115 exit: 2116 return rc; 2117 } 2118 2119 static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db *db) 2120 { 2121 int rc = SEPOL_ERR; 2122 struct cil_list_item *curr; 2123 2124 cil_list_for_each(curr, classperms) { 2125 if (curr->flavor == CIL_CLASSPERMS) { 2126 struct cil_classperms *cp = curr->data; 2127 if (FLAVOR(cp->class) == CIL_CLASS) { 2128 rc = __evaluate_classperms(cp, db); 2129 if (rc != SEPOL_OK) { 2130 goto exit; 2131 } 2132 } else { /* MAP */ 2133 struct cil_list_item *i = NULL; 2134 cil_list_for_each(i, cp->perms) { 2135 struct cil_perm *cmp = i->data; 2136 rc = __evaluate_classperms_list(cmp->classperms, db); 2137 if (rc != SEPOL_OK) { 2138 goto exit; 2139 } 2140 } 2141 } 2142 } else { /* SET */ 2143 struct cil_classperms_set *cp_set = curr->data; 2144 struct cil_classpermission *cp = cp_set->set; 2145 rc = __evaluate_classperms_list(cp->classperms, db); 2146 if (rc != SEPOL_OK) { 2147 goto exit; 2148 } 2149 } 2150 } 2151 2152 return SEPOL_OK; 2153 2154 exit: 2155 return rc; 2156 } 2157 2158 struct class_map_args { 2159 struct cil_db *db; 2160 int rc; 2161 }; 2162 2163 static int __evaluate_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 2164 { 2165 struct class_map_args *map_args = args; 2166 struct cil_perm *cmp = (struct cil_perm *)d; 2167 2168 int rc = __evaluate_classperms_list(cmp->classperms, map_args->db); 2169 2170 if (rc != SEPOL_OK) { 2171 map_args->rc = rc; 2172 } 2173 2174 return SEPOL_OK; 2175 } 2176 2177 static int __evaluate_map_class(struct cil_class *mc, struct cil_db *db) 2178 { 2179 struct class_map_args map_args; 2180 2181 map_args.db = db; 2182 map_args.rc = SEPOL_OK; 2183 cil_symtab_map(&mc->perms, __evaluate_map_perm_classperms, &map_args); 2184 2185 return map_args.rc; 2186 } 2187 2188 static int __cil_post_db_classperms_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 2189 { 2190 int rc = SEPOL_ERR; 2191 struct cil_db *db = extra_args; 2192 2193 switch (node->flavor) { 2194 case CIL_BLOCK: { 2195 struct cil_block *blk = node->data; 2196 if (blk->is_abstract == CIL_TRUE) { 2197 *finished = CIL_TREE_SKIP_HEAD; 2198 } 2199 break; 2200 } 2201 case CIL_MACRO: 2202 *finished = CIL_TREE_SKIP_HEAD; 2203 break; 2204 case CIL_MAP_CLASS: { 2205 rc = __evaluate_map_class(node->data, db); 2206 if (rc != SEPOL_OK) { 2207 goto exit; 2208 } 2209 break; 2210 } 2211 case CIL_CLASSPERMISSION: { 2212 struct cil_classpermission *cp = node->data; 2213 rc = __evaluate_classperms_list(cp->classperms, db); 2214 if (rc != SEPOL_OK) { 2215 goto exit; 2216 } 2217 break; 2218 } 2219 case CIL_AVRULE: { 2220 struct cil_avrule *avrule = node->data; 2221 rc = __evaluate_classperms_list(avrule->perms.classperms, db); 2222 if (rc != SEPOL_OK) { 2223 goto exit; 2224 } 2225 break; 2226 } 2227 case CIL_CONSTRAIN: 2228 case CIL_MLSCONSTRAIN: { 2229 struct cil_constrain *constrain = node->data; 2230 rc = __evaluate_classperms_list(constrain->classperms, db); 2231 if (rc != SEPOL_OK) { 2232 goto exit; 2233 } 2234 break; 2235 } 2236 default: 2237 break; 2238 } 2239 2240 return SEPOL_OK; 2241 2242 exit: 2243 return rc; 2244 } 2245 2246 static int __cil_post_report_conflict(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 2247 { 2248 struct cil_list_item *li = extra_args; 2249 2250 if (node->flavor == CIL_BLOCK) { 2251 struct cil_block *blk = node->data; 2252 if (blk->is_abstract == CIL_TRUE) { 2253 *finished = CIL_TREE_SKIP_HEAD; 2254 } 2255 } else if (node->flavor == CIL_MACRO) { 2256 *finished = CIL_TREE_SKIP_HEAD; 2257 } else if (node->flavor == li->flavor) { 2258 if (node->data == li->data) { 2259 char *path = cil_tree_get_cil_path(node); 2260 cil_log(CIL_WARN, " at %s:%d\n", path, node->line); 2261 } 2262 } 2263 return SEPOL_OK; 2264 } 2265 2266 static int __cil_post_process_context_rules(struct cil_sort *sort, int (*compar)(const void *, const void *), int (*concompar)(const void *, const void *), struct cil_db *db, enum cil_flavor flavor, const char *flavor_str) 2267 { 2268 uint32_t count = sort->count; 2269 uint32_t i, j = 0, removed = 0; 2270 int rc = SEPOL_OK; 2271 2272 if (count < 2) { 2273 return SEPOL_OK; 2274 } 2275 2276 qsort(sort->array, sort->count, sizeof(sort->array), compar); 2277 2278 for (i=1; i<count; i++) { 2279 if (compar(&sort->array[i], &sort->array[j]) != 0) { 2280 j++; 2281 } else { 2282 removed++; 2283 if (!db->multiple_decls || 2284 concompar(&sort->array[i], &sort->array[j]) != 0) { 2285 struct cil_list_item li; 2286 int rc2; 2287 cil_log(CIL_WARN, "Found conflicting %s rules\n", 2288 flavor_str); 2289 rc = SEPOL_ERR; 2290 li.flavor = flavor; 2291 li.data = sort->array[i]; 2292 rc2 = cil_tree_walk(db->ast->root, 2293 __cil_post_report_conflict, 2294 NULL, NULL, &li); 2295 if (rc2 != SEPOL_OK) goto exit; 2296 li.data = sort->array[j]; 2297 rc2 = cil_tree_walk(db->ast->root, 2298 __cil_post_report_conflict, 2299 NULL, NULL, &li); 2300 if (rc2 != SEPOL_OK) goto exit; 2301 } 2302 } 2303 if (i != j) { 2304 sort->array[j] = sort->array[i]; 2305 } 2306 } 2307 2308 sort->count = count - removed; 2309 2310 exit: 2311 return rc; 2312 } 2313 2314 static int cil_post_db(struct cil_db *db) 2315 { 2316 int rc = SEPOL_ERR; 2317 2318 rc = cil_tree_walk(db->ast->root, __cil_post_db_count_helper, NULL, NULL, db); 2319 if (rc != SEPOL_OK) { 2320 cil_log(CIL_INFO, "Failure during cil databse count helper\n"); 2321 goto exit; 2322 } 2323 2324 rc = cil_tree_walk(db->ast->root, __cil_post_db_array_helper, NULL, NULL, db); 2325 if (rc != SEPOL_OK) { 2326 cil_log(CIL_INFO, "Failure during cil database array helper\n"); 2327 goto exit; 2328 } 2329 2330 rc = cil_tree_walk(db->ast->root, __cil_post_db_neverallow_attr_helper, NULL, NULL, db); 2331 if (rc != SEPOL_OK) { 2332 cil_log(CIL_INFO, "Failed to mark attributes used by generated attributes used in neverallow rules\n"); 2333 goto exit; 2334 } 2335 2336 rc = cil_tree_walk(db->ast->root, __cil_post_db_attr_helper, NULL, NULL, db); 2337 if (rc != SEPOL_OK) { 2338 cil_log(CIL_INFO, "Failed to create attribute bitmaps\n"); 2339 goto exit; 2340 } 2341 2342 rc = cil_tree_walk(db->ast->root, __cil_post_db_roletype_helper, NULL, NULL, db); 2343 if (rc != SEPOL_OK) { 2344 cil_log(CIL_INFO, "Failed during roletype association\n"); 2345 goto exit; 2346 } 2347 2348 rc = cil_tree_walk(db->ast->root, __cil_post_db_userrole_helper, NULL, NULL, db); 2349 if (rc != SEPOL_OK) { 2350 cil_log(CIL_INFO, "Failed during userrole association\n"); 2351 goto exit; 2352 } 2353 2354 rc = cil_tree_walk(db->ast->root, __cil_post_db_classperms_helper, NULL, NULL, db); 2355 if (rc != SEPOL_OK) { 2356 cil_log(CIL_INFO, "Failed to evaluate class mapping permissions expressions\n"); 2357 goto exit; 2358 } 2359 2360 rc = cil_tree_walk(db->ast->root, __cil_post_db_cat_helper, NULL, NULL, db); 2361 if (rc != SEPOL_OK) { 2362 cil_log(CIL_INFO, "Failed to evaluate category expressions\n"); 2363 goto exit; 2364 } 2365 2366 rc = __cil_post_process_context_rules(db->netifcon, cil_post_netifcon_compare, cil_post_netifcon_context_compare, db, CIL_NETIFCON, CIL_KEY_NETIFCON); 2367 if (rc != SEPOL_OK) { 2368 cil_log(CIL_ERR, "Problems processing netifcon rules\n"); 2369 goto exit; 2370 } 2371 2372 rc = __cil_post_process_context_rules(db->genfscon, cil_post_genfscon_compare, cil_post_genfscon_context_compare, db, CIL_GENFSCON, CIL_KEY_GENFSCON); 2373 if (rc != SEPOL_OK) { 2374 cil_log(CIL_ERR, "Problems processing genfscon rules\n"); 2375 goto exit; 2376 } 2377 2378 rc = __cil_post_process_context_rules(db->ibpkeycon, cil_post_ibpkeycon_compare, cil_post_ibpkeycon_context_compare, db, CIL_IBPKEYCON, CIL_KEY_IBPKEYCON); 2379 if (rc != SEPOL_OK) { 2380 cil_log(CIL_ERR, "Problems processing ibpkeycon rules\n"); 2381 goto exit; 2382 } 2383 2384 rc = __cil_post_process_context_rules(db->ibendportcon, cil_post_ibendportcon_compare, cil_post_ibendportcon_context_compare, db, CIL_IBENDPORTCON, CIL_KEY_IBENDPORTCON); 2385 if (rc != SEPOL_OK) { 2386 cil_log(CIL_ERR, "Problems processing ibendportcon rules\n"); 2387 goto exit; 2388 } 2389 2390 rc = __cil_post_process_context_rules(db->portcon, cil_post_portcon_compare, cil_post_portcon_context_compare, db, CIL_PORTCON, CIL_KEY_PORTCON); 2391 if (rc != SEPOL_OK) { 2392 cil_log(CIL_ERR, "Problems processing portcon rules\n"); 2393 goto exit; 2394 } 2395 2396 rc = __cil_post_process_context_rules(db->nodecon, cil_post_nodecon_compare, cil_post_nodecon_context_compare, db, CIL_NODECON, CIL_KEY_NODECON); 2397 if (rc != SEPOL_OK) { 2398 cil_log(CIL_ERR, "Problems processing nodecon rules\n"); 2399 goto exit; 2400 } 2401 2402 rc = __cil_post_process_context_rules(db->fsuse, cil_post_fsuse_compare, cil_post_fsuse_context_compare, db, CIL_FSUSE, CIL_KEY_FSUSE); 2403 if (rc != SEPOL_OK) { 2404 cil_log(CIL_ERR, "Problems processing fsuse rules\n"); 2405 goto exit; 2406 } 2407 2408 rc = __cil_post_process_context_rules(db->filecon, cil_post_filecon_compare, cil_post_filecon_context_compare, db, CIL_FILECON, CIL_KEY_FILECON); 2409 if (rc != SEPOL_OK) { 2410 cil_log(CIL_ERR, "Problems processing filecon rules\n"); 2411 goto exit; 2412 } 2413 2414 rc = __cil_post_process_context_rules(db->iomemcon, cil_post_iomemcon_compare, cil_post_iomemcon_context_compare, db, CIL_IOMEMCON, CIL_KEY_IOMEMCON); 2415 if (rc != SEPOL_OK) { 2416 cil_log(CIL_ERR, "Problems processing iomemcon rules\n"); 2417 goto exit; 2418 } 2419 2420 rc = __cil_post_process_context_rules(db->ioportcon, cil_post_ioportcon_compare, cil_post_ioportcon_context_compare, db, CIL_IOPORTCON, CIL_KEY_IOPORTCON); 2421 if (rc != SEPOL_OK) { 2422 cil_log(CIL_ERR, "Problems processing ioportcon rules\n"); 2423 goto exit; 2424 } 2425 2426 rc = __cil_post_process_context_rules(db->pcidevicecon, cil_post_pcidevicecon_compare, cil_post_pcidevicecon_context_compare, db, CIL_PCIDEVICECON, CIL_KEY_PCIDEVICECON); 2427 if (rc != SEPOL_OK) { 2428 cil_log(CIL_ERR, "Problems processing pcidevicecon rules\n"); 2429 goto exit; 2430 } 2431 2432 rc = __cil_post_process_context_rules(db->devicetreecon, cil_post_devicetreecon_compare, cil_post_devicetreecon_context_compare, db, CIL_DEVICETREECON, CIL_KEY_DEVICETREECON); 2433 if (rc != SEPOL_OK) { 2434 cil_log(CIL_ERR, "Problems processing devicetreecon rules\n"); 2435 goto exit; 2436 } 2437 2438 exit: 2439 return rc; 2440 } 2441 2442 static int cil_post_verify(struct cil_db *db) 2443 { 2444 int rc = SEPOL_ERR; 2445 int avrule_cnt = 0; 2446 int handleunknown = -1; 2447 int mls = -1; 2448 int nseuserdflt = 0; 2449 int pass = 0; 2450 struct cil_args_verify extra_args; 2451 struct cil_complex_symtab csymtab; 2452 2453 cil_complex_symtab_init(&csymtab, CIL_CLASS_SYM_SIZE); 2454 2455 extra_args.db = db; 2456 extra_args.csymtab = &csymtab; 2457 extra_args.avrule_cnt = &avrule_cnt; 2458 extra_args.handleunknown = &handleunknown; 2459 extra_args.mls = &mls; 2460 extra_args.nseuserdflt = &nseuserdflt; 2461 extra_args.pass = &pass; 2462 2463 for (pass = 0; pass < 2; pass++) { 2464 rc = cil_tree_walk(db->ast->root, __cil_verify_helper, NULL, NULL, &extra_args); 2465 if (rc != SEPOL_OK) { 2466 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2467 goto exit; 2468 } 2469 } 2470 2471 if (db->handle_unknown == -1) { 2472 if (handleunknown == -1) { 2473 db->handle_unknown = SEPOL_DENY_UNKNOWN; 2474 } else { 2475 db->handle_unknown = handleunknown; 2476 } 2477 } 2478 2479 if (db->mls == -1) { 2480 if (mls == -1) { 2481 db->mls = CIL_FALSE; 2482 } else { 2483 db->mls = mls; 2484 } 2485 } 2486 2487 if (avrule_cnt == 0) { 2488 cil_log(CIL_ERR, "Policy must include at least one avrule\n"); 2489 rc = SEPOL_ERR; 2490 goto exit; 2491 } 2492 2493 if (nseuserdflt > 1) { 2494 cil_log(CIL_ERR, "Policy cannot contain more than one selinuxuserdefault, found: %d\n", nseuserdflt); 2495 rc = SEPOL_ERR; 2496 goto exit; 2497 } 2498 2499 exit: 2500 cil_complex_symtab_destroy(&csymtab); 2501 return rc; 2502 } 2503 2504 static int cil_pre_verify(struct cil_db *db) 2505 { 2506 int rc = SEPOL_ERR; 2507 struct cil_args_verify extra_args; 2508 2509 extra_args.db = db; 2510 2511 rc = cil_tree_walk(db->ast->root, __cil_pre_verify_helper, NULL, NULL, &extra_args); 2512 if (rc != SEPOL_OK) { 2513 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2514 goto exit; 2515 } 2516 2517 exit: 2518 return rc; 2519 } 2520 2521 int cil_post_process(struct cil_db *db) 2522 { 2523 int rc = SEPOL_ERR; 2524 2525 rc = cil_pre_verify(db); 2526 if (rc != SEPOL_OK) { 2527 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2528 goto exit; 2529 } 2530 2531 rc = cil_post_db(db); 2532 if (rc != SEPOL_OK) { 2533 cil_log(CIL_ERR, "Failed post db handling\n"); 2534 goto exit; 2535 } 2536 2537 rc = cil_post_verify(db); 2538 if (rc != SEPOL_OK) { 2539 cil_log(CIL_ERR, "Failed to verify cil database\n"); 2540 goto exit; 2541 } 2542 2543 exit: 2544 return rc; 2545 2546 } 2547