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