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