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