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