1 2 /* Authors: Frank Mayer <mayerf (at) tresys.com> and Karl MacMillan <kmacmillan (at) tresys.com> 3 * 4 * Copyright (C) 2003,2004,2005 Tresys Technology, LLC 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, version 2. 8 */ 9 10 /* 11 * dismod.c 12 * 13 * Test program to the contents of a binary policy in text 14 * form. 15 * 16 * dismod binary_mod_file 17 */ 18 19 #include <getopt.h> 20 #include <assert.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 #include <sys/mman.h> 24 #include <errno.h> 25 #include <stdio.h> 26 #include <fcntl.h> 27 #include <stdlib.h> 28 #include <unistd.h> 29 30 #include <sepol/policydb/policydb.h> 31 #include <sepol/policydb/services.h> 32 #include <sepol/policydb/conditional.h> 33 #include <sepol/policydb/flask.h> 34 #include <sepol/policydb/link.h> 35 #include <sepol/policydb/module.h> 36 #include <sepol/policydb/util.h> 37 #include <sepol/policydb/polcaps.h> 38 39 #include <byteswap.h> 40 #include <endian.h> 41 42 #if __BYTE_ORDER == __LITTLE_ENDIAN 43 #define le32_to_cpu(x) (x) 44 #else 45 #define le32_to_cpu(x) bswap_32(x) 46 #endif 47 48 #define DISPLAY_AVBLOCK_COND_AVTAB 0 49 #define DISPLAY_AVBLOCK_UNCOND_AVTAB 1 50 #define DISPLAY_AVBLOCK_ROLE_TYPE_NODE 2 /* unused? */ 51 #define DISPLAY_AVBLOCK_ROLE_TRANS 3 52 #define DISPLAY_AVBLOCK_ROLE_ALLOW 4 53 #define DISPLAY_AVBLOCK_REQUIRES 5 54 #define DISPLAY_AVBLOCK_DECLARES 6 55 #define DISPLAY_AVBLOCK_FILENAME_TRANS 7 56 57 static policydb_t policydb; 58 extern unsigned int ss_initialized; 59 60 int policyvers = MOD_POLICYDB_VERSION_BASE; 61 62 static const char *symbol_labels[9] = { 63 "commons", 64 "classes", "roles ", "types ", "users ", "bools ", 65 "levels ", "cats ", "attribs" 66 }; 67 68 void usage(const char *progname) 69 { 70 printf("usage: %s binary_pol_file\n\n", progname); 71 exit(1); 72 } 73 74 static void render_access_mask(uint32_t mask, uint32_t class, policydb_t * p, 75 FILE * fp) 76 { 77 char *perm; 78 fprintf(fp, "{"); 79 perm = sepol_av_to_string(p, class, mask); 80 if (perm) 81 fprintf(fp, "%s ", perm); 82 fprintf(fp, "}"); 83 } 84 85 static void render_access_bitmap(ebitmap_t * map, uint32_t class, 86 policydb_t * p, FILE * fp) 87 { 88 unsigned int i; 89 char *perm; 90 fprintf(fp, "{"); 91 for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) { 92 if (ebitmap_get_bit(map, i)) { 93 perm = sepol_av_to_string(p, class, 1 << i); 94 if (perm) 95 fprintf(fp, " %s", perm); 96 } 97 } 98 fprintf(fp, " }"); 99 } 100 101 static void display_id(policydb_t * p, FILE * fp, uint32_t symbol_type, 102 uint32_t symbol_value, const char *prefix) 103 { 104 char *id = p->sym_val_to_name[symbol_type][symbol_value]; 105 scope_datum_t *scope = 106 (scope_datum_t *) hashtab_search(p->scope[symbol_type].table, id); 107 assert(scope != NULL); 108 if (scope->scope == SCOPE_REQ) { 109 fprintf(fp, " [%s%s]", prefix, id); 110 } else { 111 fprintf(fp, " %s%s", prefix, id); 112 } 113 } 114 115 int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy, 116 FILE * fp) 117 { 118 unsigned int i, num_types; 119 120 if (set->flags & TYPE_STAR) { 121 fprintf(fp, " * "); 122 return 0; 123 } else if (set->flags & TYPE_COMP) { 124 fprintf(fp, " ~"); 125 } 126 127 num_types = 0; 128 if (flags & RULE_SELF) { 129 num_types++; 130 } 131 132 for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); 133 i++) { 134 if (!ebitmap_get_bit(&set->types, i)) 135 continue; 136 num_types++; 137 if (num_types > 1) 138 break; 139 } 140 141 if (num_types <= 1) { 142 for (i = ebitmap_startbit(&set->negset); 143 i < ebitmap_length(&set->negset); i++) { 144 if (!ebitmap_get_bit(&set->negset, i)) 145 continue; 146 num_types++; 147 if (num_types > 1) 148 break; 149 } 150 } 151 152 if (num_types > 1) 153 fprintf(fp, "{"); 154 155 for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); 156 i++) { 157 if (!ebitmap_get_bit(&set->types, i)) 158 continue; 159 display_id(policy, fp, SYM_TYPES, i, ""); 160 } 161 162 for (i = ebitmap_startbit(&set->negset); 163 i < ebitmap_length(&set->negset); i++) { 164 if (!ebitmap_get_bit(&set->negset, i)) 165 continue; 166 display_id(policy, fp, SYM_TYPES, i, "-"); 167 } 168 169 if (flags & RULE_SELF) { 170 fprintf(fp, " self"); 171 } 172 173 if (num_types > 1) 174 fprintf(fp, " }"); 175 176 return 0; 177 } 178 179 int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp) 180 { 181 unsigned int i, num = 0; 182 183 if (roles->flags & ROLE_STAR) { 184 fprintf(fp, " * "); 185 return 0; 186 } else if (roles->flags & ROLE_COMP) { 187 fprintf(fp, " ~"); 188 } 189 190 for (i = ebitmap_startbit(&roles->roles); 191 i < ebitmap_length(&roles->roles); i++) { 192 if (!ebitmap_get_bit(&roles->roles, i)) 193 continue; 194 num++; 195 if (num > 1) { 196 fprintf(fp, "{"); 197 break; 198 } 199 } 200 201 for (i = ebitmap_startbit(&roles->roles); 202 i < ebitmap_length(&roles->roles); i++) { 203 if (ebitmap_get_bit(&roles->roles, i)) 204 display_id(p, fp, SYM_ROLES, i, ""); 205 } 206 207 if (num > 1) 208 fprintf(fp, " }"); 209 210 return 0; 211 212 } 213 214 int display_avrule(avrule_t * avrule, policydb_t * policy, 215 FILE * fp) 216 { 217 class_perm_node_t *cur; 218 int num_classes; 219 220 if (avrule == NULL) { 221 fprintf(fp, " <empty>\n"); 222 return 0; 223 } 224 if (avrule->specified & AVRULE_AV) { 225 if (avrule->specified & AVRULE_ALLOWED) { 226 fprintf(fp, " allow"); 227 } 228 if (avrule->specified & AVRULE_AUDITALLOW) { 229 fprintf(fp, " auditallow "); 230 } 231 if (avrule->specified & AVRULE_DONTAUDIT) { 232 fprintf(fp, " dontaudit"); 233 } 234 } else if (avrule->specified & AVRULE_TYPE) { 235 if (avrule->specified & AVRULE_TRANSITION) { 236 fprintf(fp, " type_transition"); 237 } 238 if (avrule->specified & AVRULE_MEMBER) { 239 fprintf(fp, " type_member"); 240 } 241 if (avrule->specified & AVRULE_CHANGE) { 242 fprintf(fp, " type_change"); 243 } 244 } else if (avrule->specified & AVRULE_NEVERALLOW) { 245 fprintf(fp, " neverallow"); 246 } else { 247 fprintf(fp, " ERROR: no valid rule type specified\n"); 248 return -1; 249 } 250 251 if (display_type_set(&avrule->stypes, 0, policy, fp)) 252 return -1; 253 254 if (display_type_set(&avrule->ttypes, avrule->flags, policy, fp)) 255 return -1; 256 257 fprintf(fp, " :"); 258 cur = avrule->perms; 259 num_classes = 0; 260 while (cur) { 261 num_classes++; 262 if (num_classes > 1) 263 break; 264 cur = cur->next; 265 } 266 267 if (num_classes > 1) 268 fprintf(fp, " {"); 269 270 cur = avrule->perms; 271 while (cur) { 272 display_id(policy, fp, SYM_CLASSES, cur->tclass - 1, ""); 273 cur = cur->next; 274 } 275 276 if (num_classes > 1) 277 fprintf(fp, " }"); 278 fprintf(fp, " "); 279 280 if (avrule->specified & (AVRULE_AV | AVRULE_NEVERALLOW)) { 281 render_access_mask(avrule->perms->data, avrule->perms->tclass, 282 policy, fp); 283 } else if (avrule->specified & AVRULE_TYPE) { 284 display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, ""); 285 } 286 287 fprintf(fp, ";\n"); 288 289 return 0; 290 } 291 292 int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) 293 { 294 type_datum_t *type; 295 FILE *fp; 296 unsigned int i, first_attrib = 1; 297 298 type = (type_datum_t *) datum; 299 fp = (FILE *) data; 300 301 if (type->primary) { 302 display_id(&policydb, fp, SYM_TYPES, type->s.value - 1, ""); 303 fprintf(fp, " [%d]: ", type->s.value); 304 } else { 305 /* as that aliases have no value of their own and that 306 * they can never be required by a module, use this 307 * alternative way of displaying a name */ 308 fprintf(fp, " %s [%d]: ", (char *)key, type->s.value); 309 } 310 if (type->flavor == TYPE_ATTRIB) { 311 fprintf(fp, "attribute for types"); 312 for (i = ebitmap_startbit(&type->types); 313 i < ebitmap_length(&type->types); i++) { 314 if (!ebitmap_get_bit(&type->types, i)) 315 continue; 316 if (first_attrib) { 317 first_attrib = 0; 318 } else { 319 fprintf(fp, ","); 320 } 321 display_id(&policydb, fp, SYM_TYPES, i, ""); 322 } 323 } else if (type->primary) { 324 fprintf(fp, "type"); 325 } else { 326 fprintf(fp, "alias for type"); 327 display_id(&policydb, fp, SYM_TYPES, type->s.value - 1, ""); 328 } 329 fprintf(fp, " flags:%x\n", type->flags); 330 331 return 0; 332 } 333 334 int display_types(policydb_t * p, FILE * fp) 335 { 336 if (hashtab_map(p->p_types.table, display_type_callback, fp)) 337 return -1; 338 return 0; 339 } 340 341 int display_users(policydb_t * p, FILE * fp) 342 { 343 unsigned int i, j; 344 ebitmap_t *bitmap; 345 for (i = 0; i < p->p_users.nprim; i++) { 346 display_id(p, fp, SYM_USERS, i, ""); 347 fprintf(fp, ":"); 348 bitmap = &(p->user_val_to_struct[i]->roles.roles); 349 for (j = ebitmap_startbit(bitmap); j < ebitmap_length(bitmap); 350 j++) { 351 if (ebitmap_get_bit(bitmap, j)) { 352 display_id(p, fp, SYM_ROLES, j, ""); 353 } 354 } 355 fprintf(fp, "\n"); 356 } 357 return 0; 358 } 359 360 int display_bools(policydb_t * p, FILE * fp) 361 { 362 unsigned int i; 363 364 for (i = 0; i < p->p_bools.nprim; i++) { 365 display_id(p, fp, SYM_BOOLS, i, ""); 366 fprintf(fp, " : %d\n", p->bool_val_to_struct[i]->state); 367 } 368 return 0; 369 } 370 371 void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) 372 { 373 374 cond_expr_t *cur; 375 for (cur = exp; cur != NULL; cur = cur->next) { 376 switch (cur->expr_type) { 377 case COND_BOOL: 378 fprintf(fp, "%s ", 379 p->p_bool_val_to_name[cur->bool - 1]); 380 break; 381 case COND_NOT: 382 fprintf(fp, "! "); 383 break; 384 case COND_OR: 385 fprintf(fp, "|| "); 386 break; 387 case COND_AND: 388 fprintf(fp, "&& "); 389 break; 390 case COND_XOR: 391 fprintf(fp, "^ "); 392 break; 393 case COND_EQ: 394 fprintf(fp, "== "); 395 break; 396 case COND_NEQ: 397 fprintf(fp, "!= "); 398 break; 399 default: 400 fprintf(fp, "error!"); 401 break; 402 } 403 } 404 } 405 406 void display_policycon(FILE * fp) 407 { 408 /* There was an attempt to implement this at one time. Look through 409 * git history to find it. */ 410 fprintf(fp, "Sorry, not implemented\n"); 411 } 412 413 void display_initial_sids(policydb_t * p, FILE * fp) 414 { 415 ocontext_t *cur; 416 char *user, *role, *type; 417 418 fprintf(fp, "Initial SIDs:\n"); 419 for (cur = p->ocontexts[OCON_ISID]; cur != NULL; cur = cur->next) { 420 user = p->p_user_val_to_name[cur->context[0].user - 1]; 421 role = p->p_role_val_to_name[cur->context[0].role - 1]; 422 type = p->p_type_val_to_name[cur->context[0].type - 1]; 423 fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n", 424 cur->u.name, cur->sid[0], user, role, type); 425 } 426 #if 0 427 fprintf(fp, "Policy Initial SIDs:\n"); 428 for (cur = p->ocontexts[OCON_POLICYISID]; cur != NULL; cur = cur->next) { 429 user = p->p_user_val_to_name[cur->context[0].user - 1]; 430 role = p->p_role_val_to_name[cur->context[0].role - 1]; 431 type = p->p_type_val_to_name[cur->context[0].type - 1]; 432 fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n", 433 cur->u.name, cur->sid[0], user, role, type); 434 } 435 #endif 436 } 437 438 void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp) 439 { 440 unsigned int i, num = 0; 441 442 for (i = ebitmap_startbit(classes); i < ebitmap_length(classes); i++) { 443 if (!ebitmap_get_bit(classes, i)) 444 continue; 445 num++; 446 if (num > 1) { 447 fprintf(fp, "{"); 448 break; 449 } 450 } 451 452 for (i = ebitmap_startbit(classes); i < ebitmap_length(classes); i++) { 453 if (ebitmap_get_bit(classes, i)) 454 display_id(p, fp, SYM_CLASSES, i, ""); 455 } 456 457 if (num > 1) 458 fprintf(fp, " }"); 459 } 460 461 void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp) 462 { 463 for (; tr; tr = tr->next) { 464 fprintf(fp, "role transition "); 465 display_mod_role_set(&tr->roles, p, fp); 466 display_type_set(&tr->types, 0, p, fp); 467 fprintf(fp, " :"); 468 display_class_set(&tr->classes, p, fp); 469 display_id(p, fp, SYM_ROLES, tr->new_role - 1, ""); 470 fprintf(fp, "\n"); 471 } 472 } 473 474 void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp) 475 { 476 for (; ra; ra = ra->next) { 477 fprintf(fp, "role allow "); 478 display_mod_role_set(&ra->roles, p, fp); 479 display_mod_role_set(&ra->new_roles, p, fp); 480 fprintf(fp, "\n"); 481 } 482 } 483 484 static void display_filename_trans(filename_trans_rule_t * tr, policydb_t * p, FILE * fp) 485 { 486 fprintf(fp, "filename transition"); 487 for (; tr; tr = tr->next) { 488 display_type_set(&tr->stypes, 0, p, fp); 489 display_type_set(&tr->ttypes, 0, p, fp); 490 display_id(p, fp, SYM_CLASSES, tr->tclass - 1, ":"); 491 display_id(p, fp, SYM_TYPES, tr->otype - 1, ""); 492 fprintf(fp, " %s\n", tr->name); 493 } 494 } 495 496 int role_display_callback(hashtab_key_t key __attribute__((unused)), 497 hashtab_datum_t datum, void *data) 498 { 499 role_datum_t *role; 500 FILE *fp; 501 502 role = (role_datum_t *) datum; 503 fp = (FILE *) data; 504 505 fprintf(fp, "role:"); 506 display_id(&policydb, fp, SYM_ROLES, role->s.value - 1, ""); 507 fprintf(fp, " types: "); 508 display_type_set(&role->types, 0, &policydb, fp); 509 fprintf(fp, "\n"); 510 511 return 0; 512 } 513 514 static int display_scope_index(scope_index_t * indices, policydb_t * p, 515 FILE * out_fp) 516 { 517 unsigned int i; 518 for (i = 0; i < SYM_NUM; i++) { 519 unsigned int any_found = 0, j; 520 fprintf(out_fp, "%s:", symbol_labels[i]); 521 for (j = ebitmap_startbit(&indices->scope[i]); 522 j < ebitmap_length(&indices->scope[i]); j++) { 523 if (ebitmap_get_bit(&indices->scope[i], j)) { 524 any_found = 1; 525 fprintf(out_fp, " %s", 526 p->sym_val_to_name[i][j]); 527 if (i == SYM_CLASSES) { 528 if (j < indices->class_perms_len) { 529 render_access_bitmap(indices-> 530 class_perms_map 531 + j, j + 1, 532 p, out_fp); 533 } else { 534 fprintf(out_fp, 535 "<no perms known>"); 536 } 537 } 538 } 539 } 540 if (!any_found) { 541 fprintf(out_fp, " <empty>"); 542 } 543 fprintf(out_fp, "\n"); 544 } 545 return 0; 546 } 547 548 #if 0 549 int display_cond_expressions(policydb_t * p, FILE * fp) 550 { 551 cond_node_t *cur; 552 cond_av_list_t *av_cur; 553 for (cur = p->cond_list; cur != NULL; cur = cur->next) { 554 fprintf(fp, "expression: "); 555 display_expr(p, cur->expr, fp); 556 fprintf(fp, "current state: %d\n", cur->cur_state); 557 fprintf(fp, "True list:\n"); 558 for (av_cur = cur->true_list; av_cur != NULL; 559 av_cur = av_cur->next) { 560 fprintf(fp, "\t"); 561 render_av_rule(&av_cur->node->key, &av_cur->node->datum, 562 RENDER_CONDITIONAL, p, fp); 563 } 564 fprintf(fp, "False list:\n"); 565 for (av_cur = cur->false_list; av_cur != NULL; 566 av_cur = av_cur->next) { 567 fprintf(fp, "\t"); 568 render_av_rule(&av_cur->node->key, &av_cur->node->datum, 569 RENDER_CONDITIONAL, p, fp); 570 } 571 } 572 return 0; 573 } 574 575 int change_bool(char *name, int state, policydb_t * p, FILE * fp) 576 { 577 cond_bool_datum_t *bool; 578 579 bool = hashtab_search(p->p_bools.table, name); 580 if (bool == NULL) { 581 fprintf(fp, "Could not find bool %s\n", name); 582 return -1; 583 } 584 bool->state = state; 585 evaluate_conds(p); 586 return 0; 587 } 588 #endif 589 590 int display_avdecl(avrule_decl_t * decl, int field, 591 policydb_t * policy, FILE * out_fp) 592 { 593 fprintf(out_fp, "decl %u:%s\n", decl->decl_id, 594 (decl->enabled ? " [enabled]" : "")); 595 switch (field) { 596 case DISPLAY_AVBLOCK_COND_AVTAB:{ 597 cond_list_t *cond = decl->cond_list; 598 avrule_t *avrule; 599 while (cond) { 600 fprintf(out_fp, "expression: "); 601 display_expr(&policydb, cond->expr, out_fp); 602 fprintf(out_fp, "current state: %d\n", 603 cond->cur_state); 604 fprintf(out_fp, "True list:\n"); 605 avrule = cond->avtrue_list; 606 while (avrule) { 607 display_avrule(avrule, 608 &policydb, out_fp); 609 avrule = avrule->next; 610 } 611 fprintf(out_fp, "False list:\n"); 612 avrule = cond->avfalse_list; 613 while (avrule) { 614 display_avrule(avrule, 615 &policydb, out_fp); 616 avrule = avrule->next; 617 } 618 cond = cond->next; 619 } 620 break; 621 } 622 case DISPLAY_AVBLOCK_UNCOND_AVTAB:{ 623 avrule_t *avrule = decl->avrules; 624 if (avrule == NULL) { 625 fprintf(out_fp, " <empty>\n"); 626 } 627 while (avrule != NULL) { 628 if (display_avrule(avrule, policy, out_fp)) 629 return -1; 630 avrule = avrule->next; 631 } 632 break; 633 } 634 case DISPLAY_AVBLOCK_ROLE_TYPE_NODE:{ /* role_type_node */ 635 break; 636 } 637 case DISPLAY_AVBLOCK_ROLE_TRANS:{ 638 display_role_trans(decl->role_tr_rules, policy, out_fp); 639 break; 640 } 641 case DISPLAY_AVBLOCK_ROLE_ALLOW:{ 642 display_role_allow(decl->role_allow_rules, policy, 643 out_fp); 644 break; 645 } 646 case DISPLAY_AVBLOCK_REQUIRES:{ 647 if (display_scope_index 648 (&decl->required, policy, out_fp)) { 649 return -1; 650 } 651 break; 652 } 653 case DISPLAY_AVBLOCK_DECLARES:{ 654 if (display_scope_index 655 (&decl->declared, policy, out_fp)) { 656 return -1; 657 } 658 break; 659 } 660 case DISPLAY_AVBLOCK_FILENAME_TRANS: 661 display_filename_trans(decl->filename_trans_rules, policy, 662 out_fp); 663 break; 664 default:{ 665 assert(0); 666 } 667 } 668 return 0; /* should never get here */ 669 } 670 671 int display_avblock(int field, policydb_t * policy, 672 FILE * out_fp) 673 { 674 avrule_block_t *block = policydb.global; 675 while (block != NULL) { 676 fprintf(out_fp, "--- begin avrule block ---\n"); 677 avrule_decl_t *decl = block->branch_list; 678 while (decl != NULL) { 679 if (display_avdecl(decl, field, policy, out_fp)) { 680 return -1; 681 } 682 decl = decl->next; 683 } 684 block = block->next; 685 } 686 return 0; 687 } 688 689 int display_handle_unknown(policydb_t * p, FILE * out_fp) 690 { 691 if (p->handle_unknown == ALLOW_UNKNOWN) 692 fprintf(out_fp, "Allow unknown classes and perms\n"); 693 else if (p->handle_unknown == DENY_UNKNOWN) 694 fprintf(out_fp, "Deny unknown classes and perms\n"); 695 else if (p->handle_unknown == REJECT_UNKNOWN) 696 fprintf(out_fp, "Reject unknown classes and perms\n"); 697 return 0; 698 } 699 700 static int read_policy(char *filename, policydb_t * policy) 701 { 702 FILE *in_fp; 703 struct policy_file f; 704 int retval; 705 uint32_t buf[1]; 706 707 if ((in_fp = fopen(filename, "rb")) == NULL) { 708 fprintf(stderr, "Can't open '%s': %s\n", 709 filename, strerror(errno)); 710 exit(1); 711 } 712 policy_file_init(&f); 713 f.type = PF_USE_STDIO; 714 f.fp = in_fp; 715 716 /* peek at the first byte. if they are indicative of a 717 package use the package reader, otherwise use the normal 718 policy reader */ 719 if (fread(buf, sizeof(uint32_t), 1, in_fp) != 1) { 720 fprintf(stderr, "Could not read from policy.\n"); 721 exit(1); 722 } 723 rewind(in_fp); 724 if (le32_to_cpu(buf[0]) == SEPOL_MODULE_PACKAGE_MAGIC) { 725 sepol_module_package_t *package; 726 if (sepol_module_package_create(&package)) { 727 fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__); 728 exit(1); 729 } 730 package->policy = (sepol_policydb_t *) policy; 731 package->file_contexts = NULL; 732 retval = 733 sepol_module_package_read(package, 734 (sepol_policy_file_t *) & f, 1); 735 free(package->file_contexts); 736 } else { 737 if (policydb_init(policy)) { 738 fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__); 739 exit(1); 740 } 741 retval = policydb_read(policy, &f, 1); 742 } 743 fclose(in_fp); 744 return retval; 745 } 746 747 static void link_module(policydb_t * base, FILE * out_fp) 748 { 749 char module_name[80] = { 0 }; 750 int ret; 751 policydb_t module, *mods = &module; 752 753 if (base->policy_type != POLICY_BASE) { 754 printf("Can only link if initial file was a base policy.\n"); 755 return; 756 } 757 printf("\nModule filename: "); 758 if (fgets(module_name, sizeof(module_name), stdin) == NULL) { 759 fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, 760 strerror(errno)); 761 exit(1); 762 } 763 764 module_name[strlen(module_name) - 1] = '\0'; /* remove LF */ 765 if (module_name[0] == '\0') { 766 return; 767 } 768 769 /* read the binary policy */ 770 fprintf(out_fp, "Reading module...\n"); 771 if (read_policy(module_name, mods)) { 772 fprintf(stderr, 773 "%s: error(s) encountered while loading policy\n", 774 module_name); 775 exit(1); 776 } 777 if (module.policy_type != POLICY_MOD) { 778 fprintf(stderr, "This file is not a loadable policy module.\n"); 779 exit(1); 780 } 781 if (policydb_index_classes(&module) || 782 policydb_index_others(NULL, &module, 0)) { 783 fprintf(stderr, "Could not index module.\n"); 784 exit(1); 785 } 786 ret = link_modules(NULL, base, &mods, 1, 0); 787 if (ret != 0) { 788 printf("Link failed (error %d)\n", ret); 789 printf("(You will probably need to restart dismod.)\n"); 790 } 791 policydb_destroy(&module); 792 return; 793 } 794 795 static void display_policycaps(policydb_t * p, FILE * fp) 796 { 797 ebitmap_node_t *node; 798 const char *capname; 799 char buf[64]; 800 unsigned int i; 801 802 fprintf(fp, "policy capabilities:\n"); 803 ebitmap_for_each_bit(&p->policycaps, node, i) { 804 if (ebitmap_node_get_bit(node, i)) { 805 capname = sepol_polcap_getname(i); 806 if (capname == NULL) { 807 snprintf(buf, sizeof(buf), "unknown (%d)", i); 808 capname = buf; 809 } 810 fprintf(fp, "\t%s\n", capname); 811 } 812 } 813 } 814 815 int menu(void) 816 { 817 printf("\nSelect a command:\n"); 818 printf("1) display unconditional AVTAB\n"); 819 printf("2) display conditional AVTAB\n"); 820 printf("3) display users\n"); 821 printf("4) display bools\n"); 822 printf("5) display roles\n"); 823 printf("6) display types, attributes, and aliases\n"); 824 printf("7) display role transitions\n"); 825 printf("8) display role allows\n"); 826 printf("9) Display policycon\n"); 827 printf("0) Display initial SIDs\n"); 828 printf("\n"); 829 printf("a) Display avrule requirements\n"); 830 printf("b) Display avrule declarations\n"); 831 printf("c) Display policy capabilities\n"); 832 printf("l) Link in a module\n"); 833 printf("u) Display the unknown handling setting\n"); 834 printf("F) Display filename_trans rules\n"); 835 printf("\n"); 836 printf("f) set output file\n"); 837 printf("m) display menu\n"); 838 printf("q) quit\n"); 839 return 0; 840 } 841 842 int main(int argc, char **argv) 843 { 844 FILE *out_fp = stdout; 845 char ans[81], OutfileName[121]; 846 847 if (argc != 2) 848 usage(argv[0]); 849 850 /* read the binary policy */ 851 fprintf(out_fp, "Reading policy...\n"); 852 if (policydb_init(&policydb)) { 853 fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__); 854 exit(1); 855 } 856 if (read_policy(argv[1], &policydb)) { 857 fprintf(stderr, 858 "%s: error(s) encountered while loading policy\n", 859 argv[0]); 860 exit(1); 861 } 862 863 if (policydb.policy_type != POLICY_BASE && 864 policydb.policy_type != POLICY_MOD) { 865 fprintf(stderr, 866 "This file is neither a base nor loadable policy module.\n"); 867 exit(1); 868 } 869 870 if (policydb_index_classes(&policydb)) { 871 fprintf(stderr, "Error indexing classes\n"); 872 exit(1); 873 } 874 875 if (policydb_index_others(NULL, &policydb, 1)) { 876 fprintf(stderr, "Error indexing others\n"); 877 exit(1); 878 } 879 880 if (policydb.policy_type == POLICY_BASE) { 881 printf("Binary base policy file loaded.\n\n"); 882 } else { 883 printf("Binary policy module file loaded.\n"); 884 printf("Module name: %s\n", policydb.name); 885 printf("Module version: %s\n", policydb.version); 886 printf("\n"); 887 } 888 889 menu(); 890 for (;;) { 891 printf("\nCommand (\'m\' for menu): "); 892 if (fgets(ans, sizeof(ans), stdin) == NULL) { 893 fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, 894 strerror(errno)); 895 continue; 896 } 897 898 switch (ans[0]) { 899 900 case '1': 901 fprintf(out_fp, "unconditional avtab:\n"); 902 display_avblock(DISPLAY_AVBLOCK_UNCOND_AVTAB, 903 &policydb, out_fp); 904 break; 905 case '2': 906 fprintf(out_fp, "conditional avtab:\n"); 907 display_avblock(DISPLAY_AVBLOCK_COND_AVTAB, 908 &policydb, out_fp); 909 break; 910 case '3': 911 display_users(&policydb, out_fp); 912 break; 913 case '4': 914 display_bools(&policydb, out_fp); 915 break; 916 case '5': 917 if (hashtab_map 918 (policydb.p_roles.table, role_display_callback, 919 out_fp)) 920 exit(1); 921 break; 922 case '6': 923 if (display_types(&policydb, out_fp)) { 924 fprintf(stderr, "Error displaying types\n"); 925 exit(1); 926 } 927 break; 928 case '7': 929 fprintf(out_fp, "role transitions:\n"); 930 display_avblock(DISPLAY_AVBLOCK_ROLE_TRANS, 931 &policydb, out_fp); 932 break; 933 case '8': 934 fprintf(out_fp, "role allows:\n"); 935 display_avblock(DISPLAY_AVBLOCK_ROLE_ALLOW, 936 &policydb, out_fp); 937 break; 938 case '9': 939 display_policycon(out_fp); 940 break; 941 case '0': 942 display_initial_sids(&policydb, out_fp); 943 break; 944 case 'a': 945 fprintf(out_fp, "avrule block requirements:\n"); 946 display_avblock(DISPLAY_AVBLOCK_REQUIRES, 947 &policydb, out_fp); 948 break; 949 case 'b': 950 fprintf(out_fp, "avrule block declarations:\n"); 951 display_avblock(DISPLAY_AVBLOCK_DECLARES, 952 &policydb, out_fp); 953 break; 954 case 'c': 955 display_policycaps(&policydb, out_fp); 956 break; 957 case 'u': 958 case 'U': 959 display_handle_unknown(&policydb, out_fp); 960 break; 961 case 'f': 962 printf 963 ("\nFilename for output (<CR> for screen output): "); 964 if (fgets(OutfileName, sizeof(OutfileName), stdin) == NULL) { 965 fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, 966 strerror(errno)); 967 break; 968 } 969 OutfileName[strlen(OutfileName) - 1] = '\0'; /* fix_string (remove LF) */ 970 if (strlen(OutfileName) == 0) 971 out_fp = stdout; 972 else if ((out_fp = fopen(OutfileName, "w")) == NULL) { 973 fprintf(stderr, "Cannot open output file %s\n", 974 OutfileName); 975 out_fp = stdout; 976 } 977 if (out_fp != stdout) 978 printf("\nOutput to file: %s\n", OutfileName); 979 break; 980 case 'F': 981 fprintf(out_fp, "filename_trans rules:\n"); 982 display_avblock(DISPLAY_AVBLOCK_FILENAME_TRANS, 983 &policydb, out_fp); 984 break; 985 case 'l': 986 link_module(&policydb, out_fp); 987 break; 988 case 'q': 989 policydb_destroy(&policydb); 990 exit(0); 991 break; 992 case 'm': 993 menu(); 994 break; 995 default: 996 printf("\nInvalid choice\n"); 997 menu(); 998 break; 999 1000 } 1001 } 1002 exit(EXIT_SUCCESS); 1003 } 1004