1 /* Authors: Steve Lawrence <slawrence (at) tresys.com> 2 * 3 * Functions to convert policy module to CIL 4 * 5 * Copyright (C) 2015 Tresys Technology, LLC 6 * Copyright (C) 2017 Mellanox Technologies Inc. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include <arpa/inet.h> 24 #include <ctype.h> 25 #include <errno.h> 26 #include <fcntl.h> 27 #include <getopt.h> 28 #include <libgen.h> 29 #include <netinet/in.h> 30 #ifndef IPPROTO_DCCP 31 #define IPPROTO_DCCP 33 32 #endif 33 #ifndef IPPROTO_SCTP 34 #define IPPROTO_SCTP 132 35 #endif 36 #include <signal.h> 37 #include <stdarg.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <inttypes.h> 42 #include <sys/types.h> 43 #include <sys/stat.h> 44 #include <unistd.h> 45 46 #include <sepol/module.h> 47 #include <sepol/module_to_cil.h> 48 #include <sepol/policydb/conditional.h> 49 #include <sepol/policydb/hashtab.h> 50 #include <sepol/policydb/polcaps.h> 51 #include <sepol/policydb/policydb.h> 52 #include <sepol/policydb/services.h> 53 #include <sepol/policydb/util.h> 54 55 #include "kernel_to_common.h" 56 #include "private.h" 57 58 #ifdef __GNUC__ 59 # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) 60 #else 61 # define UNUSED(x) UNUSED_ ## x 62 #endif 63 64 FILE *out_file; 65 66 #define STACK_SIZE 16 67 #define DEFAULT_LEVEL "systemlow" 68 #define DEFAULT_OBJECT "object_r" 69 #define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/cil/src/cil_post.c */ 70 #define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/cil/src/cil_post.c */ 71 #define ROLEATTR_INFIX "_roleattr_" 72 73 __attribute__ ((format(printf, 1, 2))) 74 static void log_err(const char *fmt, ...) 75 { 76 va_list argptr; 77 va_start(argptr, fmt); 78 if (vfprintf(stderr, fmt, argptr) < 0) { 79 _exit(EXIT_FAILURE); 80 } 81 va_end(argptr); 82 if (fprintf(stderr, "\n") < 0) { 83 _exit(EXIT_FAILURE); 84 } 85 } 86 87 static void cil_indent(int indent) 88 { 89 if (fprintf(out_file, "%*s", indent * 4, "") < 0) { 90 log_err("Failed to write to output"); 91 _exit(EXIT_FAILURE); 92 } 93 } 94 95 __attribute__ ((format(printf, 1, 2))) 96 static void cil_printf(const char *fmt, ...) { 97 va_list argptr; 98 va_start(argptr, fmt); 99 if (vfprintf(out_file, fmt, argptr) < 0) { 100 log_err("Failed to write to output"); 101 _exit(EXIT_FAILURE); 102 } 103 va_end(argptr); 104 } 105 106 __attribute__ ((format(printf, 2, 3))) 107 static void cil_println(int indent, const char *fmt, ...) 108 { 109 cil_indent(indent); 110 va_list argptr; 111 va_start(argptr, fmt); 112 if (vfprintf(out_file, fmt, argptr) < 0) { 113 log_err("Failed to write to output"); 114 _exit(EXIT_FAILURE); 115 } 116 va_end(argptr); 117 if (fprintf(out_file, "\n") < 0) { 118 log_err("Failed to write to output"); 119 _exit(EXIT_FAILURE); 120 } 121 } 122 123 static int get_line(char **start, char *end, char **line) 124 { 125 int rc = 1; 126 char *p = NULL; 127 size_t len = 0; 128 129 *line = NULL; 130 131 for (p = *start; p < end && isspace(*p); p++); 132 133 *start = p; 134 135 for (len = 0; p < end && *p != '\n' && *p != '\0'; p++, len++); 136 137 if (zero_or_saturated(len)) { 138 rc = 0; 139 goto exit; 140 } 141 142 *line = malloc(len+1); 143 if (*line == NULL) { 144 log_err("Out of memory"); 145 rc = -1; 146 goto exit; 147 } 148 149 memcpy(*line, *start, len); 150 (*line)[len] = '\0'; 151 152 *start = p; 153 154 return rc; 155 156 exit: 157 *start = NULL; 158 return rc; 159 } 160 161 struct map_args { 162 struct policydb *pdb; 163 struct avrule_block *block; 164 struct stack *decl_stack; 165 int scope; 166 int indent; 167 int sym_index; 168 }; 169 170 struct stack { 171 void **stack; 172 int pos; 173 int size; 174 }; 175 176 struct role_list_node { 177 char *role_name; 178 role_datum_t *role; 179 }; 180 181 struct attr_list_node { 182 char *attr_name; 183 int is_type; 184 void *set; 185 }; 186 187 struct list_node { 188 void *data; 189 struct list_node *next; 190 }; 191 192 struct list { 193 struct list_node *head; 194 }; 195 196 /* A linked list of all roles stored in the pdb 197 * which is iterated to determine types associated 198 * with each role when printing role_type statements 199 */ 200 static struct list *role_list; 201 202 static void list_destroy(struct list **list) 203 { 204 struct list_node *curr = (*list)->head; 205 struct list_node *tmp; 206 207 while (curr != NULL) { 208 tmp = curr->next; 209 free(curr); 210 curr = tmp; 211 } 212 213 free(*list); 214 *list = NULL; 215 } 216 217 static void role_list_destroy(void) 218 { 219 struct list_node *curr; 220 221 if (role_list == NULL) { 222 return; 223 } 224 curr = role_list->head; 225 226 while (curr != NULL) { 227 free(curr->data); 228 curr->data = NULL; 229 curr = curr->next; 230 } 231 232 list_destroy(&role_list); 233 } 234 235 static void attr_list_destroy(struct list **attr_list) 236 { 237 if (attr_list == NULL || *attr_list == NULL) { 238 return; 239 } 240 241 struct list_node *curr = (*attr_list)->head; 242 struct attr_list_node *attr; 243 244 while (curr != NULL) { 245 attr = curr->data; 246 if (attr != NULL) { 247 free(attr->attr_name); 248 } 249 250 free(curr->data); 251 curr->data = NULL; 252 curr = curr->next; 253 } 254 255 list_destroy(attr_list); 256 } 257 258 static int list_init(struct list **list) 259 { 260 struct list *l = calloc(1, sizeof(*l)); 261 if (l == NULL) { 262 return -1; 263 } 264 265 *list = l; 266 return 0; 267 } 268 269 static int list_prepend(struct list *list, void *data) 270 { 271 int rc = -1; 272 struct list_node *node = calloc(1, sizeof(*node)); 273 if (node == NULL) { 274 goto exit; 275 } 276 277 node->data = data; 278 node->next = list->head; 279 list->head = node; 280 281 rc = 0; 282 283 exit: 284 return rc; 285 } 286 287 static int roles_gather_map(char *key, void *data, void *args) 288 { 289 struct role_list_node *role_node; 290 role_datum_t *role = data; 291 int rc = -1; 292 293 role_node = calloc(1, sizeof(*role_node)); 294 if (role_node == NULL) { 295 return rc; 296 } 297 298 role_node->role_name = key; 299 role_node->role = role; 300 301 rc = list_prepend((struct list *)args, role_node); 302 if (rc != 0) 303 free(role_node); 304 return rc; 305 } 306 307 static int role_list_create(hashtab_t roles_tab) 308 { 309 int rc = -1; 310 311 rc = list_init(&role_list); 312 if (rc != 0) { 313 goto exit; 314 } 315 316 rc = hashtab_map(roles_tab, roles_gather_map, role_list); 317 318 exit: 319 return rc; 320 } 321 322 // array of lists, where each list contains all the aliases defined in the scope at index i 323 static struct list **typealias_lists; 324 static uint32_t typealias_lists_len; 325 326 static int typealiases_gather_map(char *key, void *data, void *arg) 327 { 328 int rc = -1; 329 struct type_datum *type = data; 330 struct policydb *pdb = arg; 331 struct scope_datum *scope; 332 uint32_t len; 333 uint32_t scope_id; 334 335 if (type->primary != 1) { 336 scope = hashtab_search(pdb->scope[SYM_TYPES].table, key); 337 if (scope == NULL) { 338 return -1; 339 } 340 341 len = scope->decl_ids_len; 342 if (len > 0) { 343 scope_id = scope->decl_ids[len-1]; 344 if (typealias_lists[scope_id] == NULL) { 345 rc = list_init(&typealias_lists[scope_id]); 346 if (rc != 0) { 347 goto exit; 348 } 349 } 350 /* As typealias_lists[scope_id] does not hold the 351 * ownership of its items (typealias_list_destroy does 352 * not free the list items), "key" does not need to be 353 * strdup'ed before it is inserted in the list. 354 */ 355 list_prepend(typealias_lists[scope_id], key); 356 } 357 } 358 359 return 0; 360 361 exit: 362 return rc; 363 } 364 365 static void typealias_list_destroy(void) 366 { 367 uint32_t i; 368 for (i = 0; i < typealias_lists_len; i++) { 369 if (typealias_lists[i] != NULL) { 370 list_destroy(&typealias_lists[i]); 371 } 372 } 373 typealias_lists_len = 0; 374 free(typealias_lists); 375 typealias_lists = NULL; 376 } 377 378 static int typealias_list_create(struct policydb *pdb) 379 { 380 uint32_t max_decl_id = 0; 381 struct avrule_decl *decl; 382 struct avrule_block *block; 383 uint32_t rc = -1; 384 385 for (block = pdb->global; block != NULL; block = block->next) { 386 decl = block->branch_list; 387 if (decl != NULL && decl->decl_id > max_decl_id) { 388 max_decl_id = decl->decl_id; 389 } 390 } 391 392 typealias_lists = calloc(max_decl_id + 1, sizeof(*typealias_lists)); 393 typealias_lists_len = max_decl_id + 1; 394 395 rc = hashtab_map(pdb->p_types.table, typealiases_gather_map, pdb); 396 if (rc != 0) { 397 goto exit; 398 } 399 400 return 0; 401 402 exit: 403 typealias_list_destroy(); 404 405 return rc; 406 } 407 408 409 static int stack_destroy(struct stack **stack) 410 { 411 if (stack == NULL || *stack == NULL) { 412 return 0; 413 } 414 415 free((*stack)->stack); 416 free(*stack); 417 *stack = NULL; 418 419 return 0; 420 } 421 422 static int stack_init(struct stack **stack) 423 { 424 int rc = -1; 425 struct stack *s = calloc(1, sizeof(*s)); 426 if (s == NULL) { 427 goto exit; 428 } 429 430 s->stack = malloc(sizeof(*s->stack) * STACK_SIZE); 431 if (s->stack == NULL) { 432 goto exit; 433 } 434 435 s->pos = -1; 436 s->size = STACK_SIZE; 437 438 *stack = s; 439 440 return 0; 441 442 exit: 443 stack_destroy(&s); 444 return rc; 445 } 446 447 static int stack_push(struct stack *stack, void *ptr) 448 { 449 int rc = -1; 450 void *new_stack; 451 452 if (stack->pos + 1 == stack->size) { 453 new_stack = realloc(stack->stack, sizeof(*stack->stack) * (stack->size * 2)); 454 if (new_stack == NULL) { 455 goto exit; 456 } 457 stack->stack = new_stack; 458 stack->size *= 2; 459 } 460 461 stack->pos++; 462 stack->stack[stack->pos] = ptr; 463 464 rc = 0; 465 exit: 466 return rc; 467 } 468 469 static void *stack_pop(struct stack *stack) 470 { 471 if (stack->pos == -1) { 472 return NULL; 473 } 474 475 stack->pos--; 476 return stack->stack[stack->pos + 1]; 477 } 478 479 static void *stack_peek(struct stack *stack) 480 { 481 if (stack->pos == -1) { 482 return NULL; 483 } 484 485 return stack->stack[stack->pos]; 486 } 487 488 static int is_id_in_scope_with_start(struct policydb *pdb, struct stack *decl_stack, int start, uint32_t symbol_type, char *id) 489 { 490 int i; 491 uint32_t j; 492 struct avrule_decl *decl; 493 struct scope_datum *scope; 494 495 scope = hashtab_search(pdb->scope[symbol_type].table, id); 496 if (scope == NULL) { 497 return 0; 498 } 499 500 for (i = start; i >= 0; i--) { 501 decl = decl_stack->stack[i]; 502 503 for (j = 0; j < scope->decl_ids_len; j++) { 504 if (scope->decl_ids[j] == decl->decl_id) { 505 return 1; 506 } 507 } 508 } 509 510 return 0; 511 } 512 513 static int is_id_in_ancestor_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type) 514 { 515 int start = decl_stack->pos - 1; 516 517 return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type); 518 } 519 520 static int is_id_in_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type) 521 { 522 int start = decl_stack->pos; 523 524 return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type); 525 } 526 527 static int semantic_level_to_cil(struct policydb *pdb, int sens_offset, struct mls_semantic_level *level) 528 { 529 struct mls_semantic_cat *cat; 530 531 cil_printf("(%s ", pdb->p_sens_val_to_name[level->sens - sens_offset]); 532 533 if (level->cat != NULL) { 534 cil_printf("("); 535 } 536 537 for (cat = level->cat; cat != NULL; cat = cat->next) { 538 if (cat->low == cat->high) { 539 cil_printf("%s", pdb->p_cat_val_to_name[cat->low - 1]); 540 } else { 541 cil_printf("range %s %s", pdb->p_cat_val_to_name[cat->low - 1], pdb->p_cat_val_to_name[cat->high - 1]); 542 } 543 544 if (cat->next != NULL) { 545 cil_printf(" "); 546 } 547 } 548 549 if (level->cat != NULL) { 550 cil_printf(")"); 551 } 552 553 cil_printf(")"); 554 555 return 0; 556 } 557 558 static int avrule_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const struct class_perm_node *classperms) 559 { 560 int rc = -1; 561 const char *rule; 562 const struct class_perm_node *classperm; 563 char *perms; 564 565 switch (type) { 566 case AVRULE_ALLOWED: 567 rule = "allow"; 568 break; 569 case AVRULE_AUDITALLOW: 570 rule = "auditallow"; 571 break; 572 case AVRULE_AUDITDENY: 573 rule = "auditdenty"; 574 break; 575 case AVRULE_DONTAUDIT: 576 rule = "dontaudit"; 577 break; 578 case AVRULE_NEVERALLOW: 579 rule = "neverallow"; 580 break; 581 case AVRULE_TRANSITION: 582 rule = "typetransition"; 583 break; 584 case AVRULE_MEMBER: 585 rule = "typemember"; 586 break; 587 case AVRULE_CHANGE: 588 rule = "typechange"; 589 break; 590 default: 591 log_err("Unknown avrule type: %i", type); 592 rc = -1; 593 goto exit; 594 } 595 596 for (classperm = classperms; classperm != NULL; classperm = classperm->next) { 597 if (type & AVRULE_AV) { 598 perms = sepol_av_to_string(pdb, classperm->tclass, classperm->data); 599 if (perms == NULL) { 600 log_err("Failed to generate permission string"); 601 rc = -1; 602 goto exit; 603 } 604 cil_println(indent, "(%s %s %s (%s (%s)))", 605 rule, src, tgt, 606 pdb->p_class_val_to_name[classperm->tclass - 1], 607 perms + 1); 608 } else { 609 cil_println(indent, "(%s %s %s %s %s)", 610 rule, src, tgt, 611 pdb->p_class_val_to_name[classperm->tclass - 1], 612 pdb->p_type_val_to_name[classperm->data - 1]); 613 } 614 } 615 616 return 0; 617 618 exit: 619 return rc; 620 } 621 622 #define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p)) 623 624 static int xperms_to_cil(const av_extended_perms_t *xperms) 625 { 626 uint16_t value; 627 uint16_t low_bit; 628 uint16_t low_value; 629 unsigned int bit; 630 unsigned int in_range = 0; 631 int first = 1; 632 633 if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) 634 && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) 635 return -1; 636 637 for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { 638 if (!xperm_test(bit, xperms->perms)) 639 continue; 640 641 if (in_range && next_bit_in_range(bit, xperms->perms)) { 642 /* continue until high value found */ 643 continue; 644 } else if (next_bit_in_range(bit, xperms->perms)) { 645 /* low value */ 646 low_bit = bit; 647 in_range = 1; 648 continue; 649 } 650 651 if (!first) 652 cil_printf(" "); 653 else 654 first = 0; 655 656 if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { 657 value = xperms->driver<<8 | bit; 658 if (in_range) { 659 low_value = xperms->driver<<8 | low_bit; 660 cil_printf("(range 0x%hx 0x%hx)", low_value, value); 661 in_range = 0; 662 } else { 663 cil_printf("0x%hx", value); 664 } 665 } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { 666 value = bit << 8; 667 if (in_range) { 668 low_value = low_bit << 8; 669 cil_printf("(range 0x%hx 0x%hx)", low_value, (uint16_t) (value|0xff)); 670 in_range = 0; 671 } else { 672 cil_printf("(range 0x%hx 0x%hx)", value, (uint16_t) (value|0xff)); 673 } 674 } 675 } 676 677 return 0; 678 } 679 680 static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const class_perm_node_t *classperms, const av_extended_perms_t *xperms) 681 { 682 int rc = -1; 683 const char *rule; 684 const struct class_perm_node *classperm; 685 686 switch (type) { 687 case AVRULE_XPERMS_ALLOWED: 688 rule = "allowx"; 689 break; 690 case AVRULE_XPERMS_AUDITALLOW: 691 rule = "auditallowx"; 692 break; 693 case AVRULE_XPERMS_DONTAUDIT: 694 rule = "dontauditx"; 695 break; 696 case AVRULE_XPERMS_NEVERALLOW: 697 rule = "neverallowx"; 698 break; 699 default: 700 log_err("Unknown avrule xperm type: %i", type); 701 rc = -1; 702 goto exit; 703 } 704 705 for (classperm = classperms; classperm != NULL; classperm = classperm->next) { 706 cil_indent(indent); 707 cil_printf("(%s %s %s (%s %s (", rule, src, tgt, 708 "ioctl", pdb->p_class_val_to_name[classperm->tclass - 1]); 709 xperms_to_cil(xperms); 710 cil_printf(")))\n"); 711 } 712 713 return 0; 714 715 exit: 716 return rc; 717 } 718 719 static int num_digits(int n) 720 { 721 int num = 1; 722 while (n >= 10) { 723 n /= 10; 724 num++; 725 } 726 return num; 727 } 728 729 static int ebitmap_to_cil(struct policydb *pdb, struct ebitmap *map, int type) 730 { 731 struct ebitmap_node *node; 732 uint32_t i; 733 char **val_to_name = pdb->sym_val_to_name[type]; 734 735 ebitmap_for_each_bit(map, node, i) { 736 if (!ebitmap_get_bit(map, i)) { 737 continue; 738 } 739 cil_printf("%s ", val_to_name[i]); 740 } 741 742 return 0; 743 } 744 745 static char *get_new_attr_name(struct policydb *pdb, int is_type) 746 { 747 static unsigned int num_attrs = 0; 748 int len, rlen; 749 const char *infix; 750 char *attr_name = NULL; 751 752 num_attrs++; 753 754 if (is_type) { 755 infix = TYPEATTR_INFIX; 756 } else { 757 infix = ROLEATTR_INFIX; 758 } 759 760 len = strlen(pdb->name) + strlen(infix) + num_digits(num_attrs) + 1; 761 attr_name = malloc(len); 762 if (!attr_name) { 763 log_err("Out of memory"); 764 goto exit; 765 } 766 767 rlen = snprintf(attr_name, len, "%s%s%i", pdb->name, infix, num_attrs); 768 if (rlen < 0 || rlen >= len) { 769 log_err("Failed to generate attribute name"); 770 free(attr_name); 771 attr_name = NULL; 772 goto exit; 773 } 774 775 exit: 776 return attr_name; 777 } 778 779 static int cil_add_attr_to_list(struct list *attr_list, char *attr_name, int is_type, void *set) 780 { 781 struct attr_list_node *attr_list_node = NULL; 782 int rc = 0; 783 784 attr_list_node = calloc(1, sizeof(*attr_list_node)); 785 if (attr_list_node == NULL) { 786 log_err("Out of memory"); 787 rc = -1; 788 goto exit; 789 } 790 791 rc = list_prepend(attr_list, attr_list_node); 792 if (rc != 0) { 793 goto exit; 794 } 795 796 attr_list_node->attr_name = attr_name; 797 attr_list_node->is_type = is_type; 798 attr_list_node->set = set; 799 800 return rc; 801 802 exit: 803 free(attr_list_node); 804 return rc; 805 } 806 807 static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, void *set, char *attr_name) 808 { 809 // CIL doesn't support anonymous positive/negative/complemented sets. So 810 // instead we create a CIL type/roleattributeset that matches the set. If 811 // the set has a negative set, then convert it to is (P & !N), where P is 812 // the list of members in the positive set and N is the list of members 813 // in the negative set. Additionally, if the set is complemented, then wrap 814 // the whole thing with a negation. 815 816 struct ebitmap_node *node; 817 struct ebitmap *pos, *neg; 818 uint32_t flags; 819 unsigned i; 820 struct type_set *ts; 821 struct role_set *rs; 822 int has_positive, has_negative; 823 const char *kind; 824 char **val_to_name; 825 int rc = 0; 826 827 if (is_type) { 828 kind = "type"; 829 val_to_name = pdb->p_type_val_to_name; 830 ts = (struct type_set *)set; 831 pos = &ts->types; 832 neg = &ts->negset; 833 flags = ts->flags; 834 has_positive = pos && (ebitmap_length(pos) > 0); 835 has_negative = neg && (ebitmap_length(neg) > 0); 836 } else { 837 kind = "role"; 838 val_to_name = pdb->p_role_val_to_name; 839 rs = (struct role_set *)set; 840 pos = &rs->roles; 841 neg = NULL; 842 flags = rs->flags; 843 has_positive = pos && (ebitmap_length(pos) > 0); 844 has_negative = 0; 845 } 846 847 cil_println(indent, "(%sattribute %s)", kind, attr_name); 848 cil_indent(indent); 849 cil_printf("(%sattributeset %s ", kind, attr_name); 850 851 if (flags & TYPE_STAR) { 852 cil_printf("(all)"); 853 } 854 855 if (flags & TYPE_COMP) { 856 cil_printf("(not "); 857 } 858 859 if (has_positive && has_negative) { 860 cil_printf("(and "); 861 } 862 863 if (has_positive) { 864 cil_printf("("); 865 ebitmap_for_each_bit(pos, node, i) { 866 if (!ebitmap_get_bit(pos, i)) { 867 continue; 868 } 869 cil_printf("%s ", val_to_name[i]); 870 } 871 cil_printf(") "); 872 } 873 874 if (has_negative) { 875 cil_printf("(not ("); 876 877 ebitmap_for_each_bit(neg, node, i) { 878 if (!ebitmap_get_bit(neg, i)) { 879 continue; 880 } 881 cil_printf("%s ", val_to_name[i]); 882 } 883 884 cil_printf("))"); 885 } 886 887 if (has_positive && has_negative) { 888 cil_printf(")"); 889 } 890 891 if (flags & TYPE_COMP) { 892 cil_printf(")"); 893 } 894 895 cil_printf(")\n"); 896 897 return rc; 898 } 899 900 static int cil_print_attr_list(int indent, struct policydb *pdb, struct list *attr_list) 901 { 902 struct list_node *curr; 903 struct attr_list_node *node; 904 int rc = 0; 905 906 for (curr = attr_list->head; curr != NULL; curr = curr->next) { 907 node = curr->data; 908 rc = cil_print_attr_strs(indent, pdb, node->is_type, node->set, node->attr_name); 909 if (rc != 0) { 910 return rc; 911 } 912 } 913 914 return rc; 915 } 916 917 static char *search_attr_list(struct list *attr_list, int is_type, void *set) 918 { 919 struct list_node *curr; 920 struct attr_list_node *node; 921 struct role_set *rs1 = NULL, *rs2; 922 struct type_set *ts1 = NULL, *ts2; 923 924 if (is_type) { 925 ts1 = (struct type_set *)set; 926 } else { 927 rs1 = (struct role_set *)set; 928 } 929 930 for (curr = attr_list->head; curr != NULL; curr = curr->next) { 931 node = curr->data; 932 if (node->is_type != is_type) 933 continue; 934 if (ts1) { 935 ts2 = (struct type_set *)node->set; 936 if (ts1->flags != ts2->flags) 937 continue; 938 if (ebitmap_cmp(&ts1->negset, &ts2->negset) == 0) 939 continue; 940 if (ebitmap_cmp(&ts1->types, &ts2->types) == 0) 941 continue; 942 return node->attr_name; 943 } else { 944 rs2 = (struct role_set *)node->set; 945 if (rs1->flags != rs2->flags) 946 continue; 947 if (ebitmap_cmp(&rs1->roles, &rs2->roles) == 0) 948 continue; 949 return node->attr_name; 950 } 951 } 952 953 return NULL; 954 } 955 956 static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, int *num_names) 957 { 958 char *attr_name = NULL; 959 int rc = 0; 960 961 *names = NULL; 962 *num_names = 0; 963 964 attr_name = search_attr_list(attr_list, is_type, set); 965 966 if (!attr_name) { 967 attr_name = get_new_attr_name(pdb, is_type); 968 if (!attr_name) { 969 rc = -1; 970 goto exit; 971 } 972 973 rc = cil_add_attr_to_list(attr_list, attr_name, is_type, set); 974 if (rc != 0) { 975 free(attr_name); 976 goto exit; 977 } 978 } 979 980 *names = malloc(sizeof(char *)); 981 if (!*names) { 982 log_err("Out of memory"); 983 rc = -1; 984 goto exit; 985 } 986 *names[0] = attr_name; 987 *num_names = 1; 988 989 exit: 990 return rc; 991 } 992 993 static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, int *num_names) 994 { 995 int rc = 0; 996 struct ebitmap_node *node; 997 uint32_t i; 998 uint32_t num; 999 char **name_arr; 1000 1001 num = 0; 1002 ebitmap_for_each_bit(map, node, i) { 1003 if (ebitmap_get_bit(map, i)) { 1004 if (num >= UINT32_MAX / sizeof(*name_arr)) { 1005 log_err("Overflow"); 1006 rc = -1; 1007 goto exit; 1008 } 1009 num++; 1010 } 1011 } 1012 1013 if (!num) { 1014 *names = NULL; 1015 *num_names = 0; 1016 goto exit; 1017 } 1018 1019 name_arr = malloc(sizeof(*name_arr) * num); 1020 if (name_arr == NULL) { 1021 log_err("Out of memory"); 1022 rc = -1; 1023 goto exit; 1024 } 1025 1026 num = 0; 1027 ebitmap_for_each_bit(map, node, i) { 1028 if (ebitmap_get_bit(map, i)) { 1029 name_arr[num] = vals_to_names[i]; 1030 num++; 1031 } 1032 } 1033 1034 *names = name_arr; 1035 *num_names = num; 1036 1037 exit: 1038 return rc; 1039 } 1040 1041 static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, int *num_names) 1042 { 1043 int rc = 0; 1044 1045 *names = NULL; 1046 *num_names = 0; 1047 1048 if (rs->flags) { 1049 rc = set_to_names(pdb, 0, &rs->roles, attr_list, names, num_names); 1050 if (rc != 0) { 1051 goto exit; 1052 } 1053 } else { 1054 rc = ebitmap_to_names(&rs->roles, pdb->p_role_val_to_name, names, num_names); 1055 if (rc != 0) { 1056 goto exit; 1057 } 1058 } 1059 1060 exit: 1061 return rc; 1062 } 1063 1064 static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, int *num_names) 1065 { 1066 int rc = 0; 1067 1068 *names = NULL; 1069 *num_names = 0; 1070 1071 if (ebitmap_length(&ts->negset) > 0 || ts->flags != 0) { 1072 rc = set_to_names(pdb, 1, ts, attr_list, names, num_names); 1073 if (rc != 0) { 1074 goto exit; 1075 } 1076 } else { 1077 rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, names, num_names); 1078 if (rc != 0) { 1079 goto exit; 1080 } 1081 } 1082 1083 exit: 1084 return rc; 1085 } 1086 1087 static void names_destroy(char ***names, int *num_names) 1088 { 1089 free(*names); 1090 *names = NULL; 1091 *num_names = 0; 1092 } 1093 1094 static int roletype_role_in_ancestor_to_cil(struct policydb *pdb, struct stack *decl_stack, char *type_name, int indent) 1095 { 1096 struct list_node *curr; 1097 char **tnames = NULL; 1098 int num_tnames, i; 1099 struct role_list_node *role_node = NULL; 1100 int rc; 1101 struct type_set *ts; 1102 struct list *attr_list = NULL; 1103 1104 rc = list_init(&attr_list); 1105 if (rc != 0) { 1106 goto exit; 1107 } 1108 1109 for (curr = role_list->head; curr != NULL; curr = curr->next) { 1110 role_node = curr->data; 1111 if (!is_id_in_ancestor_scope(pdb, decl_stack, role_node->role_name, SYM_ROLES)) { 1112 continue; 1113 } 1114 1115 ts = &role_node->role->types; 1116 rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames); 1117 if (rc != 0) { 1118 goto exit; 1119 } 1120 for (i = 0; i < num_tnames; i++) { 1121 if (!strcmp(type_name, tnames[i])) { 1122 cil_println(indent, "(roletype %s %s)", role_node->role_name, type_name); 1123 } 1124 } 1125 names_destroy(&tnames, &num_tnames); 1126 } 1127 1128 rc = cil_print_attr_list(indent, pdb, attr_list); 1129 if (rc != 0) { 1130 goto exit; 1131 } 1132 1133 exit: 1134 attr_list_destroy(&attr_list); 1135 return rc; 1136 } 1137 1138 1139 static int name_list_to_string(char **names, int num_names, char **string) 1140 { 1141 // create a space separated string of the names 1142 int rc = -1; 1143 size_t len = 0; 1144 int i; 1145 char *str; 1146 char *strpos; 1147 1148 for (i = 0; i < num_names; i++) { 1149 len += strlen(names[i]); 1150 if (len < strlen(names[i])) { 1151 log_err("Overflow"); 1152 return -1; 1153 } 1154 } 1155 1156 // add spaces + null terminator 1157 len += num_names; 1158 if (len < (size_t)num_names) { 1159 log_err("Overflow"); 1160 return -1; 1161 } 1162 1163 if (!len) { 1164 log_err("Empty list"); 1165 return -1; 1166 } 1167 1168 str = malloc(len); 1169 if (str == NULL) { 1170 log_err("Out of memory"); 1171 rc = -1; 1172 goto exit; 1173 } 1174 str[0] = 0; 1175 1176 strpos = str; 1177 1178 for (i = 0; i < num_names; i++) { 1179 strpos = stpcpy(strpos, names[i]); 1180 if (i < num_names - 1) { 1181 *strpos++ = ' '; 1182 } 1183 } 1184 1185 *string = str; 1186 1187 return 0; 1188 exit: 1189 free(str); 1190 return rc; 1191 } 1192 1193 static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *avrule_list, struct list *attr_list) 1194 { 1195 int rc = -1; 1196 struct avrule *avrule; 1197 char **snames = NULL; 1198 char **tnames = NULL; 1199 int s, t, num_snames, num_tnames; 1200 struct type_set *ts; 1201 1202 for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) { 1203 if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) && 1204 avrule->source_filename) { 1205 cil_println(0, ";;* lmx %lu %s\n",avrule->source_line, avrule->source_filename); 1206 } 1207 1208 ts = &avrule->stypes; 1209 rc = process_typeset(pdb, ts, attr_list, &snames, &num_snames); 1210 if (rc != 0) { 1211 goto exit; 1212 } 1213 1214 ts = &avrule->ttypes; 1215 rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames); 1216 if (rc != 0) { 1217 goto exit; 1218 } 1219 1220 for (s = 0; s < num_snames; s++) { 1221 for (t = 0; t < num_tnames; t++) { 1222 if (avrule->specified & AVRULE_XPERMS) { 1223 rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms, avrule->xperms); 1224 } else { 1225 rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms); 1226 } 1227 if (rc != 0) { 1228 goto exit; 1229 } 1230 } 1231 1232 if (avrule->flags & RULE_SELF) { 1233 if (avrule->specified & AVRULE_XPERMS) { 1234 rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms, avrule->xperms); 1235 } else { 1236 rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms); 1237 } 1238 if (rc != 0) { 1239 goto exit; 1240 } 1241 } 1242 } 1243 1244 names_destroy(&snames, &num_snames); 1245 names_destroy(&tnames, &num_tnames); 1246 1247 if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) && 1248 avrule->source_filename) { 1249 cil_println(0, ";;* lme\n"); 1250 } 1251 } 1252 1253 return 0; 1254 1255 exit: 1256 names_destroy(&snames, &num_snames); 1257 names_destroy(&tnames, &num_tnames); 1258 1259 return rc; 1260 } 1261 1262 static int cond_expr_to_cil(int indent, struct policydb *pdb, struct cond_expr *cond_expr, uint32_t flags) 1263 { 1264 int rc = 0; 1265 struct cond_expr *curr; 1266 struct stack *stack = NULL; 1267 int len = 0; 1268 int rlen; 1269 char *new_val = NULL; 1270 char *val1 = NULL; 1271 char *val2 = NULL; 1272 int num_params; 1273 const char *op; 1274 const char *fmt_str; 1275 const char *type; 1276 1277 rc = stack_init(&stack); 1278 if (rc != 0) { 1279 log_err("Out of memory"); 1280 goto exit; 1281 } 1282 1283 for (curr = cond_expr; curr != NULL; curr = curr->next) { 1284 if (curr->expr_type == COND_BOOL) { 1285 val1 = pdb->p_bool_val_to_name[curr->bool - 1]; 1286 // length of boolean + 2 parens + null terminator 1287 len = strlen(val1) + 2 + 1; 1288 new_val = malloc(len); 1289 if (new_val == NULL) { 1290 log_err("Out of memory"); 1291 rc = -1; 1292 goto exit; 1293 } 1294 rlen = snprintf(new_val, len, "(%s)", val1); 1295 if (rlen < 0 || rlen >= len) { 1296 log_err("Failed to generate conditional expression"); 1297 rc = -1; 1298 goto exit; 1299 } 1300 } else { 1301 switch(curr->expr_type) { 1302 case COND_NOT: op = "not"; break; 1303 case COND_OR: op = "or"; break; 1304 case COND_AND: op = "and"; break; 1305 case COND_XOR: op = "xor"; break; 1306 case COND_EQ: op = "eq"; break; 1307 case COND_NEQ: op = "neq"; break; 1308 default: 1309 rc = -1; 1310 goto exit; 1311 } 1312 1313 num_params = curr->expr_type == COND_NOT ? 1 : 2; 1314 1315 if (num_params == 1) { 1316 val1 = stack_pop(stack); 1317 val2 = strdup(""); 1318 if (val2 == NULL) { 1319 log_err("Out of memory"); 1320 rc = -1; 1321 goto exit; 1322 } 1323 fmt_str = "(%s %s)"; 1324 } else { 1325 val2 = stack_pop(stack); 1326 val1 = stack_pop(stack); 1327 fmt_str = "(%s %s %s)"; 1328 } 1329 1330 if (val1 == NULL || val2 == NULL) { 1331 log_err("Invalid conditional expression"); 1332 rc = -1; 1333 goto exit; 1334 } 1335 1336 // length = length of parameters + 1337 // length of operator + 1338 // 1 space preceeding each parameter + 1339 // 2 parens around the whole expression 1340 // + null terminator 1341 len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1; 1342 new_val = malloc(len); 1343 if (new_val == NULL) { 1344 log_err("Out of memory"); 1345 rc = -1; 1346 goto exit; 1347 } 1348 1349 // although we always supply val2 and there isn't always a 2nd 1350 // value, it should only be used when there are actually two values 1351 // in the format strings 1352 rlen = snprintf(new_val, len, fmt_str, op, val1, val2); 1353 if (rlen < 0 || rlen >= len) { 1354 log_err("Failed to generate conditional expression"); 1355 rc = -1; 1356 goto exit; 1357 } 1358 1359 free(val1); 1360 free(val2); 1361 val1 = NULL; 1362 val2 = NULL; 1363 } 1364 1365 rc = stack_push(stack, new_val); 1366 if (rc != 0) { 1367 log_err("Out of memory"); 1368 goto exit; 1369 } 1370 new_val = NULL; 1371 } 1372 1373 if (flags & COND_NODE_FLAGS_TUNABLE) { 1374 type = "tunableif"; 1375 } else { 1376 type = "booleanif"; 1377 } 1378 1379 val1 = stack_pop(stack); 1380 if (val1 == NULL || stack_peek(stack) != NULL) { 1381 log_err("Invalid conditional expression"); 1382 rc = -1; 1383 goto exit; 1384 } 1385 1386 cil_println(indent, "(%s %s", type, val1); 1387 free(val1); 1388 val1 = NULL; 1389 1390 rc = 0; 1391 1392 exit: 1393 free(new_val); 1394 free(val1); 1395 free(val2); 1396 if (stack != NULL) { 1397 while ((val1 = stack_pop(stack)) != NULL) { 1398 free(val1); 1399 } 1400 stack_destroy(&stack); 1401 } 1402 return rc; 1403 } 1404 1405 static int cond_list_to_cil(int indent, struct policydb *pdb, struct cond_node *cond_list, struct list *attr_list) 1406 { 1407 int rc = 0; 1408 struct cond_node *cond; 1409 1410 for (cond = cond_list; cond != NULL; cond = cond->next) { 1411 1412 rc = cond_expr_to_cil(indent, pdb, cond->expr, cond->flags); 1413 if (rc != 0) { 1414 goto exit; 1415 } 1416 1417 if (cond->avtrue_list != NULL) { 1418 cil_println(indent + 1, "(true"); 1419 rc = avrule_list_to_cil(indent + 2, pdb, cond->avtrue_list, attr_list); 1420 if (rc != 0) { 1421 goto exit; 1422 } 1423 cil_println(indent + 1, ")"); 1424 } 1425 1426 if (cond->avfalse_list != NULL) { 1427 cil_println(indent + 1, "(false"); 1428 rc = avrule_list_to_cil(indent + 2, pdb, cond->avfalse_list, attr_list); 1429 if (rc != 0) { 1430 goto exit; 1431 } 1432 cil_println(indent + 1, ")"); 1433 } 1434 1435 cil_println(indent, ")"); 1436 } 1437 1438 exit: 1439 return rc; 1440 } 1441 1442 static int role_trans_to_cil(int indent, struct policydb *pdb, struct role_trans_rule *rules, struct list *role_attr_list, struct list *type_attr_list) 1443 { 1444 int rc = 0; 1445 struct role_trans_rule *rule; 1446 char **role_names = NULL; 1447 int num_role_names = 0; 1448 int role; 1449 char **type_names = NULL; 1450 int num_type_names = 0; 1451 int type; 1452 uint32_t i; 1453 struct ebitmap_node *node; 1454 struct type_set *ts; 1455 struct role_set *rs; 1456 1457 for (rule = rules; rule != NULL; rule = rule->next) { 1458 rs = &rule->roles; 1459 rc = process_roleset(pdb, rs, role_attr_list, &role_names, &num_role_names); 1460 if (rc != 0) { 1461 goto exit; 1462 } 1463 1464 ts = &rule->types; 1465 rc = process_typeset(pdb, ts, type_attr_list, &type_names, &num_type_names); 1466 if (rc != 0) { 1467 goto exit; 1468 } 1469 1470 for (role = 0; role < num_role_names; role++) { 1471 for (type = 0; type < num_type_names; type++) { 1472 ebitmap_for_each_bit(&rule->classes, node, i) { 1473 if (!ebitmap_get_bit(&rule->classes, i)) { 1474 continue; 1475 } 1476 cil_println(indent, "(roletransition %s %s %s %s)", 1477 role_names[role], type_names[type], 1478 pdb->p_class_val_to_name[i], 1479 pdb->p_role_val_to_name[rule->new_role - 1]); 1480 } 1481 } 1482 } 1483 1484 names_destroy(&role_names, &num_role_names); 1485 names_destroy(&type_names, &num_type_names); 1486 } 1487 1488 exit: 1489 names_destroy(&role_names, &num_role_names); 1490 names_destroy(&type_names, &num_type_names); 1491 1492 return rc; 1493 } 1494 1495 static int role_allows_to_cil(int indent, struct policydb *pdb, struct role_allow_rule *rules, struct list *attr_list) 1496 { 1497 int rc = -1; 1498 struct role_allow_rule *rule; 1499 char **roles = NULL; 1500 int num_roles = 0; 1501 char **new_roles = NULL; 1502 int num_new_roles = 0; 1503 int i,j; 1504 struct role_set *rs; 1505 1506 for (rule = rules; rule != NULL; rule = rule->next) { 1507 rs = &rule->roles; 1508 rc = process_roleset(pdb, rs, attr_list, &roles, &num_roles); 1509 if (rc != 0) { 1510 goto exit; 1511 } 1512 1513 rs = &rule->new_roles; 1514 rc = process_roleset(pdb, rs, attr_list, &new_roles, &num_new_roles); 1515 if (rc != 0) { 1516 goto exit; 1517 } 1518 1519 for (i = 0; i < num_roles; i++) { 1520 for (j = 0; j < num_new_roles; j++) { 1521 cil_println(indent, "(roleallow %s %s)", roles[i], new_roles[j]); 1522 } 1523 } 1524 1525 names_destroy(&roles, &num_roles); 1526 names_destroy(&new_roles, &num_new_roles); 1527 } 1528 1529 rc = 0; 1530 1531 exit: 1532 names_destroy(&roles, &num_roles); 1533 names_destroy(&new_roles, &num_new_roles); 1534 1535 return rc; 1536 } 1537 1538 static int range_trans_to_cil(int indent, struct policydb *pdb, struct range_trans_rule *rules, struct list *attr_list) 1539 { 1540 int rc = -1; 1541 struct range_trans_rule *rule; 1542 char **stypes = NULL; 1543 int num_stypes = 0; 1544 int stype; 1545 char **ttypes = NULL; 1546 int num_ttypes = 0; 1547 int ttype; 1548 struct ebitmap_node *node; 1549 uint32_t i; 1550 struct type_set *ts; 1551 1552 if (!pdb->mls) { 1553 return 0; 1554 } 1555 1556 for (rule = rules; rule != NULL; rule = rule->next) { 1557 ts = &rule->stypes; 1558 rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes); 1559 if (rc != 0) { 1560 goto exit; 1561 } 1562 1563 ts = &rule->ttypes; 1564 rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes); 1565 if (rc != 0) { 1566 goto exit; 1567 } 1568 1569 for (stype = 0; stype < num_stypes; stype++) { 1570 for (ttype = 0; ttype < num_ttypes; ttype++) { 1571 ebitmap_for_each_bit(&rule->tclasses, node, i) { 1572 if (!ebitmap_get_bit(&rule->tclasses, i)) { 1573 continue; 1574 } 1575 1576 cil_indent(indent); 1577 cil_printf("(rangetransition %s %s %s ", stypes[stype], ttypes[ttype], pdb->p_class_val_to_name[i]); 1578 1579 cil_printf("("); 1580 1581 rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[0]); 1582 if (rc != 0) { 1583 goto exit; 1584 } 1585 1586 cil_printf(" "); 1587 1588 rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[1]); 1589 if (rc != 0) { 1590 goto exit; 1591 } 1592 1593 cil_printf("))\n"); 1594 } 1595 1596 } 1597 } 1598 1599 names_destroy(&stypes, &num_stypes); 1600 names_destroy(&ttypes, &num_ttypes); 1601 } 1602 1603 rc = 0; 1604 1605 exit: 1606 names_destroy(&stypes, &num_stypes); 1607 names_destroy(&ttypes, &num_ttypes); 1608 1609 return rc; 1610 } 1611 1612 static int filename_trans_to_cil(int indent, struct policydb *pdb, struct filename_trans_rule *rules, struct list *attr_list) 1613 { 1614 int rc = -1; 1615 char **stypes = NULL; 1616 int num_stypes = 0; 1617 int stype; 1618 char **ttypes = NULL; 1619 int num_ttypes = 0; 1620 int ttype; 1621 struct type_set *ts; 1622 struct filename_trans_rule *rule; 1623 1624 for (rule = rules; rule != NULL; rule = rule->next) { 1625 ts = &rule->stypes; 1626 rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes); 1627 if (rc != 0) { 1628 goto exit; 1629 } 1630 1631 ts = &rule->ttypes; 1632 rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes); 1633 if (rc != 0) { 1634 goto exit; 1635 } 1636 1637 for (stype = 0; stype < num_stypes; stype++) { 1638 for (ttype = 0; ttype < num_ttypes; ttype++) { 1639 cil_println(indent, "(typetransition %s %s %s \"%s\" %s)", 1640 stypes[stype], ttypes[ttype], 1641 pdb->p_class_val_to_name[rule->tclass - 1], 1642 rule->name, 1643 pdb->p_type_val_to_name[rule->otype - 1]); 1644 } 1645 } 1646 1647 names_destroy(&stypes, &num_stypes); 1648 names_destroy(&ttypes, &num_ttypes); 1649 } 1650 1651 rc = 0; 1652 exit: 1653 names_destroy(&stypes, &num_stypes); 1654 names_destroy(&ttypes, &num_ttypes); 1655 1656 return rc; 1657 } 1658 1659 struct class_perm_datum { 1660 char *name; 1661 uint32_t val; 1662 }; 1663 1664 struct class_perm_array { 1665 struct class_perm_datum *perms; 1666 uint32_t count; 1667 }; 1668 1669 static int class_perm_to_array(char *key, void *data, void *args) 1670 { 1671 struct class_perm_array *arr = args; 1672 struct perm_datum *datum = data; 1673 arr->perms[arr->count].name = key; 1674 arr->perms[arr->count].val = datum->s.value; 1675 arr->count++; 1676 1677 return 0; 1678 } 1679 1680 static int class_perm_cmp(const void *a, const void *b) 1681 { 1682 const struct class_perm_datum *aa = a; 1683 const struct class_perm_datum *bb = b; 1684 1685 return aa->val - bb->val; 1686 } 1687 1688 static int common_to_cil(char *key, void *data, void *UNUSED(arg)) 1689 { 1690 int rc = -1; 1691 struct common_datum *common = data; 1692 struct class_perm_array arr; 1693 uint32_t i; 1694 1695 arr.count = 0; 1696 arr.perms = calloc(common->permissions.nprim, sizeof(*arr.perms)); 1697 if (arr.perms == NULL) { 1698 goto exit; 1699 } 1700 rc = hashtab_map(common->permissions.table, class_perm_to_array, &arr); 1701 if (rc != 0) { 1702 goto exit; 1703 } 1704 1705 qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp); 1706 1707 cil_printf("(common %s (", key); 1708 for (i = 0; i < arr.count; i++) { 1709 cil_printf("%s ", arr.perms[i].name); 1710 } 1711 cil_printf("))\n"); 1712 1713 rc = 0; 1714 1715 exit: 1716 free(arr.perms); 1717 return rc; 1718 } 1719 1720 1721 static int constraint_expr_to_string(struct policydb *pdb, struct constraint_expr *exprs, char **expr_string) 1722 { 1723 int rc = -1; 1724 struct constraint_expr *expr; 1725 struct stack *stack = NULL; 1726 int len = 0; 1727 int rlen; 1728 char *new_val = NULL; 1729 char *val1 = NULL; 1730 char *val2 = NULL; 1731 uint32_t num_params; 1732 const char *op; 1733 const char *fmt_str; 1734 const char *attr1; 1735 const char *attr2; 1736 char *names = NULL; 1737 char **name_list = NULL; 1738 int num_names = 0; 1739 struct type_set *ts; 1740 1741 rc = stack_init(&stack); 1742 if (rc != 0) { 1743 goto exit; 1744 } 1745 1746 for (expr = exprs; expr != NULL; expr = expr->next) { 1747 if (expr->expr_type == CEXPR_ATTR || expr->expr_type == CEXPR_NAMES) { 1748 switch (expr->op) { 1749 case CEXPR_EQ: op = "eq"; break; 1750 case CEXPR_NEQ: op = "neq"; break; 1751 case CEXPR_DOM: op = "dom"; break; 1752 case CEXPR_DOMBY: op = "domby"; break; 1753 case CEXPR_INCOMP: op = "incomp"; break; 1754 default: 1755 log_err("Unknown constraint operator type: %i", expr->op); 1756 rc = -1; 1757 goto exit; 1758 } 1759 1760 switch (expr->attr) { 1761 case CEXPR_USER: attr1 = "u1"; attr2 = "u2"; break; 1762 case CEXPR_USER | CEXPR_TARGET: attr1 = "u2"; attr2 = ""; break; 1763 case CEXPR_USER | CEXPR_XTARGET: attr1 = "u3"; attr2 = ""; break; 1764 case CEXPR_ROLE: attr1 = "r1"; attr2 = "r2"; break; 1765 case CEXPR_ROLE | CEXPR_TARGET: attr1 = "r2"; attr2 = ""; break; 1766 case CEXPR_ROLE | CEXPR_XTARGET: attr1 = "r3"; attr2 = ""; break; 1767 case CEXPR_TYPE: attr1 = "t1"; attr2 = ""; break; 1768 case CEXPR_TYPE | CEXPR_TARGET: attr1 = "t2"; attr2 = ""; break; 1769 case CEXPR_TYPE | CEXPR_XTARGET: attr1 = "t3"; attr2 = ""; break; 1770 case CEXPR_L1L2: attr1 = "l1"; attr2 = "l2"; break; 1771 case CEXPR_L1H2: attr1 = "l1"; attr2 = "h2"; break; 1772 case CEXPR_H1L2: attr1 = "h1"; attr2 = "l2"; break; 1773 case CEXPR_H1H2: attr1 = "h1"; attr2 = "h2"; break; 1774 case CEXPR_L1H1: attr1 = "l1"; attr2 = "h1"; break; 1775 case CEXPR_L2H2: attr1 = "l2"; attr2 = "h2"; break; 1776 default: 1777 log_err("Unknown expression attribute type: %i", expr->attr); 1778 rc = -1; 1779 goto exit; 1780 } 1781 1782 if (expr->expr_type == CEXPR_ATTR) { 1783 // length of values/attrs + 2 separating spaces + 2 parens + null terminator 1784 len = strlen(op) + strlen(attr1) + strlen(attr2) + 2 + 2 + 1; 1785 new_val = malloc(len); 1786 if (new_val == NULL) { 1787 log_err("Out of memory"); 1788 rc = -1; 1789 goto exit; 1790 } 1791 rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, attr2); 1792 if (rlen < 0 || rlen >= len) { 1793 log_err("Failed to generate constraint expression"); 1794 rc = -1; 1795 goto exit; 1796 } 1797 } else { 1798 if (expr->attr & CEXPR_TYPE) { 1799 ts = expr->type_names; 1800 rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, &name_list, &num_names); 1801 if (rc != 0) { 1802 goto exit; 1803 } 1804 } else if (expr->attr & CEXPR_USER) { 1805 rc = ebitmap_to_names(&expr->names, pdb->p_user_val_to_name, &name_list, &num_names); 1806 if (rc != 0) { 1807 goto exit; 1808 } 1809 } else if (expr->attr & CEXPR_ROLE) { 1810 rc = ebitmap_to_names(&expr->names, pdb->p_role_val_to_name, &name_list, &num_names); 1811 if (rc != 0) { 1812 goto exit; 1813 } 1814 } 1815 rc = name_list_to_string(name_list, num_names, &names); 1816 if (rc != 0) { 1817 goto exit; 1818 } 1819 1820 // length of values/oper + 2 spaces + 2 parens + null terminator 1821 len = strlen(op) + strlen(attr1) + strlen(names) + 2 + 2 + 1; 1822 new_val = malloc(len); 1823 if (new_val == NULL) { 1824 log_err("Out of memory"); 1825 rc = -1; 1826 goto exit; 1827 } 1828 rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names); 1829 if (rlen < 0 || rlen >= len) { 1830 log_err("Failed to generate constraint expression"); 1831 rc = -1; 1832 goto exit; 1833 } 1834 1835 names_destroy(&name_list, &num_names); 1836 free(names); 1837 names = NULL; 1838 } 1839 } else { 1840 switch (expr->expr_type) { 1841 case CEXPR_NOT: op = "not"; break; 1842 case CEXPR_AND: op = "and"; break; 1843 case CEXPR_OR: op = "or"; break; 1844 default: 1845 log_err("Unknown constraint expression type: %i", expr->expr_type); 1846 rc = -1; 1847 goto exit; 1848 } 1849 1850 num_params = expr->expr_type == CEXPR_NOT ? 1 : 2; 1851 1852 if (num_params == 1) { 1853 val1 = stack_pop(stack); 1854 val2 = strdup(""); 1855 if (val2 == NULL) { 1856 log_err("Out of memory"); 1857 rc = -1; 1858 goto exit; 1859 } 1860 fmt_str = "(%s %s)"; 1861 } else { 1862 val2 = stack_pop(stack); 1863 val1 = stack_pop(stack); 1864 fmt_str = "(%s %s %s)"; 1865 } 1866 1867 if (val1 == NULL || val2 == NULL) { 1868 log_err("Invalid constraint expression"); 1869 rc = -1; 1870 goto exit; 1871 } 1872 1873 // length = length of parameters + 1874 // length of operator + 1875 // 1 space preceeding each parameter + 1876 // 2 parens around the whole expression 1877 // + null terminator 1878 len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1; 1879 new_val = malloc(len); 1880 if (new_val == NULL) { 1881 log_err("Out of memory"); 1882 rc = -1; 1883 goto exit; 1884 } 1885 1886 // although we always supply val2 and there isn't always a 2nd 1887 // value, it should only be used when there are actually two values 1888 // in the format strings 1889 rlen = snprintf(new_val, len, fmt_str, op, val1, val2); 1890 if (rlen < 0 || rlen >= len) { 1891 log_err("Failed to generate constraint expression"); 1892 rc = -1; 1893 goto exit; 1894 } 1895 1896 free(val1); 1897 free(val2); 1898 val1 = NULL; 1899 val2 = NULL; 1900 } 1901 1902 rc = stack_push(stack, new_val); 1903 if (rc != 0) { 1904 log_err("Out of memory"); 1905 goto exit; 1906 } 1907 1908 new_val = NULL; 1909 } 1910 1911 new_val = stack_pop(stack); 1912 if (new_val == NULL || stack_peek(stack) != NULL) { 1913 log_err("Invalid constraint expression"); 1914 rc = -1; 1915 goto exit; 1916 } 1917 1918 *expr_string = new_val; 1919 new_val = NULL; 1920 1921 rc = 0; 1922 1923 exit: 1924 names_destroy(&name_list, &num_names); 1925 free(names); 1926 1927 free(new_val); 1928 free(val1); 1929 free(val2); 1930 if (stack != NULL) { 1931 while ((val1 = stack_pop(stack)) != NULL) { 1932 free(val1); 1933 } 1934 stack_destroy(&stack); 1935 } 1936 1937 return rc; 1938 } 1939 1940 1941 static int constraints_to_cil(int indent, struct policydb *pdb, char *classkey, struct class_datum *class, struct constraint_node *constraints, int is_constraint) 1942 { 1943 int rc = -1; 1944 struct constraint_node *node; 1945 char *expr = NULL; 1946 const char *mls; 1947 char *perms; 1948 1949 mls = pdb->mls ? "mls" : ""; 1950 1951 for (node = constraints; node != NULL; node = node->next) { 1952 1953 rc = constraint_expr_to_string(pdb, node->expr, &expr); 1954 if (rc != 0) { 1955 goto exit; 1956 } 1957 1958 if (is_constraint) { 1959 perms = sepol_av_to_string(pdb, class->s.value, node->permissions); 1960 cil_println(indent, "(%sconstrain (%s (%s)) %s)", mls, classkey, perms + 1, expr); 1961 } else { 1962 cil_println(indent, "(%svalidatetrans %s %s)", mls, classkey, expr); 1963 } 1964 1965 free(expr); 1966 expr = NULL; 1967 } 1968 1969 rc = 0; 1970 1971 exit: 1972 free(expr); 1973 return rc; 1974 } 1975 1976 static int class_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) 1977 { 1978 int rc = -1; 1979 struct class_datum *class = datum; 1980 const char *dflt; 1981 struct class_perm_array arr; 1982 uint32_t i; 1983 1984 if (scope == SCOPE_REQ) { 1985 return 0; 1986 } 1987 1988 arr.count = 0; 1989 arr.perms = calloc(class->permissions.nprim, sizeof(*arr.perms)); 1990 if (arr.perms == NULL) { 1991 goto exit; 1992 } 1993 rc = hashtab_map(class->permissions.table, class_perm_to_array, &arr); 1994 if (rc != 0) { 1995 goto exit; 1996 } 1997 1998 qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp); 1999 2000 cil_indent(indent); 2001 cil_printf("(class %s (", key); 2002 for (i = 0; i < arr.count; i++) { 2003 cil_printf("%s ", arr.perms[i].name); 2004 } 2005 cil_printf("))\n"); 2006 2007 if (class->comkey != NULL) { 2008 cil_println(indent, "(classcommon %s %s)", key, class->comkey); 2009 } 2010 2011 if (class->default_user != 0) { 2012 switch (class->default_user) { 2013 case DEFAULT_SOURCE: dflt = "source"; break; 2014 case DEFAULT_TARGET: dflt = "target"; break; 2015 default: 2016 log_err("Unknown default user value: %i", class->default_user); 2017 rc = -1; 2018 goto exit; 2019 } 2020 cil_println(indent, "(defaultuser %s %s)", key, dflt); 2021 } 2022 2023 if (class->default_role != 0) { 2024 switch (class->default_role) { 2025 case DEFAULT_SOURCE: dflt = "source"; break; 2026 case DEFAULT_TARGET: dflt = "target"; break; 2027 default: 2028 log_err("Unknown default role value: %i", class->default_role); 2029 rc = -1; 2030 goto exit; 2031 } 2032 cil_println(indent, "(defaultrole %s %s)", key, dflt); 2033 } 2034 2035 if (class->default_type != 0) { 2036 switch (class->default_type) { 2037 case DEFAULT_SOURCE: dflt = "source"; break; 2038 case DEFAULT_TARGET: dflt = "target"; break; 2039 default: 2040 log_err("Unknown default type value: %i", class->default_type); 2041 rc = -1; 2042 goto exit; 2043 } 2044 cil_println(indent, "(defaulttype %s %s)", key, dflt); 2045 } 2046 2047 if (class->default_range != 0) { 2048 switch (class->default_range) { 2049 case DEFAULT_SOURCE_LOW: dflt = "source low"; break; 2050 case DEFAULT_SOURCE_HIGH: dflt = "source high"; break; 2051 case DEFAULT_SOURCE_LOW_HIGH: dflt = "source low-high"; break; 2052 case DEFAULT_TARGET_LOW: dflt = "target low"; break; 2053 case DEFAULT_TARGET_HIGH: dflt = "target high"; break; 2054 case DEFAULT_TARGET_LOW_HIGH: dflt = "target low-high"; break; 2055 default: 2056 log_err("Unknown default range value: %i", class->default_range); 2057 rc = -1; 2058 goto exit; 2059 } 2060 cil_println(indent, "(defaultrange %s %s)", key, dflt); 2061 2062 } 2063 2064 if (class->constraints != NULL) { 2065 rc = constraints_to_cil(indent, pdb, key, class, class->constraints, 1); 2066 if (rc != 0) { 2067 goto exit; 2068 } 2069 } 2070 2071 if (class->validatetrans != NULL) { 2072 rc = constraints_to_cil(indent, pdb, key, class, class->validatetrans, 0); 2073 if (rc != 0) { 2074 goto exit; 2075 } 2076 } 2077 2078 rc = 0; 2079 2080 exit: 2081 free(arr.perms); 2082 return rc; 2083 } 2084 2085 static int class_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order) 2086 { 2087 struct ebitmap_node *node; 2088 uint32_t i; 2089 2090 if (ebitmap_cardinality(&order) == 0) { 2091 return 0; 2092 } 2093 2094 cil_indent(indent); 2095 cil_printf("(classorder ("); 2096 2097 ebitmap_for_each_bit(&order, node, i) { 2098 if (!ebitmap_get_bit(&order, i)) { 2099 continue; 2100 } 2101 cil_printf("%s ", pdb->sym_val_to_name[SYM_CLASSES][i]); 2102 } 2103 2104 cil_printf("))\n"); 2105 2106 return 0; 2107 } 2108 2109 static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope) 2110 { 2111 int rc = -1; 2112 struct ebitmap_node *node; 2113 uint32_t i; 2114 int j; 2115 char **types = NULL; 2116 int num_types = 0; 2117 struct role_datum *role = datum; 2118 struct type_set *ts; 2119 struct list *attr_list = NULL; 2120 2121 rc = list_init(&attr_list); 2122 if (rc != 0) { 2123 goto exit; 2124 } 2125 2126 if (scope == SCOPE_REQ) { 2127 // if a role/roleattr is in the REQ scope, then it could cause an 2128 // optional block to fail, even if it is never used. However in CIL, 2129 // symbols must be used in order to cause an optional block to fail. So 2130 // for symbols in the REQ scope, add them to a roleattribute as a way 2131 // to 'use' them in the optional without affecting the resulting policy. 2132 cil_println(indent, "(roleattributeset " GEN_REQUIRE_ATTR " %s)", key); 2133 } 2134 2135 switch (role->flavor) { 2136 case ROLE_ROLE: 2137 if (scope == SCOPE_DECL) { 2138 // Only declare certain roles if we are reading a base module. 2139 // These roles are defined in the base module and sometimes in 2140 // other non-base modules. If we generated the roles regardless of 2141 // the policy type, it would result in duplicate declarations, 2142 // which isn't allowed in CIL. Patches have been made to refpolicy 2143 // to remove these duplicate role declarations, but we need to be 2144 // backwards compatible and support older policies. Since we know 2145 // these roles are always declared in base, only print them when we 2146 // see them in the base module. If the declarations appear in a 2147 // non-base module, ignore their declarations. 2148 // 2149 // Note that this is a hack, and if a policy author does not define 2150 // one of these roles in base, the declaration will not appear in 2151 // the resulting policy, likely resulting in a compilation error in 2152 // CIL. 2153 // 2154 // To make things more complicated, the auditadm_r and secadm_r 2155 // roles could actually be in either the base module or a non-base 2156 // module, or both. So we can't rely on this same behavior. So for 2157 // these roles, don't declare them here, even if they are in a base 2158 // or non-base module. Instead we will just declare them in the 2159 // base module elsewhere. 2160 int is_base_role = (!strcmp(key, "user_r") || 2161 !strcmp(key, "staff_r") || 2162 !strcmp(key, "sysadm_r") || 2163 !strcmp(key, "system_r") || 2164 !strcmp(key, "unconfined_r")); 2165 int is_builtin_role = (!strcmp(key, "auditadm_r") || 2166 !strcmp(key, "secadm_r")); 2167 if ((is_base_role && pdb->policy_type == SEPOL_POLICY_BASE) || 2168 (!is_base_role && !is_builtin_role)) { 2169 cil_println(indent, "(role %s)", key); 2170 } 2171 } 2172 2173 if (ebitmap_cardinality(&role->dominates) > 1) { 2174 log_err("Warning: role 'dominance' statement unsupported in CIL. Dropping from output."); 2175 } 2176 2177 ts = &role->types; 2178 rc = process_typeset(pdb, ts, attr_list, &types, &num_types); 2179 if (rc != 0) { 2180 goto exit; 2181 } 2182 2183 for (j = 0; j < num_types; j++) { 2184 if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) { 2185 cil_println(indent, "(roletype %s %s)", key, types[j]); 2186 } 2187 } 2188 2189 if (role->bounds > 0) { 2190 cil_println(indent, "(rolebounds %s %s)", key, pdb->p_role_val_to_name[role->bounds - 1]); 2191 } 2192 break; 2193 2194 case ROLE_ATTRIB: 2195 if (scope == SCOPE_DECL) { 2196 cil_println(indent, "(roleattribute %s)", key); 2197 } 2198 2199 if (ebitmap_cardinality(&role->roles) > 0) { 2200 cil_indent(indent); 2201 cil_printf("(roleattributeset %s (", key); 2202 ebitmap_for_each_bit(&role->roles, node, i) { 2203 if (!ebitmap_get_bit(&role->roles, i)) { 2204 continue; 2205 } 2206 cil_printf("%s ", pdb->p_role_val_to_name[i]); 2207 } 2208 cil_printf("))\n"); 2209 } 2210 2211 ts = &role->types; 2212 rc = process_typeset(pdb, ts, attr_list, &types, &num_types); 2213 if (rc != 0) { 2214 goto exit; 2215 } 2216 2217 2218 for (j = 0; j < num_types; j++) { 2219 if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) { 2220 cil_println(indent, "(roletype %s %s)", key, types[j]); 2221 } 2222 } 2223 2224 break; 2225 2226 default: 2227 log_err("Unknown role type: %i", role->flavor); 2228 rc = -1; 2229 goto exit; 2230 } 2231 2232 rc = cil_print_attr_list(indent, pdb, attr_list); 2233 if (rc != 0) { 2234 goto exit; 2235 } 2236 2237 exit: 2238 attr_list_destroy(&attr_list); 2239 names_destroy(&types, &num_types); 2240 2241 return rc; 2242 } 2243 2244 static int type_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope) 2245 { 2246 int rc = -1; 2247 struct type_datum *type = datum; 2248 2249 if (scope == SCOPE_REQ) { 2250 // if a type/typeattr is in the REQ scope, then it could cause an 2251 // optional block to fail, even if it is never used. However in CIL, 2252 // symbols must be used in order to cause an optional block to fail. So 2253 // for symbols in the REQ scope, add them to a typeattribute as a way 2254 // to 'use' them in the optional without affecting the resulting policy. 2255 cil_println(indent, "(typeattributeset " GEN_REQUIRE_ATTR " %s)", key); 2256 } 2257 2258 rc = roletype_role_in_ancestor_to_cil(pdb, decl_stack, key, indent); 2259 if (rc != 0) { 2260 goto exit; 2261 } 2262 2263 switch(type->flavor) { 2264 case TYPE_TYPE: 2265 if (scope == SCOPE_DECL) { 2266 cil_println(indent, "(type %s)", key); 2267 // object_r is implicit in checkmodule, but not with CIL, 2268 // create it as part of base 2269 cil_println(indent, "(roletype " DEFAULT_OBJECT " %s)", key); 2270 } 2271 2272 if (type->flags & TYPE_FLAGS_PERMISSIVE) { 2273 cil_println(indent, "(typepermissive %s)", key); 2274 } 2275 2276 if (type->bounds > 0) { 2277 cil_println(indent, "(typebounds %s %s)", pdb->p_type_val_to_name[type->bounds - 1], key); 2278 } 2279 break; 2280 case TYPE_ATTRIB: 2281 if (scope == SCOPE_DECL) { 2282 cil_println(indent, "(typeattribute %s)", key); 2283 } 2284 2285 if (type->flags & TYPE_FLAGS_EXPAND_ATTR) { 2286 cil_indent(indent); 2287 cil_printf("(expandtypeattribute (%s) ", key); 2288 if (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE) { 2289 cil_printf("true"); 2290 } else if (type->flags & TYPE_FLAGS_EXPAND_ATTR_FALSE) { 2291 cil_printf("false"); 2292 } 2293 cil_printf(")\n"); 2294 } 2295 2296 if (ebitmap_cardinality(&type->types) > 0) { 2297 cil_indent(indent); 2298 cil_printf("(typeattributeset %s (", key); 2299 ebitmap_to_cil(pdb, &type->types, SYM_TYPES); 2300 cil_printf("))\n"); 2301 } 2302 break; 2303 case TYPE_ALIAS: 2304 break; 2305 default: 2306 log_err("Unknown flavor (%i) of type %s", type->flavor, key); 2307 rc = -1; 2308 goto exit; 2309 } 2310 2311 rc = 0; 2312 2313 exit: 2314 return rc; 2315 } 2316 2317 static int user_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) 2318 { 2319 struct user_datum *user = datum; 2320 struct ebitmap roles = user->roles.roles; 2321 struct mls_semantic_level level = user->dfltlevel; 2322 struct mls_semantic_range range = user->range; 2323 struct ebitmap_node *node; 2324 uint32_t i; 2325 int sens_offset = 1; 2326 2327 if (scope == SCOPE_DECL) { 2328 cil_println(indent, "(user %s)", key); 2329 // object_r is implicit in checkmodule, but not with CIL, create it 2330 // as part of base 2331 cil_println(indent, "(userrole %s " DEFAULT_OBJECT ")", key); 2332 } 2333 2334 ebitmap_for_each_bit(&roles, node, i) { 2335 if (!ebitmap_get_bit(&roles, i)) { 2336 continue; 2337 } 2338 cil_println(indent, "(userrole %s %s)", key, pdb->p_role_val_to_name[i]); 2339 } 2340 2341 if (block->flags & AVRULE_OPTIONAL) { 2342 // sensitivites in user statements in optionals do not have the 2343 // standard -1 offset 2344 sens_offset = 0; 2345 } 2346 2347 cil_indent(indent); 2348 cil_printf("(userlevel %s ", key); 2349 if (pdb->mls) { 2350 semantic_level_to_cil(pdb, sens_offset, &level); 2351 } else { 2352 cil_printf(DEFAULT_LEVEL); 2353 } 2354 cil_printf(")\n"); 2355 2356 cil_indent(indent); 2357 cil_printf("(userrange %s (", key); 2358 if (pdb->mls) { 2359 semantic_level_to_cil(pdb, sens_offset, &range.level[0]); 2360 cil_printf(" "); 2361 semantic_level_to_cil(pdb, sens_offset, &range.level[1]); 2362 } else { 2363 cil_printf(DEFAULT_LEVEL " " DEFAULT_LEVEL); 2364 } 2365 cil_printf("))\n"); 2366 2367 2368 return 0; 2369 } 2370 2371 static int boolean_to_cil(int indent, struct policydb *UNUSED(pdb), struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) 2372 { 2373 struct cond_bool_datum *boolean = datum; 2374 const char *type; 2375 2376 if (scope == SCOPE_DECL) { 2377 if (boolean->flags & COND_BOOL_FLAGS_TUNABLE) { 2378 type = "tunable"; 2379 } else { 2380 type = "boolean"; 2381 } 2382 2383 cil_println(indent, "(%s %s %s)", type, key, boolean->state ? "true" : "false"); 2384 } 2385 2386 return 0; 2387 } 2388 2389 static int sens_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) 2390 { 2391 struct level_datum *level = datum; 2392 2393 if (scope == SCOPE_DECL) { 2394 if (!level->isalias) { 2395 cil_println(indent, "(sensitivity %s)", key); 2396 } else { 2397 cil_println(indent, "(sensitivityalias %s)", key); 2398 cil_println(indent, "(sensitivityaliasactual %s %s)", key, pdb->p_sens_val_to_name[level->level->sens - 1]); 2399 } 2400 } 2401 2402 if (ebitmap_cardinality(&level->level->cat) > 0) { 2403 cil_indent(indent); 2404 cil_printf("(sensitivitycategory %s (", key); 2405 ebitmap_to_cil(pdb, &level->level->cat, SYM_CATS); 2406 cil_printf("))\n"); 2407 } 2408 2409 return 0; 2410 } 2411 2412 static int sens_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order) 2413 { 2414 struct ebitmap_node *node; 2415 uint32_t i; 2416 2417 if (ebitmap_cardinality(&order) == 0) { 2418 return 0; 2419 } 2420 2421 cil_indent(indent); 2422 cil_printf("(sensitivityorder ("); 2423 2424 ebitmap_for_each_bit(&order, node, i) { 2425 if (!ebitmap_get_bit(&order, i)) { 2426 continue; 2427 } 2428 cil_printf("%s ", pdb->p_sens_val_to_name[i]); 2429 } 2430 2431 cil_printf("))\n"); 2432 2433 return 0; 2434 } 2435 2436 static int cat_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope) 2437 { 2438 struct cat_datum *cat = datum; 2439 2440 if (scope == SCOPE_REQ) { 2441 return 0; 2442 } 2443 2444 if (!cat->isalias) { 2445 cil_println(indent, "(category %s)", key); 2446 } else { 2447 cil_println(indent, "(categoryalias %s)", key); 2448 cil_println(indent, "(categoryaliasactual %s %s)", key, pdb->p_cat_val_to_name[cat->s.value - 1]); 2449 } 2450 2451 return 0; 2452 } 2453 2454 static int cat_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order) 2455 { 2456 int rc = -1; 2457 struct ebitmap_node *node; 2458 uint32_t i; 2459 2460 if (ebitmap_cardinality(&order) == 0) { 2461 rc = 0; 2462 goto exit; 2463 } 2464 2465 cil_indent(indent); 2466 cil_printf("(categoryorder ("); 2467 2468 ebitmap_for_each_bit(&order, node, i) { 2469 if (!ebitmap_get_bit(&order, i)) { 2470 continue; 2471 } 2472 cil_printf("%s ", pdb->p_cat_val_to_name[i]); 2473 } 2474 2475 cil_printf("))\n"); 2476 2477 return 0; 2478 exit: 2479 return rc; 2480 } 2481 2482 static int polcaps_to_cil(struct policydb *pdb) 2483 { 2484 int rc = -1; 2485 struct ebitmap *map; 2486 struct ebitmap_node *node; 2487 uint32_t i; 2488 const char *name; 2489 2490 map = &pdb->policycaps; 2491 2492 ebitmap_for_each_bit(map, node, i) { 2493 if (!ebitmap_get_bit(map, i)) { 2494 continue; 2495 } 2496 name = sepol_polcap_getname(i); 2497 if (name == NULL) { 2498 log_err("Unknown policy capability id: %i", i); 2499 rc = -1; 2500 goto exit; 2501 } 2502 2503 cil_println(0, "(policycap %s)", name); 2504 } 2505 2506 return 0; 2507 exit: 2508 return rc; 2509 } 2510 2511 static int level_to_cil(struct policydb *pdb, struct mls_level *level) 2512 { 2513 struct ebitmap *map = &level->cat; 2514 2515 cil_printf("(%s", pdb->p_sens_val_to_name[level->sens - 1]); 2516 2517 if (ebitmap_cardinality(map) > 0) { 2518 cil_printf("("); 2519 ebitmap_to_cil(pdb, map, SYM_CATS); 2520 cil_printf(")"); 2521 } 2522 2523 cil_printf(")"); 2524 2525 return 0; 2526 } 2527 2528 static int context_to_cil(struct policydb *pdb, struct context_struct *con) 2529 { 2530 cil_printf("(%s %s %s (", 2531 pdb->p_user_val_to_name[con->user - 1], 2532 pdb->p_role_val_to_name[con->role - 1], 2533 pdb->p_type_val_to_name[con->type - 1]); 2534 2535 if (pdb->mls) { 2536 level_to_cil(pdb, &con->range.level[0]); 2537 cil_printf(" "); 2538 level_to_cil(pdb, &con->range.level[1]); 2539 } else { 2540 cil_printf(DEFAULT_LEVEL); 2541 cil_printf(" "); 2542 cil_printf(DEFAULT_LEVEL); 2543 } 2544 2545 cil_printf("))"); 2546 2547 return 0; 2548 } 2549 2550 static int ocontext_isid_to_cil(struct policydb *pdb, const char *const *sid_to_string, 2551 unsigned num_sids, struct ocontext *isids) 2552 { 2553 int rc = -1; 2554 2555 struct ocontext *isid; 2556 2557 struct sid_item { 2558 char *sid_key; 2559 struct sid_item *next; 2560 }; 2561 2562 struct sid_item *head = NULL; 2563 struct sid_item *item = NULL; 2564 char *sid; 2565 char unknown[18]; 2566 unsigned i; 2567 2568 for (isid = isids; isid != NULL; isid = isid->next) { 2569 i = isid->sid[0]; 2570 if (i < num_sids) { 2571 sid = (char*)sid_to_string[i]; 2572 } else { 2573 snprintf(unknown, 18, "%s%u", "UNKNOWN", i); 2574 sid = unknown; 2575 } 2576 cil_println(0, "(sid %s)", sid); 2577 cil_printf("(sidcontext %s ", sid); 2578 context_to_cil(pdb, &isid->context[0]); 2579 cil_printf(")\n"); 2580 2581 // get the sid names in the correct order (reverse from the isids 2582 // ocontext) for sidorder statement 2583 item = malloc(sizeof(*item)); 2584 if (item == NULL) { 2585 log_err("Out of memory"); 2586 rc = -1; 2587 goto exit; 2588 } 2589 item->sid_key = strdup(sid); 2590 item->next = head; 2591 head = item; 2592 } 2593 2594 if (head != NULL) { 2595 cil_printf("(sidorder ("); 2596 for (item = head; item != NULL; item = item->next) { 2597 cil_printf("%s ", item->sid_key); 2598 } 2599 cil_printf("))\n"); 2600 } 2601 2602 rc = 0; 2603 2604 exit: 2605 while(head) { 2606 item = head; 2607 head = item->next; 2608 free(item->sid_key); 2609 free(item); 2610 } 2611 return rc; 2612 } 2613 2614 static int ocontext_selinux_isid_to_cil(struct policydb *pdb, struct ocontext *isids) 2615 { 2616 int rc = -1; 2617 2618 rc = ocontext_isid_to_cil(pdb, selinux_sid_to_str, SELINUX_SID_SZ, isids); 2619 if (rc != 0) { 2620 goto exit; 2621 } 2622 2623 return 0; 2624 2625 exit: 2626 return rc; 2627 } 2628 2629 static int ocontext_selinux_fs_to_cil(struct policydb *UNUSED(pdb), struct ocontext *fss) 2630 { 2631 if (fss != NULL) { 2632 log_err("Warning: 'fscon' statement unsupported in CIL. Dropping from output."); 2633 } 2634 2635 return 0; 2636 } 2637 2638 static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *portcons) 2639 { 2640 int rc = -1; 2641 struct ocontext *portcon; 2642 const char *protocol; 2643 uint16_t high; 2644 uint16_t low; 2645 2646 for (portcon = portcons; portcon != NULL; portcon = portcon->next) { 2647 2648 switch (portcon->u.port.protocol) { 2649 case IPPROTO_TCP: protocol = "tcp"; break; 2650 case IPPROTO_UDP: protocol = "udp"; break; 2651 case IPPROTO_DCCP: protocol = "dccp"; break; 2652 case IPPROTO_SCTP: protocol = "sctp"; break; 2653 default: 2654 log_err("Unknown portcon protocol: %i", portcon->u.port.protocol); 2655 rc = -1; 2656 goto exit; 2657 } 2658 2659 low = portcon->u.port.low_port; 2660 high = portcon->u.port.high_port; 2661 2662 if (low == high) { 2663 cil_printf("(portcon %s %i ", protocol, low); 2664 } else { 2665 cil_printf("(portcon %s (%i %i) ", protocol, low, high); 2666 } 2667 2668 context_to_cil(pdb, &portcon->context[0]); 2669 2670 cil_printf(")\n"); 2671 } 2672 2673 return 0; 2674 exit: 2675 return rc; 2676 } 2677 2678 static int ocontext_selinux_ibpkey_to_cil(struct policydb *pdb, 2679 struct ocontext *ibpkeycons) 2680 { 2681 int rc = -1; 2682 struct ocontext *ibpkeycon; 2683 char subnet_prefix_str[INET6_ADDRSTRLEN]; 2684 struct in6_addr subnet_prefix = IN6ADDR_ANY_INIT; 2685 uint16_t high; 2686 uint16_t low; 2687 2688 for (ibpkeycon = ibpkeycons; ibpkeycon; ibpkeycon = ibpkeycon->next) { 2689 low = ibpkeycon->u.ibpkey.low_pkey; 2690 high = ibpkeycon->u.ibpkey.high_pkey; 2691 memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix, 2692 sizeof(ibpkeycon->u.ibpkey.subnet_prefix)); 2693 2694 if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, 2695 subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { 2696 log_err("ibpkeycon subnet_prefix is invalid: %s", 2697 strerror(errno)); 2698 rc = -1; 2699 goto exit; 2700 } 2701 2702 if (low == high) 2703 cil_printf("(ibpkeycon %s %i ", subnet_prefix_str, low); 2704 else 2705 cil_printf("(ibpkeycon %s (%i %i) ", subnet_prefix_str, low, 2706 high); 2707 2708 context_to_cil(pdb, &ibpkeycon->context[0]); 2709 2710 cil_printf(")\n"); 2711 } 2712 return 0; 2713 exit: 2714 return rc; 2715 } 2716 2717 static int ocontext_selinux_netif_to_cil(struct policydb *pdb, struct ocontext *netifs) 2718 { 2719 struct ocontext *netif; 2720 2721 for (netif = netifs; netif != NULL; netif = netif->next) { 2722 cil_printf("(netifcon %s ", netif->u.name); 2723 context_to_cil(pdb, &netif->context[0]); 2724 2725 cil_printf(" "); 2726 context_to_cil(pdb, &netif->context[1]); 2727 cil_printf(")\n"); 2728 } 2729 2730 return 0; 2731 } 2732 2733 static int ocontext_selinux_node_to_cil(struct policydb *pdb, struct ocontext *nodes) 2734 { 2735 int rc = -1; 2736 struct ocontext *node; 2737 char addr[INET_ADDRSTRLEN]; 2738 char mask[INET_ADDRSTRLEN]; 2739 2740 for (node = nodes; node != NULL; node = node->next) { 2741 if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) { 2742 log_err("Nodecon address is invalid: %s", strerror(errno)); 2743 rc = -1; 2744 goto exit; 2745 } 2746 2747 if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) { 2748 log_err("Nodecon mask is invalid: %s", strerror(errno)); 2749 rc = -1; 2750 goto exit; 2751 } 2752 2753 cil_printf("(nodecon (%s) (%s) ", addr, mask); 2754 2755 context_to_cil(pdb, &node->context[0]); 2756 2757 cil_printf(")\n"); 2758 } 2759 2760 return 0; 2761 exit: 2762 return rc; 2763 } 2764 2765 static int ocontext_selinux_node6_to_cil(struct policydb *pdb, struct ocontext *nodes) 2766 { 2767 int rc = -1; 2768 struct ocontext *node; 2769 char addr[INET6_ADDRSTRLEN]; 2770 char mask[INET6_ADDRSTRLEN]; 2771 2772 for (node = nodes; node != NULL; node = node->next) { 2773 if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) { 2774 log_err("Nodecon address is invalid: %s", strerror(errno)); 2775 rc = -1; 2776 goto exit; 2777 } 2778 2779 if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) { 2780 log_err("Nodecon mask is invalid: %s", strerror(errno)); 2781 rc = -1; 2782 goto exit; 2783 } 2784 2785 cil_printf("(nodecon (%s) (%s) ", addr, mask); 2786 2787 context_to_cil(pdb, &node->context[0]); 2788 2789 cil_printf(")\n"); 2790 } 2791 2792 return 0; 2793 exit: 2794 return rc; 2795 } 2796 2797 static int ocontext_selinux_ibendport_to_cil(struct policydb *pdb, struct ocontext *ibendports) 2798 { 2799 struct ocontext *ibendport; 2800 2801 for (ibendport = ibendports; ibendport; ibendport = ibendport->next) { 2802 cil_printf("(ibendportcon %s %u ", ibendport->u.ibendport.dev_name, ibendport->u.ibendport.port); 2803 context_to_cil(pdb, &ibendport->context[0]); 2804 2805 cil_printf(")\n"); 2806 } 2807 2808 return 0; 2809 } 2810 2811 static int ocontext_selinux_fsuse_to_cil(struct policydb *pdb, struct ocontext *fsuses) 2812 { 2813 int rc = -1; 2814 struct ocontext *fsuse; 2815 const char *behavior; 2816 2817 2818 for (fsuse = fsuses; fsuse != NULL; fsuse = fsuse->next) { 2819 switch (fsuse->v.behavior) { 2820 case SECURITY_FS_USE_XATTR: behavior = "xattr"; break; 2821 case SECURITY_FS_USE_TRANS: behavior = "trans"; break; 2822 case SECURITY_FS_USE_TASK: behavior = "task"; break; 2823 default: 2824 log_err("Unknown fsuse behavior: %i", fsuse->v.behavior); 2825 rc = -1; 2826 goto exit; 2827 } 2828 2829 cil_printf("(fsuse %s %s ", behavior, fsuse->u.name); 2830 2831 context_to_cil(pdb, &fsuse->context[0]); 2832 2833 cil_printf(")\n"); 2834 2835 } 2836 2837 return 0; 2838 exit: 2839 return rc; 2840 } 2841 2842 2843 static int ocontext_xen_isid_to_cil(struct policydb *pdb, struct ocontext *isids) 2844 { 2845 int rc = -1; 2846 2847 rc = ocontext_isid_to_cil(pdb, xen_sid_to_str, XEN_SID_SZ, isids); 2848 if (rc != 0) { 2849 goto exit; 2850 } 2851 2852 return 0; 2853 2854 exit: 2855 return rc; 2856 } 2857 2858 static int ocontext_xen_pirq_to_cil(struct policydb *pdb, struct ocontext *pirqs) 2859 { 2860 struct ocontext *pirq; 2861 2862 for (pirq = pirqs; pirq != NULL; pirq = pirq->next) { 2863 cil_printf("(pirqcon %i ", pirq->u.pirq); 2864 context_to_cil(pdb, &pirq->context[0]); 2865 cil_printf(")\n"); 2866 } 2867 2868 return 0; 2869 } 2870 2871 static int ocontext_xen_ioport_to_cil(struct policydb *pdb, struct ocontext *ioports) 2872 { 2873 struct ocontext *ioport; 2874 uint32_t low; 2875 uint32_t high; 2876 2877 for (ioport = ioports; ioport != NULL; ioport = ioport->next) { 2878 low = ioport->u.ioport.low_ioport; 2879 high = ioport->u.ioport.high_ioport; 2880 2881 if (low == high) { 2882 cil_printf("(ioportcon 0x%x ", low); 2883 } else { 2884 cil_printf("(ioportcon (0x%x 0x%x) ", low, high); 2885 } 2886 2887 context_to_cil(pdb, &ioport->context[0]); 2888 2889 cil_printf(")\n"); 2890 } 2891 2892 return 0; 2893 } 2894 2895 static int ocontext_xen_iomem_to_cil(struct policydb *pdb, struct ocontext *iomems) 2896 { 2897 struct ocontext *iomem; 2898 uint64_t low; 2899 uint64_t high; 2900 2901 for (iomem = iomems; iomem != NULL; iomem = iomem->next) { 2902 low = iomem->u.iomem.low_iomem; 2903 high = iomem->u.iomem.high_iomem; 2904 2905 if (low == high) { 2906 cil_printf("(iomemcon 0x%"PRIx64" ", low); 2907 } else { 2908 cil_printf("(iomemcon (0x%"PRIx64" 0x%"PRIx64") ", low, high); 2909 } 2910 2911 context_to_cil(pdb, &iomem->context[0]); 2912 2913 cil_printf(")\n"); 2914 } 2915 2916 return 0; 2917 } 2918 2919 static int ocontext_xen_pcidevice_to_cil(struct policydb *pdb, struct ocontext *pcids) 2920 { 2921 struct ocontext *pcid; 2922 2923 for (pcid = pcids; pcid != NULL; pcid = pcid->next) { 2924 cil_printf("(pcidevicecon 0x%lx ", (unsigned long)pcid->u.device); 2925 context_to_cil(pdb, &pcid->context[0]); 2926 cil_printf(")\n"); 2927 } 2928 2929 return 0; 2930 } 2931 2932 static int ocontexts_to_cil(struct policydb *pdb) 2933 { 2934 int rc = -1; 2935 int ocon; 2936 2937 static int (**ocon_funcs)(struct policydb *pdb, struct ocontext *ocon); 2938 static int (*ocon_selinux_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = { 2939 ocontext_selinux_isid_to_cil, 2940 ocontext_selinux_fs_to_cil, 2941 ocontext_selinux_port_to_cil, 2942 ocontext_selinux_netif_to_cil, 2943 ocontext_selinux_node_to_cil, 2944 ocontext_selinux_fsuse_to_cil, 2945 ocontext_selinux_node6_to_cil, 2946 ocontext_selinux_ibpkey_to_cil, 2947 ocontext_selinux_ibendport_to_cil, 2948 }; 2949 static int (*ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = { 2950 ocontext_xen_isid_to_cil, 2951 ocontext_xen_pirq_to_cil, 2952 ocontext_xen_ioport_to_cil, 2953 ocontext_xen_iomem_to_cil, 2954 ocontext_xen_pcidevice_to_cil, 2955 NULL, 2956 NULL, 2957 }; 2958 2959 switch (pdb->target_platform) { 2960 case SEPOL_TARGET_SELINUX: 2961 ocon_funcs = ocon_selinux_funcs; 2962 break; 2963 case SEPOL_TARGET_XEN: 2964 ocon_funcs = ocon_xen_funcs; 2965 break; 2966 default: 2967 log_err("Unknown target platform: %i", pdb->target_platform); 2968 rc = -1; 2969 goto exit; 2970 } 2971 2972 for (ocon = 0; ocon < OCON_NUM; ocon++) { 2973 if (ocon_funcs[ocon] != NULL) { 2974 rc = ocon_funcs[ocon](pdb, pdb->ocontexts[ocon]); 2975 if (rc != 0) { 2976 goto exit; 2977 } 2978 } 2979 } 2980 2981 return 0; 2982 exit: 2983 return rc; 2984 } 2985 2986 static int genfscon_to_cil(struct policydb *pdb) 2987 { 2988 struct genfs *genfs; 2989 struct ocontext *ocon; 2990 2991 for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) { 2992 for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) { 2993 cil_printf("(genfscon %s %s ", genfs->fstype, ocon->u.name); 2994 context_to_cil(pdb, &ocon->context[0]); 2995 cil_printf(")\n"); 2996 } 2997 } 2998 2999 return 0; 3000 } 3001 3002 static int level_string_to_cil(char *levelstr) 3003 { 3004 int rc = -1; 3005 char *sens = NULL; 3006 char *cats = NULL; 3007 int matched; 3008 char *saveptr = NULL; 3009 char *token = NULL; 3010 char *ranged = NULL; 3011 3012 matched = tokenize(levelstr, ':', 2, &sens, &cats); 3013 if (matched < 1 || matched > 2) { 3014 log_err("Invalid level: %s", levelstr); 3015 rc = -1; 3016 goto exit; 3017 } 3018 3019 cil_printf("(%s", sens); 3020 3021 if (matched == 2) { 3022 cil_printf("("); 3023 token = strtok_r(cats, ",", &saveptr); 3024 while (token != NULL) { 3025 ranged = strchr(token, '.'); 3026 if (ranged == NULL) { 3027 cil_printf("%s ", token); 3028 } else { 3029 *ranged = '\0'; 3030 cil_printf("(range %s %s) ", token, ranged + 1); 3031 } 3032 token = strtok_r(NULL, ",", &saveptr); 3033 } 3034 cil_printf(")"); 3035 } 3036 3037 cil_printf(")"); 3038 3039 rc = 0; 3040 exit: 3041 free(sens); 3042 free(cats); 3043 return rc; 3044 } 3045 3046 static int level_range_string_to_cil(char *levelrangestr) 3047 { 3048 char *ranged = NULL; 3049 char *low; 3050 char *high; 3051 3052 ranged = strchr(levelrangestr, '-'); 3053 if (ranged == NULL) { 3054 low = high = levelrangestr; 3055 } else { 3056 *ranged = '\0'; 3057 low = levelrangestr; 3058 high = ranged + 1; 3059 } 3060 3061 level_string_to_cil(low); 3062 cil_printf(" "); 3063 level_string_to_cil(high); 3064 3065 return 0; 3066 } 3067 3068 static int context_string_to_cil(char *contextstr) 3069 { 3070 int rc = -1; 3071 int matched; 3072 char *user = NULL; 3073 char *role = NULL; 3074 char *type = NULL; 3075 char *level = NULL; 3076 3077 matched = tokenize(contextstr, ':', 4, &user, &role, &type, &level); 3078 if (matched < 3 || matched > 4) { 3079 log_err("Invalid context: %s", contextstr); 3080 rc = -1; 3081 goto exit; 3082 } 3083 3084 cil_printf("(%s %s %s (", user, role, type); 3085 3086 if (matched == 3) { 3087 cil_printf(DEFAULT_LEVEL); 3088 cil_printf(" "); 3089 cil_printf(DEFAULT_LEVEL); 3090 } else { 3091 level_range_string_to_cil(level); 3092 } 3093 3094 cil_printf("))"); 3095 3096 rc = 0; 3097 3098 exit: 3099 free(user); 3100 free(role); 3101 free(type); 3102 free(level); 3103 3104 return rc; 3105 } 3106 3107 static int seusers_to_cil(struct sepol_module_package *mod_pkg) 3108 { 3109 int rc = -1; 3110 char *seusers = sepol_module_package_get_seusers(mod_pkg); 3111 size_t seusers_len = sepol_module_package_get_seusers_len(mod_pkg); 3112 char *cur = seusers; 3113 char *end = seusers + seusers_len; 3114 char *line = NULL; 3115 char *user = NULL; 3116 char *seuser = NULL; 3117 char *level = NULL; 3118 char *tmp = NULL; 3119 int matched; 3120 3121 if (seusers_len == 0) { 3122 return 0; 3123 } 3124 3125 while ((rc = get_line(&cur, end, &line)) > 0) { 3126 tmp = line; 3127 while (isspace(*tmp)) { 3128 tmp++; 3129 } 3130 3131 if (tmp[0] == '#' || tmp[0] == '\0') { 3132 free(line); 3133 line = NULL; 3134 continue; 3135 } 3136 3137 matched = tokenize(tmp, ':', 3, &user, &seuser, &level); 3138 3139 if (matched < 2 || matched > 3) { 3140 log_err("Invalid seuser line: %s", line); 3141 rc = -1; 3142 goto exit; 3143 } 3144 3145 if (!strcmp(user, "__default__")) { 3146 cil_printf("(selinuxuserdefault %s (", seuser); 3147 } else { 3148 cil_printf("(selinuxuser %s %s (", user, seuser); 3149 } 3150 3151 switch (matched) { 3152 case 2: 3153 cil_printf("systemlow systemlow"); 3154 break; 3155 case 3: 3156 level_range_string_to_cil(level); 3157 break; 3158 } 3159 3160 cil_printf("))\n"); 3161 3162 free(user); 3163 free(seuser); 3164 free(level); 3165 free(line); 3166 user = seuser = level = NULL; 3167 } 3168 3169 if (rc == -1) { 3170 cil_printf("Failed to read seusers\n"); 3171 goto exit; 3172 } 3173 3174 rc = 0; 3175 exit: 3176 free(line); 3177 free(user); 3178 free(seuser); 3179 free(level); 3180 3181 return rc; 3182 } 3183 3184 static int netfilter_contexts_to_cil(struct sepol_module_package *mod_pkg) 3185 { 3186 size_t netcons_len = sepol_module_package_get_netfilter_contexts_len(mod_pkg); 3187 3188 if (netcons_len > 0) { 3189 log_err("Warning: netfilter_contexts are unsupported in CIL. Dropping from output."); 3190 } 3191 3192 return 0; 3193 } 3194 3195 static int user_extra_to_cil(struct sepol_module_package *mod_pkg) 3196 { 3197 int rc = -1; 3198 char *userx = sepol_module_package_get_user_extra(mod_pkg); 3199 size_t userx_len = sepol_module_package_get_user_extra_len(mod_pkg); 3200 char *cur = userx; 3201 char *end = userx + userx_len; 3202 char *line; 3203 int matched; 3204 char *user = NULL; 3205 char *prefix = NULL; 3206 int prefix_len = 0; 3207 char *user_str = NULL; 3208 char *prefix_str = NULL; 3209 char *eol = NULL; 3210 char *tmp = NULL; 3211 3212 if (userx_len == 0) { 3213 return 0; 3214 } 3215 3216 while ((rc = get_line(&cur, end, &line)) > 0) { 3217 tmp = line; 3218 while (isspace(*tmp)) { 3219 tmp++; 3220 } 3221 3222 if (tmp[0] == '#' || tmp[0] == '\0') { 3223 free(line); 3224 line = NULL; 3225 continue; 3226 } 3227 3228 matched = tokenize(tmp, ' ', 4, &user_str, &user, &prefix_str, &prefix); 3229 if (matched != 4) { 3230 rc = -1; 3231 log_err("Invalid user extra line: %s", line); 3232 goto exit; 3233 } 3234 3235 prefix_len = strlen(prefix); 3236 eol = prefix + prefix_len - 1; 3237 if (*eol != ';' || strcmp(user_str, "user") || strcmp(prefix_str, "prefix")) { 3238 rc = -1; 3239 log_err("Invalid user extra line: %s", line); 3240 goto exit; 3241 } 3242 *eol = '\0'; 3243 3244 cil_println(0, "(userprefix %s %s)", user, prefix); 3245 free(user); 3246 free(prefix); 3247 free(line); 3248 free(user_str); 3249 free(prefix_str); 3250 user = prefix = line = user_str = prefix_str = NULL; 3251 } 3252 3253 if (rc == -1) { 3254 cil_printf("Failed to read user_extra\n"); 3255 goto exit; 3256 } 3257 3258 rc = 0; 3259 exit: 3260 free(line); 3261 free(user); 3262 free(prefix); 3263 3264 return rc; 3265 } 3266 3267 static int file_contexts_to_cil(struct sepol_module_package *mod_pkg) 3268 { 3269 int rc = -1; 3270 char *fc = sepol_module_package_get_file_contexts(mod_pkg); 3271 size_t fc_len = sepol_module_package_get_file_contexts_len(mod_pkg); 3272 char *cur = fc; 3273 char *end = fc + fc_len; 3274 char *line = NULL; 3275 int matched; 3276 char *regex = NULL; 3277 char *mode = NULL; 3278 char *context = NULL; 3279 const char *cilmode; 3280 char *tmp = NULL; 3281 3282 if (fc_len == 0) { 3283 return 0; 3284 } 3285 3286 while ((rc = get_line(&cur, end, &line)) > 0) { 3287 tmp = line; 3288 while (isspace(*tmp)) { 3289 tmp++; 3290 } 3291 3292 if (tmp[0] == '#' || tmp[0] == '\0') { 3293 free(line); 3294 line = NULL; 3295 continue; 3296 } 3297 3298 matched = tokenize(tmp, ' ', 3, ®ex, &mode, &context); 3299 if (matched < 2 || matched > 3) { 3300 rc = -1; 3301 log_err("Invalid file context line: %s", line); 3302 goto exit; 3303 } 3304 3305 if (matched == 2) { 3306 context = mode; 3307 mode = NULL; 3308 } 3309 3310 if (mode == NULL) { 3311 cilmode = "any"; 3312 } else if (!strcmp(mode, "--")) { 3313 cilmode = "file"; 3314 } else if (!strcmp(mode, "-d")) { 3315 cilmode = "dir"; 3316 } else if (!strcmp(mode, "-c")) { 3317 cilmode = "char"; 3318 } else if (!strcmp(mode, "-b")) { 3319 cilmode = "block"; 3320 } else if (!strcmp(mode, "-s")) { 3321 cilmode = "socket"; 3322 } else if (!strcmp(mode, "-p")) { 3323 cilmode = "pipe"; 3324 } else if (!strcmp(mode, "-l")) { 3325 cilmode = "symlink"; 3326 } else { 3327 rc = -1; 3328 log_err("Invalid mode in file context line: %s", line); 3329 goto exit; 3330 } 3331 3332 cil_printf("(filecon \"%s\" %s ", regex, cilmode); 3333 3334 if (!strcmp(context, "<<none>>")) { 3335 cil_printf("()"); 3336 } else { 3337 context_string_to_cil(context); 3338 } 3339 3340 cil_printf(")\n"); 3341 3342 free(regex); 3343 free(mode); 3344 free(context); 3345 free(line); 3346 regex = mode = context = line = NULL; 3347 } 3348 3349 if (rc == -1) { 3350 cil_printf("Failed to read file_contexts_to_cil\n"); 3351 goto exit; 3352 } 3353 3354 rc = 0; 3355 exit: 3356 free(line); 3357 free(regex); 3358 free(mode); 3359 free(context); 3360 3361 return rc; 3362 } 3363 3364 3365 static int (*func_to_cil[SYM_NUM])(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack, char *key, void *datum, int scope) = { 3366 NULL, // commons, only stored in the global symtab, handled elsewhere 3367 class_to_cil, 3368 role_to_cil, 3369 type_to_cil, 3370 user_to_cil, 3371 boolean_to_cil, 3372 sens_to_cil, 3373 cat_to_cil 3374 }; 3375 3376 static int typealiases_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack) 3377 { 3378 struct type_datum *alias_datum; 3379 char *alias_name; 3380 char *type_name; 3381 struct list_node *curr; 3382 struct avrule_decl *decl = stack_peek(decl_stack); 3383 struct list *alias_list = typealias_lists[decl->decl_id]; 3384 int rc = -1; 3385 3386 if (alias_list == NULL) { 3387 return 0; 3388 } 3389 3390 for (curr = alias_list->head; curr != NULL; curr = curr->next) { 3391 alias_name = curr->data; 3392 alias_datum = hashtab_search(pdb->p_types.table, alias_name); 3393 if (alias_datum == NULL) { 3394 rc = -1; 3395 goto exit; 3396 } 3397 if (alias_datum->flavor == TYPE_ALIAS) { 3398 type_name = pdb->p_type_val_to_name[alias_datum->primary - 1]; 3399 } else { 3400 type_name = pdb->p_type_val_to_name[alias_datum->s.value - 1]; 3401 } 3402 cil_println(indent, "(typealias %s)", alias_name); 3403 cil_println(indent, "(typealiasactual %s %s)", alias_name, type_name); 3404 } 3405 3406 return 0; 3407 3408 exit: 3409 return rc; 3410 } 3411 3412 static int declared_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack) 3413 { 3414 int rc = -1; 3415 struct ebitmap map; 3416 struct ebitmap_node *node; 3417 unsigned int i; 3418 char * key; 3419 struct scope_datum *scope; 3420 int sym; 3421 void *datum; 3422 struct avrule_decl *decl = stack_peek(decl_stack); 3423 3424 for (sym = 0; sym < SYM_NUM; sym++) { 3425 if (func_to_cil[sym] == NULL) { 3426 continue; 3427 } 3428 3429 map = decl->declared.scope[sym]; 3430 ebitmap_for_each_bit(&map, node, i) { 3431 if (!ebitmap_get_bit(&map, i)) { 3432 continue; 3433 } 3434 key = pdb->sym_val_to_name[sym][i]; 3435 datum = hashtab_search(pdb->symtab[sym].table, key); 3436 if (datum == NULL) { 3437 rc = -1; 3438 goto exit; 3439 } 3440 scope = hashtab_search(pdb->scope[sym].table, key); 3441 if (scope == NULL) { 3442 rc = -1; 3443 goto exit; 3444 } 3445 rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, scope->scope); 3446 if (rc != 0) { 3447 goto exit; 3448 } 3449 } 3450 3451 if (sym == SYM_CATS) { 3452 rc = cat_order_to_cil(indent, pdb, map); 3453 if (rc != 0) { 3454 goto exit; 3455 } 3456 } 3457 3458 if (sym == SYM_LEVELS) { 3459 rc = sens_order_to_cil(indent, pdb, map); 3460 if (rc != 0) { 3461 goto exit; 3462 } 3463 } 3464 3465 if (sym == SYM_CLASSES) { 3466 rc = class_order_to_cil(indent, pdb, map); 3467 if (rc != 0) { 3468 goto exit; 3469 } 3470 } 3471 } 3472 3473 return 0; 3474 exit: 3475 return rc; 3476 } 3477 3478 static int required_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack) 3479 { 3480 int rc = -1; 3481 struct ebitmap map; 3482 struct ebitmap_node *node; 3483 unsigned int i; 3484 unsigned int j; 3485 char * key; 3486 int sym; 3487 void *datum; 3488 struct avrule_decl *decl = stack_peek(decl_stack); 3489 struct scope_datum *scope_datum; 3490 3491 for (sym = 0; sym < SYM_NUM; sym++) { 3492 if (func_to_cil[sym] == NULL) { 3493 continue; 3494 } 3495 3496 map = decl->required.scope[sym]; 3497 ebitmap_for_each_bit(&map, node, i) { 3498 if (!ebitmap_get_bit(&map, i)) { 3499 continue; 3500 } 3501 key = pdb->sym_val_to_name[sym][i]; 3502 3503 scope_datum = hashtab_search(pdb->scope[sym].table, key); 3504 if (scope_datum == NULL) { 3505 rc = -1; 3506 goto exit; 3507 } 3508 for (j = 0; j < scope_datum->decl_ids_len; j++) { 3509 if (scope_datum->decl_ids[j] == decl->decl_id) { 3510 break; 3511 } 3512 } 3513 if (j >= scope_datum->decl_ids_len) { 3514 // Symbols required in the global scope are also in the 3515 // required scope ebitmap of all avrule decls (i.e. required 3516 // in all optionals). So we need to look at the scopes of each 3517 // symbol in this avrule_decl to determine if it actually is 3518 // required in this decl, or if it's just required in the 3519 // global scope. If we got here, then this symbol is not 3520 // actually required in this scope, so skip it. 3521 continue; 3522 } 3523 3524 datum = hashtab_search(pdb->symtab[sym].table, key); 3525 if (datum == NULL) { 3526 rc = -1; 3527 goto exit; 3528 } 3529 rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, SCOPE_REQ); 3530 if (rc != 0) { 3531 goto exit; 3532 } 3533 } 3534 } 3535 3536 return 0; 3537 exit: 3538 return rc; 3539 } 3540 3541 3542 static int additive_scopes_to_cil_map(char *key, void *data, void *arg) 3543 { 3544 int rc = -1; 3545 struct map_args *args = arg; 3546 3547 rc = func_to_cil[args->sym_index](args->indent, args->pdb, args->block, args->decl_stack, key, data, SCOPE_REQ); 3548 if (rc != 0) { 3549 goto exit; 3550 } 3551 3552 return 0; 3553 3554 exit: 3555 return rc; 3556 } 3557 3558 static int additive_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack) 3559 { 3560 int rc = -1; 3561 struct map_args args; 3562 args.pdb = pdb; 3563 args.block = block; 3564 args.decl_stack = decl_stack; 3565 args.indent = indent; 3566 struct avrule_decl *decl = stack_peek(decl_stack); 3567 3568 for (args.sym_index = 0; args.sym_index < SYM_NUM; args.sym_index++) { 3569 if (func_to_cil[args.sym_index] == NULL) { 3570 continue; 3571 } 3572 rc = hashtab_map(decl->symtab[args.sym_index].table, additive_scopes_to_cil_map, &args); 3573 if (rc != 0) { 3574 goto exit; 3575 } 3576 } 3577 3578 return 0; 3579 3580 exit: 3581 return rc; 3582 } 3583 3584 static int is_scope_superset(struct scope_index *sup, struct scope_index *sub) 3585 { 3586 // returns 1 if sup is a superset of sub, returns 0 otherwise 3587 3588 int rc = 0; 3589 3590 uint32_t i; 3591 struct ebitmap sup_map; 3592 struct ebitmap sub_map; 3593 struct ebitmap res; 3594 3595 ebitmap_init(&res); 3596 3597 for (i = 0; i < SYM_NUM; i++) { 3598 sup_map = sup->scope[i]; 3599 sub_map = sub->scope[i]; 3600 3601 ebitmap_and(&res, &sup_map, &sub_map); 3602 if (!ebitmap_cmp(&res, &sub_map)) { 3603 goto exit; 3604 } 3605 ebitmap_destroy(&res); 3606 } 3607 3608 if (sup->class_perms_len < sub->class_perms_len) { 3609 goto exit; 3610 } 3611 3612 for (i = 0; i < sub->class_perms_len; i++) { 3613 sup_map = sup->class_perms_map[i]; 3614 sub_map = sub->class_perms_map[i]; 3615 3616 ebitmap_and(&res, &sup_map, &sub_map); 3617 if (!ebitmap_cmp(&res, &sub_map)) { 3618 goto exit; 3619 } 3620 ebitmap_destroy(&res); 3621 } 3622 3623 rc = 1; 3624 3625 exit: 3626 3627 ebitmap_destroy(&res); 3628 return rc; 3629 } 3630 3631 static int block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int indent) 3632 { 3633 int rc = -1; 3634 struct avrule_decl *decl; 3635 struct list *type_attr_list = NULL; 3636 struct list *role_attr_list = NULL; 3637 3638 decl = block->branch_list; 3639 3640 rc = list_init(&type_attr_list); 3641 if (rc != 0) { 3642 goto exit; 3643 } 3644 rc = list_init(&role_attr_list); 3645 if (rc != 0) { 3646 goto exit; 3647 } 3648 3649 rc = typealiases_to_cil(indent, pdb, block, stack); 3650 if (rc != 0) { 3651 goto exit; 3652 } 3653 3654 rc = declared_scopes_to_cil(indent, pdb, block, stack); 3655 if (rc != 0) { 3656 goto exit; 3657 } 3658 3659 rc = required_scopes_to_cil(indent, pdb, block, stack); 3660 if (rc != 0) { 3661 goto exit; 3662 } 3663 3664 rc = additive_scopes_to_cil(indent, pdb, block, stack); 3665 if (rc != 0) { 3666 goto exit; 3667 } 3668 3669 rc = avrule_list_to_cil(indent, pdb, decl->avrules, type_attr_list); 3670 if (rc != 0) { 3671 goto exit; 3672 } 3673 3674 rc = role_trans_to_cil(indent, pdb, decl->role_tr_rules, role_attr_list, type_attr_list); 3675 if (rc != 0) { 3676 goto exit; 3677 } 3678 3679 rc = role_allows_to_cil(indent, pdb, decl->role_allow_rules, role_attr_list); 3680 if (rc != 0) { 3681 goto exit; 3682 } 3683 3684 rc = range_trans_to_cil(indent, pdb, decl->range_tr_rules, type_attr_list); 3685 if (rc != 0) { 3686 goto exit; 3687 } 3688 3689 rc = filename_trans_to_cil(indent, pdb, decl->filename_trans_rules, type_attr_list); 3690 if (rc != 0) { 3691 goto exit; 3692 } 3693 3694 rc = cond_list_to_cil(indent, pdb, decl->cond_list, type_attr_list); 3695 if (rc != 0) { 3696 goto exit; 3697 } 3698 3699 rc = cil_print_attr_list(indent, pdb, type_attr_list); 3700 if (rc != 0) { 3701 goto exit; 3702 } 3703 rc = cil_print_attr_list(indent, pdb, role_attr_list); 3704 if (rc != 0) { 3705 goto exit; 3706 } 3707 3708 exit: 3709 attr_list_destroy(&type_attr_list); 3710 attr_list_destroy(&role_attr_list); 3711 3712 return rc; 3713 } 3714 3715 static int module_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int *indent) 3716 { 3717 int rc = 0; 3718 struct avrule_decl *decl; 3719 struct avrule_decl *decl_tmp; 3720 3721 decl = block->branch_list; 3722 if (decl == NULL) { 3723 goto exit; 3724 } 3725 3726 if (decl->next != NULL) { 3727 log_err("Warning: 'else' blocks in optional statements are unsupported in CIL. Dropping from output."); 3728 } 3729 3730 if (block->flags & AVRULE_OPTIONAL) { 3731 while (stack->pos > 0) { 3732 decl_tmp = stack_peek(stack); 3733 if (is_scope_superset(&decl->required, &decl_tmp->required)) { 3734 break; 3735 } 3736 3737 stack_pop(stack); 3738 (*indent)--; 3739 cil_println(*indent, ")"); 3740 } 3741 3742 cil_println(*indent, "(optional %s_optional_%i", pdb->name, decl->decl_id); 3743 (*indent)++; 3744 } 3745 3746 stack_push(stack, decl); 3747 3748 rc = block_to_cil(pdb, block, stack, *indent); 3749 if (rc != 0) { 3750 goto exit; 3751 } 3752 3753 exit: 3754 return rc; 3755 } 3756 3757 static int global_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack) 3758 { 3759 int rc = 0; 3760 struct avrule_decl *decl; 3761 3762 decl = block->branch_list; 3763 if (decl == NULL) { 3764 goto exit; 3765 } 3766 3767 if (decl->next != NULL) { 3768 log_err("Warning: 'else' not allowed in global block. Dropping from output."); 3769 } 3770 3771 stack_push(stack, decl); 3772 3773 // type aliases and commons are only stored in the global symtab. 3774 // However, to get scoping correct, we assume they are in the 3775 // global block 3776 rc = hashtab_map(pdb->p_commons.table, common_to_cil, NULL); 3777 if (rc != 0) { 3778 goto exit; 3779 } 3780 3781 rc = block_to_cil(pdb, block, stack, 0); 3782 if (rc != 0) { 3783 goto exit; 3784 } 3785 3786 exit: 3787 return rc; 3788 } 3789 3790 static int blocks_to_cil(struct policydb *pdb) 3791 { 3792 int rc = -1; 3793 struct avrule_block *block; 3794 int indent = 0; 3795 struct stack *stack = NULL; 3796 3797 rc = stack_init(&stack); 3798 if (rc != 0) { 3799 goto exit; 3800 } 3801 3802 block = pdb->global; 3803 rc = global_block_to_cil(pdb, block, stack); 3804 if (rc != 0) { 3805 goto exit; 3806 } 3807 3808 for (block = block->next; block != NULL; block = block->next) { 3809 rc = module_block_to_cil(pdb, block, stack, &indent); 3810 if (rc != 0) { 3811 goto exit; 3812 } 3813 } 3814 3815 while (indent > 0) { 3816 indent--; 3817 cil_println(indent, ")"); 3818 } 3819 3820 exit: 3821 stack_destroy(&stack); 3822 3823 return rc; 3824 } 3825 3826 static int linked_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack) 3827 { 3828 int rc = 0; 3829 struct avrule_decl *decl; 3830 3831 decl = block->branch_list; 3832 if (decl == NULL) { 3833 goto exit; 3834 } 3835 3836 if (!decl->enabled) { 3837 if (decl->next != NULL) { 3838 decl = decl->next; 3839 } else { 3840 goto exit; 3841 } 3842 } 3843 3844 stack_push(stack, decl); 3845 3846 rc = block_to_cil(pdb, block, stack, 0); 3847 if (rc != 0) { 3848 goto exit; 3849 } 3850 3851 stack_pop(stack); 3852 3853 exit: 3854 return rc; 3855 } 3856 3857 static int linked_blocks_to_cil(struct policydb *pdb) 3858 { 3859 // Convert base module that has been linked to CIL 3860 // Since it is linked, all optional blocks have been resolved 3861 int rc = -1; 3862 struct avrule_block *block; 3863 struct stack *stack = NULL; 3864 3865 rc = stack_init(&stack); 3866 if (rc != 0) { 3867 goto exit; 3868 } 3869 3870 block = pdb->global; 3871 rc = global_block_to_cil(pdb, block, stack); 3872 if (rc != 0) { 3873 goto exit; 3874 } 3875 3876 for (block = block->next; block != NULL; block = block->next) { 3877 rc = linked_block_to_cil(pdb, block, stack); 3878 if (rc != 0) { 3879 goto exit; 3880 } 3881 } 3882 3883 exit: 3884 stack_destroy(&stack); 3885 3886 return rc; 3887 } 3888 3889 static int handle_unknown_to_cil(struct policydb *pdb) 3890 { 3891 int rc = -1; 3892 const char *hu; 3893 3894 switch (pdb->handle_unknown) { 3895 case SEPOL_DENY_UNKNOWN: 3896 hu = "deny"; 3897 break; 3898 case SEPOL_REJECT_UNKNOWN: 3899 hu = "reject"; 3900 break; 3901 case SEPOL_ALLOW_UNKNOWN: 3902 hu = "allow"; 3903 break; 3904 default: 3905 log_err("Unknown value for handle-unknown: %i", pdb->handle_unknown); 3906 rc = -1; 3907 goto exit; 3908 } 3909 3910 cil_println(0, "(handleunknown %s)", hu); 3911 3912 return 0; 3913 3914 exit: 3915 return rc; 3916 } 3917 3918 static int generate_mls(struct policydb *pdb) 3919 { 3920 const char *mls_str = pdb->mls ? "true" : "false"; 3921 cil_println(0, "(mls %s)", mls_str); 3922 3923 return 0; 3924 } 3925 3926 static int generate_default_level(void) 3927 { 3928 cil_println(0, "(sensitivity s0)"); 3929 cil_println(0, "(sensitivityorder (s0))"); 3930 cil_println(0, "(level " DEFAULT_LEVEL " (s0))"); 3931 3932 return 0; 3933 } 3934 3935 static int generate_default_object(void) 3936 { 3937 cil_println(0, "(role " DEFAULT_OBJECT ")"); 3938 3939 return 0; 3940 } 3941 3942 static int generate_builtin_roles(void) 3943 { 3944 // due to inconsistentencies between policies and CIL not allowing 3945 // duplicate roles, some roles are always created, regardless of if they 3946 // are declared in modules or not 3947 cil_println(0, "(role auditadm_r)"); 3948 cil_println(0, "(role secadm_r)"); 3949 3950 return 0; 3951 } 3952 3953 static int generate_gen_require_attribute(void) 3954 { 3955 cil_println(0, "(typeattribute " GEN_REQUIRE_ATTR ")"); 3956 cil_println(0, "(roleattribute " GEN_REQUIRE_ATTR ")"); 3957 3958 return 0; 3959 } 3960 3961 static int fix_module_name(struct policydb *pdb) 3962 { 3963 char *letter; 3964 int rc = -1; 3965 3966 // The base module doesn't have its name set, but we use that for some 3967 // autogenerated names, like optionals and attributes, to prevent naming 3968 // collisions. However, they sometimes need to be fixed up. 3969 3970 // the base module isn't given a name, so just call it "base" 3971 if (pdb->policy_type == POLICY_BASE) { 3972 pdb->name = strdup("base"); 3973 if (pdb->name == NULL) { 3974 log_err("Out of memory"); 3975 rc = -1; 3976 goto exit; 3977 } 3978 } 3979 3980 // CIL is more restrictive in module names than checkmodule. Convert bad 3981 // characters to underscores 3982 for (letter = pdb->name; *letter != '\0'; letter++) { 3983 if (isalnum(*letter)) { 3984 continue; 3985 } 3986 3987 *letter = '_'; 3988 } 3989 3990 return 0; 3991 exit: 3992 return rc; 3993 } 3994 3995 int sepol_module_policydb_to_cil(FILE *fp, struct policydb *pdb, int linked) 3996 { 3997 int rc = -1; 3998 3999 out_file = fp; 4000 4001 if (pdb == NULL) { 4002 rc = 0; 4003 goto exit; 4004 } 4005 4006 if (pdb->policy_type != SEPOL_POLICY_BASE && 4007 pdb->policy_type != SEPOL_POLICY_MOD) { 4008 log_err("Policy pakcage is not a base or module"); 4009 rc = -1; 4010 goto exit; 4011 } 4012 4013 rc = fix_module_name(pdb); 4014 if (rc != 0) { 4015 goto exit; 4016 } 4017 4018 if (pdb->policy_type == SEPOL_POLICY_BASE && !pdb->mls) { 4019 // If this is a base non-mls policy, we need to define a default level 4020 // range that can be used for contexts by other non-mls modules, since 4021 // CIL requires that all contexts have a range, even if they are 4022 // ignored as in non-mls policies 4023 rc = generate_default_level(); 4024 if (rc != 0) { 4025 goto exit; 4026 } 4027 } 4028 4029 if (pdb->policy_type == SEPOL_POLICY_BASE) { 4030 // object_r is implicit in checkmodule, but not with CIL, create it 4031 // as part of base 4032 rc = generate_default_object(); 4033 if (rc != 0) { 4034 goto exit; 4035 } 4036 4037 rc = generate_builtin_roles(); 4038 if (rc != 0) { 4039 goto exit; 4040 } 4041 4042 // default attribute to be used to mimic gen_require in CIL 4043 rc = generate_gen_require_attribute(); 4044 if (rc != 0) { 4045 goto exit; 4046 } 4047 4048 // handle_unknown is used from only the base module 4049 rc = handle_unknown_to_cil(pdb); 4050 if (rc != 0) { 4051 goto exit; 4052 } 4053 4054 // mls is used from only the base module 4055 rc = generate_mls(pdb); 4056 if (rc != 0) { 4057 goto exit; 4058 } 4059 } 4060 4061 rc = role_list_create(pdb->p_roles.table); 4062 if (rc != 0) { 4063 goto exit; 4064 } 4065 4066 rc = typealias_list_create(pdb); 4067 if (rc != 0) { 4068 goto exit; 4069 } 4070 4071 rc = polcaps_to_cil(pdb); 4072 if (rc != 0) { 4073 goto exit; 4074 } 4075 4076 rc = ocontexts_to_cil(pdb); 4077 if (rc != 0) { 4078 goto exit; 4079 } 4080 4081 rc = genfscon_to_cil(pdb); 4082 if (rc != 0) { 4083 goto exit; 4084 } 4085 4086 // now print everything that is scoped 4087 if (linked) { 4088 rc = linked_blocks_to_cil(pdb); 4089 } else { 4090 rc = blocks_to_cil(pdb); 4091 } 4092 if (rc != 0) { 4093 goto exit; 4094 } 4095 4096 rc = 0; 4097 4098 exit: 4099 role_list_destroy(); 4100 typealias_list_destroy(); 4101 4102 return rc; 4103 } 4104 4105 int sepol_module_package_to_cil(FILE *fp, struct sepol_module_package *mod_pkg) 4106 { 4107 int rc = -1; 4108 struct sepol_policydb *pdb; 4109 4110 out_file = fp; 4111 4112 pdb = sepol_module_package_get_policy(mod_pkg); 4113 if (pdb == NULL) { 4114 log_err("Failed to get policydb"); 4115 rc = -1; 4116 goto exit; 4117 } 4118 4119 rc = sepol_module_policydb_to_cil(fp, &pdb->p, 0); 4120 if (rc != 0) { 4121 goto exit; 4122 } 4123 4124 rc = seusers_to_cil(mod_pkg); 4125 if (rc != 0) { 4126 goto exit; 4127 } 4128 4129 rc = netfilter_contexts_to_cil(mod_pkg); 4130 if (rc != 0) { 4131 goto exit; 4132 } 4133 4134 rc = user_extra_to_cil(mod_pkg); 4135 if (rc != 0) { 4136 goto exit; 4137 } 4138 4139 rc = file_contexts_to_cil(mod_pkg); 4140 if (rc != 0) { 4141 goto exit; 4142 } 4143 4144 rc = 0; 4145 4146 exit: 4147 return rc; 4148 } 4149 4150 static int fp_to_buffer(FILE *fp, char **data, size_t *data_len) 4151 { 4152 int rc = -1; 4153 char *d = NULL; 4154 size_t d_len = 0; 4155 size_t read_len = 0; 4156 size_t max_len = 1 << 17; // start at 128KB, this is enough to hold about half of all the existing pp files 4157 4158 d = malloc(max_len); 4159 if (d == NULL) { 4160 log_err("Out of memory"); 4161 rc = -1; 4162 goto exit; 4163 } 4164 4165 while ((read_len = fread(d + d_len, 1, max_len - d_len, fp)) > 0) { 4166 d_len += read_len; 4167 if (d_len == max_len) { 4168 max_len *= 2; 4169 d = realloc(d, max_len); 4170 if (d == NULL) { 4171 log_err("Out of memory"); 4172 rc = -1; 4173 goto exit; 4174 } 4175 } 4176 } 4177 4178 if (ferror(fp) != 0) { 4179 log_err("Failed to read pp file"); 4180 rc = -1; 4181 goto exit; 4182 } 4183 4184 *data = d; 4185 *data_len = d_len; 4186 4187 return 0; 4188 4189 exit: 4190 free(d); 4191 return rc; 4192 } 4193 4194 int sepol_ppfile_to_module_package(FILE *fp, struct sepol_module_package **mod_pkg) 4195 { 4196 int rc = -1; 4197 struct sepol_policy_file *pf = NULL; 4198 struct sepol_module_package *pkg = NULL; 4199 char *data = NULL; 4200 size_t data_len; 4201 int fd; 4202 struct stat sb; 4203 4204 rc = sepol_policy_file_create(&pf); 4205 if (rc != 0) { 4206 log_err("Failed to create policy file"); 4207 goto exit; 4208 } 4209 4210 fd = fileno(fp); 4211 if (fstat(fd, &sb) == -1) { 4212 rc = -1; 4213 goto exit; 4214 } 4215 4216 if (S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode)) { 4217 // libsepol fails when trying to read a policy package from a pipe or a 4218 // socket due its use of lseek. In this case, read the data into a 4219 // buffer and provide that to libsepol 4220 rc = fp_to_buffer(fp, &data, &data_len); 4221 if (rc != 0) { 4222 goto exit; 4223 } 4224 4225 sepol_policy_file_set_mem(pf, data, data_len); 4226 } else { 4227 sepol_policy_file_set_fp(pf, fp); 4228 } 4229 4230 rc = sepol_module_package_create(&pkg); 4231 if (rc != 0) { 4232 log_err("Failed to create module package"); 4233 goto exit; 4234 } 4235 4236 rc = sepol_module_package_read(pkg, pf, 0); 4237 if (rc != 0) { 4238 log_err("Failed to read policy package"); 4239 goto exit; 4240 } 4241 4242 *mod_pkg = pkg; 4243 4244 exit: 4245 free(data); 4246 4247 sepol_policy_file_free(pf); 4248 4249 if (rc != 0) { 4250 sepol_module_package_free(pkg); 4251 } 4252 4253 return rc; 4254 } 4255