16cd6a6acSopenharmony_ci 26cd6a6acSopenharmony_ci/* Authors: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> 36cd6a6acSopenharmony_ci * 46cd6a6acSopenharmony_ci * Copyright (C) 2003,2004,2005 Tresys Technology, LLC 56cd6a6acSopenharmony_ci * This program is free software; you can redistribute it and/or modify 66cd6a6acSopenharmony_ci * it under the terms of the GNU General Public License as published by 76cd6a6acSopenharmony_ci * the Free Software Foundation, version 2. 86cd6a6acSopenharmony_ci */ 96cd6a6acSopenharmony_ci 106cd6a6acSopenharmony_ci/* 116cd6a6acSopenharmony_ci * dismod.c 126cd6a6acSopenharmony_ci * 136cd6a6acSopenharmony_ci * Test program to the contents of a binary policy in text 146cd6a6acSopenharmony_ci * form. 156cd6a6acSopenharmony_ci * 166cd6a6acSopenharmony_ci * dismod binary_mod_file 176cd6a6acSopenharmony_ci */ 186cd6a6acSopenharmony_ci 196cd6a6acSopenharmony_ci#include <getopt.h> 206cd6a6acSopenharmony_ci#include <assert.h> 216cd6a6acSopenharmony_ci#include <sys/stat.h> 226cd6a6acSopenharmony_ci#include <sys/types.h> 236cd6a6acSopenharmony_ci#include <sys/mman.h> 246cd6a6acSopenharmony_ci#include <errno.h> 256cd6a6acSopenharmony_ci#include <stdio.h> 266cd6a6acSopenharmony_ci#include <fcntl.h> 276cd6a6acSopenharmony_ci#include <stdlib.h> 286cd6a6acSopenharmony_ci#include <unistd.h> 296cd6a6acSopenharmony_ci 306cd6a6acSopenharmony_ci#include <sepol/policydb/policydb.h> 316cd6a6acSopenharmony_ci#include <sepol/policydb/services.h> 326cd6a6acSopenharmony_ci#include <sepol/policydb/conditional.h> 336cd6a6acSopenharmony_ci#include <sepol/policydb/link.h> 346cd6a6acSopenharmony_ci#include <sepol/policydb/module.h> 356cd6a6acSopenharmony_ci#include <sepol/policydb/util.h> 366cd6a6acSopenharmony_ci#include <sepol/policydb/polcaps.h> 376cd6a6acSopenharmony_ci 386cd6a6acSopenharmony_ci#include <byteswap.h> 396cd6a6acSopenharmony_ci#include <endian.h> 406cd6a6acSopenharmony_ci 416cd6a6acSopenharmony_ci#if __BYTE_ORDER == __LITTLE_ENDIAN 426cd6a6acSopenharmony_ci#define le32_to_cpu(x) (x) 436cd6a6acSopenharmony_ci#else 446cd6a6acSopenharmony_ci#define le32_to_cpu(x) bswap_32(x) 456cd6a6acSopenharmony_ci#endif 466cd6a6acSopenharmony_ci 476cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_COND_AVTAB 0 486cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_UNCOND_AVTAB 1 496cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_ROLE_TYPE_NODE 2 /* unused? */ 506cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_ROLE_TRANS 3 516cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_ROLE_ALLOW 4 526cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_REQUIRES 5 536cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_DECLARES 6 546cd6a6acSopenharmony_ci#define DISPLAY_AVBLOCK_FILENAME_TRANS 7 556cd6a6acSopenharmony_ci 566cd6a6acSopenharmony_cistatic policydb_t policydb; 576cd6a6acSopenharmony_ciextern unsigned int ss_initialized; 586cd6a6acSopenharmony_ci 596cd6a6acSopenharmony_ciint policyvers = MOD_POLICYDB_VERSION_BASE; 606cd6a6acSopenharmony_ci 616cd6a6acSopenharmony_cistatic const char *symbol_labels[9] = { 626cd6a6acSopenharmony_ci "commons", 636cd6a6acSopenharmony_ci "classes", "roles ", "types ", "users ", "bools ", 646cd6a6acSopenharmony_ci "levels ", "cats ", "attribs" 656cd6a6acSopenharmony_ci}; 666cd6a6acSopenharmony_ci 676cd6a6acSopenharmony_cistatic __attribute__((__noreturn__)) void usage(const char *progname) 686cd6a6acSopenharmony_ci{ 696cd6a6acSopenharmony_ci printf("usage: %s binary_pol_file\n\n", progname); 706cd6a6acSopenharmony_ci exit(1); 716cd6a6acSopenharmony_ci} 726cd6a6acSopenharmony_ci 736cd6a6acSopenharmony_cistatic void render_access_mask(uint32_t mask, uint32_t class, policydb_t * p, 746cd6a6acSopenharmony_ci FILE * fp) 756cd6a6acSopenharmony_ci{ 766cd6a6acSopenharmony_ci char *perm; 776cd6a6acSopenharmony_ci fprintf(fp, "{"); 786cd6a6acSopenharmony_ci perm = sepol_av_to_string(p, class, mask); 796cd6a6acSopenharmony_ci if (perm) 806cd6a6acSopenharmony_ci fprintf(fp, "%s ", perm); 816cd6a6acSopenharmony_ci fprintf(fp, "}"); 826cd6a6acSopenharmony_ci} 836cd6a6acSopenharmony_ci 846cd6a6acSopenharmony_cistatic void render_access_bitmap(ebitmap_t * map, uint32_t class, 856cd6a6acSopenharmony_ci policydb_t * p, FILE * fp) 866cd6a6acSopenharmony_ci{ 876cd6a6acSopenharmony_ci unsigned int i; 886cd6a6acSopenharmony_ci char *perm; 896cd6a6acSopenharmony_ci fprintf(fp, "{"); 906cd6a6acSopenharmony_ci for (i = ebitmap_startbit(map); i < ebitmap_length(map); i++) { 916cd6a6acSopenharmony_ci if (ebitmap_get_bit(map, i)) { 926cd6a6acSopenharmony_ci perm = sepol_av_to_string(p, class, UINT32_C(1) << i); 936cd6a6acSopenharmony_ci if (perm) 946cd6a6acSopenharmony_ci fprintf(fp, " %s", perm); 956cd6a6acSopenharmony_ci } 966cd6a6acSopenharmony_ci } 976cd6a6acSopenharmony_ci fprintf(fp, " }"); 986cd6a6acSopenharmony_ci} 996cd6a6acSopenharmony_ci 1006cd6a6acSopenharmony_cistatic void display_id(policydb_t * p, FILE * fp, uint32_t symbol_type, 1016cd6a6acSopenharmony_ci uint32_t symbol_value, const char *prefix) 1026cd6a6acSopenharmony_ci{ 1036cd6a6acSopenharmony_ci char *id = p->sym_val_to_name[symbol_type][symbol_value]; 1046cd6a6acSopenharmony_ci scope_datum_t *scope = 1056cd6a6acSopenharmony_ci (scope_datum_t *) hashtab_search(p->scope[symbol_type].table, id); 1066cd6a6acSopenharmony_ci assert(scope != NULL); 1076cd6a6acSopenharmony_ci if (scope->scope == SCOPE_REQ) { 1086cd6a6acSopenharmony_ci fprintf(fp, " [%s%s]", prefix, id); 1096cd6a6acSopenharmony_ci } else { 1106cd6a6acSopenharmony_ci fprintf(fp, " %s%s", prefix, id); 1116cd6a6acSopenharmony_ci } 1126cd6a6acSopenharmony_ci} 1136cd6a6acSopenharmony_ci 1146cd6a6acSopenharmony_cistatic int display_type_set(type_set_t * set, uint32_t flags, policydb_t * policy, 1156cd6a6acSopenharmony_ci FILE * fp) 1166cd6a6acSopenharmony_ci{ 1176cd6a6acSopenharmony_ci unsigned int i, num_types; 1186cd6a6acSopenharmony_ci 1196cd6a6acSopenharmony_ci if (set->flags & TYPE_STAR) { 1206cd6a6acSopenharmony_ci fprintf(fp, " * "); 1216cd6a6acSopenharmony_ci return 0; 1226cd6a6acSopenharmony_ci } else if (set->flags & TYPE_COMP) { 1236cd6a6acSopenharmony_ci fprintf(fp, " ~"); 1246cd6a6acSopenharmony_ci } 1256cd6a6acSopenharmony_ci 1266cd6a6acSopenharmony_ci num_types = 0; 1276cd6a6acSopenharmony_ci if (flags & RULE_SELF) { 1286cd6a6acSopenharmony_ci num_types++; 1296cd6a6acSopenharmony_ci } 1306cd6a6acSopenharmony_ci 1316cd6a6acSopenharmony_ci for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); 1326cd6a6acSopenharmony_ci i++) { 1336cd6a6acSopenharmony_ci if (!ebitmap_get_bit(&set->types, i)) 1346cd6a6acSopenharmony_ci continue; 1356cd6a6acSopenharmony_ci num_types++; 1366cd6a6acSopenharmony_ci if (num_types > 1) 1376cd6a6acSopenharmony_ci break; 1386cd6a6acSopenharmony_ci } 1396cd6a6acSopenharmony_ci 1406cd6a6acSopenharmony_ci if (num_types <= 1) { 1416cd6a6acSopenharmony_ci for (i = ebitmap_startbit(&set->negset); 1426cd6a6acSopenharmony_ci i < ebitmap_length(&set->negset); i++) { 1436cd6a6acSopenharmony_ci if (!ebitmap_get_bit(&set->negset, i)) 1446cd6a6acSopenharmony_ci continue; 1456cd6a6acSopenharmony_ci num_types++; 1466cd6a6acSopenharmony_ci if (num_types > 1) 1476cd6a6acSopenharmony_ci break; 1486cd6a6acSopenharmony_ci } 1496cd6a6acSopenharmony_ci } 1506cd6a6acSopenharmony_ci 1516cd6a6acSopenharmony_ci if (num_types > 1) 1526cd6a6acSopenharmony_ci fprintf(fp, "{"); 1536cd6a6acSopenharmony_ci 1546cd6a6acSopenharmony_ci for (i = ebitmap_startbit(&set->types); i < ebitmap_length(&set->types); 1556cd6a6acSopenharmony_ci i++) { 1566cd6a6acSopenharmony_ci if (!ebitmap_get_bit(&set->types, i)) 1576cd6a6acSopenharmony_ci continue; 1586cd6a6acSopenharmony_ci display_id(policy, fp, SYM_TYPES, i, ""); 1596cd6a6acSopenharmony_ci } 1606cd6a6acSopenharmony_ci 1616cd6a6acSopenharmony_ci for (i = ebitmap_startbit(&set->negset); 1626cd6a6acSopenharmony_ci i < ebitmap_length(&set->negset); i++) { 1636cd6a6acSopenharmony_ci if (!ebitmap_get_bit(&set->negset, i)) 1646cd6a6acSopenharmony_ci continue; 1656cd6a6acSopenharmony_ci display_id(policy, fp, SYM_TYPES, i, "-"); 1666cd6a6acSopenharmony_ci } 1676cd6a6acSopenharmony_ci 1686cd6a6acSopenharmony_ci if (flags & RULE_SELF) { 1696cd6a6acSopenharmony_ci fprintf(fp, " self"); 1706cd6a6acSopenharmony_ci } 1716cd6a6acSopenharmony_ci 1726cd6a6acSopenharmony_ci if (num_types > 1) 1736cd6a6acSopenharmony_ci fprintf(fp, " }"); 1746cd6a6acSopenharmony_ci 1756cd6a6acSopenharmony_ci return 0; 1766cd6a6acSopenharmony_ci} 1776cd6a6acSopenharmony_ci 1786cd6a6acSopenharmony_cistatic int display_mod_role_set(role_set_t * roles, policydb_t * p, FILE * fp) 1796cd6a6acSopenharmony_ci{ 1806cd6a6acSopenharmony_ci unsigned int i, num = 0; 1816cd6a6acSopenharmony_ci 1826cd6a6acSopenharmony_ci if (roles->flags & ROLE_STAR) { 1836cd6a6acSopenharmony_ci fprintf(fp, " * "); 1846cd6a6acSopenharmony_ci return 0; 1856cd6a6acSopenharmony_ci } else if (roles->flags & ROLE_COMP) { 1866cd6a6acSopenharmony_ci fprintf(fp, " ~"); 1876cd6a6acSopenharmony_ci } 1886cd6a6acSopenharmony_ci 1896cd6a6acSopenharmony_ci for (i = ebitmap_startbit(&roles->roles); 1906cd6a6acSopenharmony_ci i < ebitmap_length(&roles->roles); i++) { 1916cd6a6acSopenharmony_ci if (!ebitmap_get_bit(&roles->roles, i)) 1926cd6a6acSopenharmony_ci continue; 1936cd6a6acSopenharmony_ci num++; 1946cd6a6acSopenharmony_ci if (num > 1) { 1956cd6a6acSopenharmony_ci fprintf(fp, "{"); 1966cd6a6acSopenharmony_ci break; 1976cd6a6acSopenharmony_ci } 1986cd6a6acSopenharmony_ci } 1996cd6a6acSopenharmony_ci 2006cd6a6acSopenharmony_ci for (i = ebitmap_startbit(&roles->roles); 2016cd6a6acSopenharmony_ci i < ebitmap_length(&roles->roles); i++) { 2026cd6a6acSopenharmony_ci if (ebitmap_get_bit(&roles->roles, i)) 2036cd6a6acSopenharmony_ci display_id(p, fp, SYM_ROLES, i, ""); 2046cd6a6acSopenharmony_ci } 2056cd6a6acSopenharmony_ci 2066cd6a6acSopenharmony_ci if (num > 1) 2076cd6a6acSopenharmony_ci fprintf(fp, " }"); 2086cd6a6acSopenharmony_ci 2096cd6a6acSopenharmony_ci return 0; 2106cd6a6acSopenharmony_ci 2116cd6a6acSopenharmony_ci} 2126cd6a6acSopenharmony_ci 2136cd6a6acSopenharmony_cistatic int display_avrule(avrule_t * avrule, policydb_t * policy, 2146cd6a6acSopenharmony_ci FILE * fp) 2156cd6a6acSopenharmony_ci{ 2166cd6a6acSopenharmony_ci class_perm_node_t *cur; 2176cd6a6acSopenharmony_ci int num_classes; 2186cd6a6acSopenharmony_ci 2196cd6a6acSopenharmony_ci if (avrule == NULL) { 2206cd6a6acSopenharmony_ci fprintf(fp, " <empty>\n"); 2216cd6a6acSopenharmony_ci return 0; 2226cd6a6acSopenharmony_ci } 2236cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_AV) { 2246cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_ALLOWED) { 2256cd6a6acSopenharmony_ci fprintf(fp, " allow"); 2266cd6a6acSopenharmony_ci } 2276cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_AUDITALLOW) { 2286cd6a6acSopenharmony_ci fprintf(fp, " auditallow "); 2296cd6a6acSopenharmony_ci } 2306cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_DONTAUDIT) { 2316cd6a6acSopenharmony_ci fprintf(fp, " dontaudit"); 2326cd6a6acSopenharmony_ci } 2336cd6a6acSopenharmony_ci } else if (avrule->specified & AVRULE_TYPE) { 2346cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_TRANSITION) { 2356cd6a6acSopenharmony_ci fprintf(fp, " type_transition"); 2366cd6a6acSopenharmony_ci } 2376cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_MEMBER) { 2386cd6a6acSopenharmony_ci fprintf(fp, " type_member"); 2396cd6a6acSopenharmony_ci } 2406cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_CHANGE) { 2416cd6a6acSopenharmony_ci fprintf(fp, " type_change"); 2426cd6a6acSopenharmony_ci } 2436cd6a6acSopenharmony_ci } else if (avrule->specified & AVRULE_NEVERALLOW) { 2446cd6a6acSopenharmony_ci fprintf(fp, " neverallow"); 2456cd6a6acSopenharmony_ci } else if (avrule->specified & AVRULE_XPERMS) { 2466cd6a6acSopenharmony_ci if (avrule->specified & AVRULE_XPERMS_ALLOWED) 2476cd6a6acSopenharmony_ci fprintf(fp, "allowxperm "); 2486cd6a6acSopenharmony_ci else if (avrule->specified & AVRULE_XPERMS_AUDITALLOW) 2496cd6a6acSopenharmony_ci fprintf(fp, "auditallowxperm "); 2506cd6a6acSopenharmony_ci else if (avrule->specified & AVRULE_XPERMS_DONTAUDIT) 2516cd6a6acSopenharmony_ci fprintf(fp, "dontauditxperm "); 2526cd6a6acSopenharmony_ci } else { 2536cd6a6acSopenharmony_ci fprintf(fp, " ERROR: no valid rule type specified\n"); 2546cd6a6acSopenharmony_ci return -1; 2556cd6a6acSopenharmony_ci } 2566cd6a6acSopenharmony_ci 2576cd6a6acSopenharmony_ci if (display_type_set(&avrule->stypes, 0, policy, fp)) 2586cd6a6acSopenharmony_ci return -1; 2596cd6a6acSopenharmony_ci 2606cd6a6acSopenharmony_ci if (display_type_set(&avrule->ttypes, avrule->flags, policy, fp)) 2616cd6a6acSopenharmony_ci return -1; 2626cd6a6acSopenharmony_ci 2636cd6a6acSopenharmony_ci fprintf(fp, " :"); 2646cd6a6acSopenharmony_ci cur = avrule->perms; 2656cd6a6acSopenharmony_ci num_classes = 0; 2666cd6a6acSopenharmony_ci while (cur) { 2676cd6a6acSopenharmony_ci num_classes++; 2686cd6a6acSopenharmony_ci if (num_classes > 1) 2696cd6a6acSopenharmony_ci break; 2706cd6a6acSopenharmony_ci cur = cur->next; 2716cd6a6acSopenharmony_ci } 2726cd6a6acSopenharmony_ci 2736cd6a6acSopenharmony_ci if (num_classes > 1) 2746cd6a6acSopenharmony_ci fprintf(fp, " {"); 2756cd6a6acSopenharmony_ci 2766cd6a6acSopenharmony_ci cur = avrule->perms; 2776cd6a6acSopenharmony_ci while (cur) { 2786cd6a6acSopenharmony_ci display_id(policy, fp, SYM_CLASSES, cur->tclass - 1, ""); 2796cd6a6acSopenharmony_ci cur = cur->next; 2806cd6a6acSopenharmony_ci } 2816cd6a6acSopenharmony_ci 2826cd6a6acSopenharmony_ci if (num_classes > 1) 2836cd6a6acSopenharmony_ci fprintf(fp, " }"); 2846cd6a6acSopenharmony_ci fprintf(fp, " "); 2856cd6a6acSopenharmony_ci 2866cd6a6acSopenharmony_ci if (avrule->specified & (AVRULE_AV | AVRULE_NEVERALLOW)) { 2876cd6a6acSopenharmony_ci render_access_mask(avrule->perms->data, avrule->perms->tclass, 2886cd6a6acSopenharmony_ci policy, fp); 2896cd6a6acSopenharmony_ci } else if (avrule->specified & AVRULE_TYPE) { 2906cd6a6acSopenharmony_ci display_id(policy, fp, SYM_TYPES, avrule->perms->data - 1, ""); 2916cd6a6acSopenharmony_ci } else if (avrule->specified & AVRULE_XPERMS) { 2926cd6a6acSopenharmony_ci avtab_extended_perms_t xperms; 2936cd6a6acSopenharmony_ci int i; 2946cd6a6acSopenharmony_ci 2956cd6a6acSopenharmony_ci if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLFUNCTION) 2966cd6a6acSopenharmony_ci xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION; 2976cd6a6acSopenharmony_ci else if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLDRIVER) 2986cd6a6acSopenharmony_ci xperms.specified = AVTAB_XPERMS_IOCTLDRIVER; 2996cd6a6acSopenharmony_ci else { 3006cd6a6acSopenharmony_ci fprintf(fp, " ERROR: no valid xperms specified\n"); 3016cd6a6acSopenharmony_ci return -1; 3026cd6a6acSopenharmony_ci } 3036cd6a6acSopenharmony_ci 3046cd6a6acSopenharmony_ci xperms.driver = avrule->xperms->driver; 3056cd6a6acSopenharmony_ci for (i = 0; i < EXTENDED_PERMS_LEN; i++) 3066cd6a6acSopenharmony_ci xperms.perms[i] = avrule->xperms->perms[i]; 3076cd6a6acSopenharmony_ci 3086cd6a6acSopenharmony_ci fprintf(fp, "%s", sepol_extended_perms_to_string(&xperms)); 3096cd6a6acSopenharmony_ci } 3106cd6a6acSopenharmony_ci 3116cd6a6acSopenharmony_ci fprintf(fp, ";\n"); 3126cd6a6acSopenharmony_ci 3136cd6a6acSopenharmony_ci return 0; 3146cd6a6acSopenharmony_ci} 3156cd6a6acSopenharmony_ci 3166cd6a6acSopenharmony_cistatic int display_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) 3176cd6a6acSopenharmony_ci{ 3186cd6a6acSopenharmony_ci type_datum_t *type; 3196cd6a6acSopenharmony_ci FILE *fp; 3206cd6a6acSopenharmony_ci unsigned int i, first_attrib = 1; 3216cd6a6acSopenharmony_ci 3226cd6a6acSopenharmony_ci type = (type_datum_t *) datum; 3236cd6a6acSopenharmony_ci fp = (FILE *) data; 3246cd6a6acSopenharmony_ci 3256cd6a6acSopenharmony_ci if (type->primary) { 3266cd6a6acSopenharmony_ci display_id(&policydb, fp, SYM_TYPES, type->s.value - 1, ""); 3276cd6a6acSopenharmony_ci fprintf(fp, " [%d]: ", type->s.value); 3286cd6a6acSopenharmony_ci } else { 3296cd6a6acSopenharmony_ci /* as that aliases have no value of their own and that 3306cd6a6acSopenharmony_ci * they can never be required by a module, use this 3316cd6a6acSopenharmony_ci * alternative way of displaying a name */ 3326cd6a6acSopenharmony_ci fprintf(fp, " %s [%d]: ", (char *)key, type->s.value); 3336cd6a6acSopenharmony_ci } 3346cd6a6acSopenharmony_ci if (type->flavor == TYPE_ATTRIB) { 3356cd6a6acSopenharmony_ci fprintf(fp, "attribute for types"); 3366cd6a6acSopenharmony_ci for (i = ebitmap_startbit(&type->types); 3376cd6a6acSopenharmony_ci i < ebitmap_length(&type->types); i++) { 3386cd6a6acSopenharmony_ci if (!ebitmap_get_bit(&type->types, i)) 3396cd6a6acSopenharmony_ci continue; 3406cd6a6acSopenharmony_ci if (first_attrib) { 3416cd6a6acSopenharmony_ci first_attrib = 0; 3426cd6a6acSopenharmony_ci } else { 3436cd6a6acSopenharmony_ci fprintf(fp, ","); 3446cd6a6acSopenharmony_ci } 3456cd6a6acSopenharmony_ci display_id(&policydb, fp, SYM_TYPES, i, ""); 3466cd6a6acSopenharmony_ci } 3476cd6a6acSopenharmony_ci } else if (type->primary) { 3486cd6a6acSopenharmony_ci fprintf(fp, "type"); 3496cd6a6acSopenharmony_ci } else { 3506cd6a6acSopenharmony_ci fprintf(fp, "alias for type"); 3516cd6a6acSopenharmony_ci display_id(&policydb, fp, SYM_TYPES, type->s.value - 1, ""); 3526cd6a6acSopenharmony_ci } 3536cd6a6acSopenharmony_ci fprintf(fp, " flags:%x\n", type->flags); 3546cd6a6acSopenharmony_ci 3556cd6a6acSopenharmony_ci return 0; 3566cd6a6acSopenharmony_ci} 3576cd6a6acSopenharmony_ci 3586cd6a6acSopenharmony_cistatic int display_types(policydb_t * p, FILE * fp) 3596cd6a6acSopenharmony_ci{ 3606cd6a6acSopenharmony_ci if (hashtab_map(p->p_types.table, display_type_callback, fp)) 3616cd6a6acSopenharmony_ci return -1; 3626cd6a6acSopenharmony_ci return 0; 3636cd6a6acSopenharmony_ci} 3646cd6a6acSopenharmony_ci 3656cd6a6acSopenharmony_cistatic int display_users(policydb_t * p, FILE * fp) 3666cd6a6acSopenharmony_ci{ 3676cd6a6acSopenharmony_ci unsigned int i, j; 3686cd6a6acSopenharmony_ci ebitmap_t *bitmap; 3696cd6a6acSopenharmony_ci for (i = 0; i < p->p_users.nprim; i++) { 3706cd6a6acSopenharmony_ci display_id(p, fp, SYM_USERS, i, ""); 3716cd6a6acSopenharmony_ci fprintf(fp, ":"); 3726cd6a6acSopenharmony_ci bitmap = &(p->user_val_to_struct[i]->roles.roles); 3736cd6a6acSopenharmony_ci for (j = ebitmap_startbit(bitmap); j < ebitmap_length(bitmap); 3746cd6a6acSopenharmony_ci j++) { 3756cd6a6acSopenharmony_ci if (ebitmap_get_bit(bitmap, j)) { 3766cd6a6acSopenharmony_ci display_id(p, fp, SYM_ROLES, j, ""); 3776cd6a6acSopenharmony_ci } 3786cd6a6acSopenharmony_ci } 3796cd6a6acSopenharmony_ci fprintf(fp, "\n"); 3806cd6a6acSopenharmony_ci } 3816cd6a6acSopenharmony_ci return 0; 3826cd6a6acSopenharmony_ci} 3836cd6a6acSopenharmony_ci 3846cd6a6acSopenharmony_cistatic int display_bools(policydb_t * p, FILE * fp) 3856cd6a6acSopenharmony_ci{ 3866cd6a6acSopenharmony_ci unsigned int i; 3876cd6a6acSopenharmony_ci 3886cd6a6acSopenharmony_ci for (i = 0; i < p->p_bools.nprim; i++) { 3896cd6a6acSopenharmony_ci display_id(p, fp, SYM_BOOLS, i, ""); 3906cd6a6acSopenharmony_ci fprintf(fp, " : %d\n", p->bool_val_to_struct[i]->state); 3916cd6a6acSopenharmony_ci } 3926cd6a6acSopenharmony_ci return 0; 3936cd6a6acSopenharmony_ci} 3946cd6a6acSopenharmony_ci 3956cd6a6acSopenharmony_cistatic void display_expr(policydb_t * p, cond_expr_t * exp, FILE * fp) 3966cd6a6acSopenharmony_ci{ 3976cd6a6acSopenharmony_ci 3986cd6a6acSopenharmony_ci cond_expr_t *cur; 3996cd6a6acSopenharmony_ci for (cur = exp; cur != NULL; cur = cur->next) { 4006cd6a6acSopenharmony_ci switch (cur->expr_type) { 4016cd6a6acSopenharmony_ci case COND_BOOL: 4026cd6a6acSopenharmony_ci fprintf(fp, "%s ", 4036cd6a6acSopenharmony_ci p->p_bool_val_to_name[cur->bool - 1]); 4046cd6a6acSopenharmony_ci break; 4056cd6a6acSopenharmony_ci case COND_NOT: 4066cd6a6acSopenharmony_ci fprintf(fp, "! "); 4076cd6a6acSopenharmony_ci break; 4086cd6a6acSopenharmony_ci case COND_OR: 4096cd6a6acSopenharmony_ci fprintf(fp, "|| "); 4106cd6a6acSopenharmony_ci break; 4116cd6a6acSopenharmony_ci case COND_AND: 4126cd6a6acSopenharmony_ci fprintf(fp, "&& "); 4136cd6a6acSopenharmony_ci break; 4146cd6a6acSopenharmony_ci case COND_XOR: 4156cd6a6acSopenharmony_ci fprintf(fp, "^ "); 4166cd6a6acSopenharmony_ci break; 4176cd6a6acSopenharmony_ci case COND_EQ: 4186cd6a6acSopenharmony_ci fprintf(fp, "== "); 4196cd6a6acSopenharmony_ci break; 4206cd6a6acSopenharmony_ci case COND_NEQ: 4216cd6a6acSopenharmony_ci fprintf(fp, "!= "); 4226cd6a6acSopenharmony_ci break; 4236cd6a6acSopenharmony_ci default: 4246cd6a6acSopenharmony_ci fprintf(fp, "error!"); 4256cd6a6acSopenharmony_ci break; 4266cd6a6acSopenharmony_ci } 4276cd6a6acSopenharmony_ci } 4286cd6a6acSopenharmony_ci} 4296cd6a6acSopenharmony_ci 4306cd6a6acSopenharmony_cistatic void display_policycon(FILE * fp) 4316cd6a6acSopenharmony_ci{ 4326cd6a6acSopenharmony_ci /* There was an attempt to implement this at one time. Look through 4336cd6a6acSopenharmony_ci * git history to find it. */ 4346cd6a6acSopenharmony_ci fprintf(fp, "Sorry, not implemented\n"); 4356cd6a6acSopenharmony_ci} 4366cd6a6acSopenharmony_ci 4376cd6a6acSopenharmony_cistatic void display_initial_sids(policydb_t * p, FILE * fp) 4386cd6a6acSopenharmony_ci{ 4396cd6a6acSopenharmony_ci ocontext_t *cur; 4406cd6a6acSopenharmony_ci char *user, *role, *type; 4416cd6a6acSopenharmony_ci 4426cd6a6acSopenharmony_ci fprintf(fp, "Initial SIDs:\n"); 4436cd6a6acSopenharmony_ci for (cur = p->ocontexts[OCON_ISID]; cur != NULL; cur = cur->next) { 4446cd6a6acSopenharmony_ci user = p->p_user_val_to_name[cur->context[0].user - 1]; 4456cd6a6acSopenharmony_ci role = p->p_role_val_to_name[cur->context[0].role - 1]; 4466cd6a6acSopenharmony_ci type = p->p_type_val_to_name[cur->context[0].type - 1]; 4476cd6a6acSopenharmony_ci fprintf(fp, "\tsid %d, context %s:%s:%s\n", 4486cd6a6acSopenharmony_ci cur->sid[0], user, role, type); 4496cd6a6acSopenharmony_ci } 4506cd6a6acSopenharmony_ci#if 0 4516cd6a6acSopenharmony_ci fprintf(fp, "Policy Initial SIDs:\n"); 4526cd6a6acSopenharmony_ci for (cur = p->ocontexts[OCON_POLICYISID]; cur != NULL; cur = cur->next) { 4536cd6a6acSopenharmony_ci user = p->p_user_val_to_name[cur->context[0].user - 1]; 4546cd6a6acSopenharmony_ci role = p->p_role_val_to_name[cur->context[0].role - 1]; 4556cd6a6acSopenharmony_ci type = p->p_type_val_to_name[cur->context[0].type - 1]; 4566cd6a6acSopenharmony_ci fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n", 4576cd6a6acSopenharmony_ci cur->u.name, cur->sid[0], user, role, type); 4586cd6a6acSopenharmony_ci } 4596cd6a6acSopenharmony_ci#endif 4606cd6a6acSopenharmony_ci} 4616cd6a6acSopenharmony_ci 4626cd6a6acSopenharmony_cistatic void display_class_set(ebitmap_t *classes, policydb_t *p, FILE *fp) 4636cd6a6acSopenharmony_ci{ 4646cd6a6acSopenharmony_ci unsigned int i, num = 0; 4656cd6a6acSopenharmony_ci 4666cd6a6acSopenharmony_ci for (i = ebitmap_startbit(classes); i < ebitmap_length(classes); i++) { 4676cd6a6acSopenharmony_ci if (!ebitmap_get_bit(classes, i)) 4686cd6a6acSopenharmony_ci continue; 4696cd6a6acSopenharmony_ci num++; 4706cd6a6acSopenharmony_ci if (num > 1) { 4716cd6a6acSopenharmony_ci fprintf(fp, "{"); 4726cd6a6acSopenharmony_ci break; 4736cd6a6acSopenharmony_ci } 4746cd6a6acSopenharmony_ci } 4756cd6a6acSopenharmony_ci 4766cd6a6acSopenharmony_ci for (i = ebitmap_startbit(classes); i < ebitmap_length(classes); i++) { 4776cd6a6acSopenharmony_ci if (ebitmap_get_bit(classes, i)) 4786cd6a6acSopenharmony_ci display_id(p, fp, SYM_CLASSES, i, ""); 4796cd6a6acSopenharmony_ci } 4806cd6a6acSopenharmony_ci 4816cd6a6acSopenharmony_ci if (num > 1) 4826cd6a6acSopenharmony_ci fprintf(fp, " }"); 4836cd6a6acSopenharmony_ci} 4846cd6a6acSopenharmony_ci 4856cd6a6acSopenharmony_cistatic void display_role_trans(role_trans_rule_t * tr, policydb_t * p, FILE * fp) 4866cd6a6acSopenharmony_ci{ 4876cd6a6acSopenharmony_ci for (; tr; tr = tr->next) { 4886cd6a6acSopenharmony_ci fprintf(fp, "role transition "); 4896cd6a6acSopenharmony_ci display_mod_role_set(&tr->roles, p, fp); 4906cd6a6acSopenharmony_ci display_type_set(&tr->types, 0, p, fp); 4916cd6a6acSopenharmony_ci fprintf(fp, " :"); 4926cd6a6acSopenharmony_ci display_class_set(&tr->classes, p, fp); 4936cd6a6acSopenharmony_ci display_id(p, fp, SYM_ROLES, tr->new_role - 1, ""); 4946cd6a6acSopenharmony_ci fprintf(fp, "\n"); 4956cd6a6acSopenharmony_ci } 4966cd6a6acSopenharmony_ci} 4976cd6a6acSopenharmony_ci 4986cd6a6acSopenharmony_cistatic void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp) 4996cd6a6acSopenharmony_ci{ 5006cd6a6acSopenharmony_ci for (; ra; ra = ra->next) { 5016cd6a6acSopenharmony_ci fprintf(fp, "role allow "); 5026cd6a6acSopenharmony_ci display_mod_role_set(&ra->roles, p, fp); 5036cd6a6acSopenharmony_ci display_mod_role_set(&ra->new_roles, p, fp); 5046cd6a6acSopenharmony_ci fprintf(fp, "\n"); 5056cd6a6acSopenharmony_ci } 5066cd6a6acSopenharmony_ci} 5076cd6a6acSopenharmony_ci 5086cd6a6acSopenharmony_cistatic void display_filename_trans(filename_trans_rule_t * tr, policydb_t * p, FILE * fp) 5096cd6a6acSopenharmony_ci{ 5106cd6a6acSopenharmony_ci fprintf(fp, "filename transition"); 5116cd6a6acSopenharmony_ci for (; tr; tr = tr->next) { 5126cd6a6acSopenharmony_ci display_type_set(&tr->stypes, 0, p, fp); 5136cd6a6acSopenharmony_ci display_type_set(&tr->ttypes, 0, p, fp); 5146cd6a6acSopenharmony_ci display_id(p, fp, SYM_CLASSES, tr->tclass - 1, ":"); 5156cd6a6acSopenharmony_ci display_id(p, fp, SYM_TYPES, tr->otype - 1, ""); 5166cd6a6acSopenharmony_ci fprintf(fp, " %s\n", tr->name); 5176cd6a6acSopenharmony_ci } 5186cd6a6acSopenharmony_ci} 5196cd6a6acSopenharmony_ci 5206cd6a6acSopenharmony_cistatic int role_display_callback(hashtab_key_t key __attribute__((unused)), 5216cd6a6acSopenharmony_ci hashtab_datum_t datum, void *data) 5226cd6a6acSopenharmony_ci{ 5236cd6a6acSopenharmony_ci role_datum_t *role; 5246cd6a6acSopenharmony_ci FILE *fp; 5256cd6a6acSopenharmony_ci 5266cd6a6acSopenharmony_ci role = (role_datum_t *) datum; 5276cd6a6acSopenharmony_ci fp = (FILE *) data; 5286cd6a6acSopenharmony_ci 5296cd6a6acSopenharmony_ci fprintf(fp, "role:"); 5306cd6a6acSopenharmony_ci display_id(&policydb, fp, SYM_ROLES, role->s.value - 1, ""); 5316cd6a6acSopenharmony_ci fprintf(fp, " types: "); 5326cd6a6acSopenharmony_ci display_type_set(&role->types, 0, &policydb, fp); 5336cd6a6acSopenharmony_ci fprintf(fp, "\n"); 5346cd6a6acSopenharmony_ci 5356cd6a6acSopenharmony_ci return 0; 5366cd6a6acSopenharmony_ci} 5376cd6a6acSopenharmony_ci 5386cd6a6acSopenharmony_cistatic int display_scope_index(scope_index_t * indices, policydb_t * p, 5396cd6a6acSopenharmony_ci FILE * out_fp) 5406cd6a6acSopenharmony_ci{ 5416cd6a6acSopenharmony_ci unsigned int i; 5426cd6a6acSopenharmony_ci for (i = 0; i < SYM_NUM; i++) { 5436cd6a6acSopenharmony_ci unsigned int any_found = 0, j; 5446cd6a6acSopenharmony_ci fprintf(out_fp, "%s:", symbol_labels[i]); 5456cd6a6acSopenharmony_ci for (j = ebitmap_startbit(&indices->scope[i]); 5466cd6a6acSopenharmony_ci j < ebitmap_length(&indices->scope[i]); j++) { 5476cd6a6acSopenharmony_ci if (ebitmap_get_bit(&indices->scope[i], j)) { 5486cd6a6acSopenharmony_ci any_found = 1; 5496cd6a6acSopenharmony_ci fprintf(out_fp, " %s", 5506cd6a6acSopenharmony_ci p->sym_val_to_name[i][j]); 5516cd6a6acSopenharmony_ci if (i == SYM_CLASSES) { 5526cd6a6acSopenharmony_ci if (j < indices->class_perms_len) { 5536cd6a6acSopenharmony_ci render_access_bitmap(indices-> 5546cd6a6acSopenharmony_ci class_perms_map 5556cd6a6acSopenharmony_ci + j, j + 1, 5566cd6a6acSopenharmony_ci p, out_fp); 5576cd6a6acSopenharmony_ci } else { 5586cd6a6acSopenharmony_ci fprintf(out_fp, 5596cd6a6acSopenharmony_ci "<no perms known>"); 5606cd6a6acSopenharmony_ci } 5616cd6a6acSopenharmony_ci } 5626cd6a6acSopenharmony_ci } 5636cd6a6acSopenharmony_ci } 5646cd6a6acSopenharmony_ci if (!any_found) { 5656cd6a6acSopenharmony_ci fprintf(out_fp, " <empty>"); 5666cd6a6acSopenharmony_ci } 5676cd6a6acSopenharmony_ci fprintf(out_fp, "\n"); 5686cd6a6acSopenharmony_ci } 5696cd6a6acSopenharmony_ci return 0; 5706cd6a6acSopenharmony_ci} 5716cd6a6acSopenharmony_ci 5726cd6a6acSopenharmony_ci#if 0 5736cd6a6acSopenharmony_ciint display_cond_expressions(policydb_t * p, FILE * fp) 5746cd6a6acSopenharmony_ci{ 5756cd6a6acSopenharmony_ci cond_node_t *cur; 5766cd6a6acSopenharmony_ci cond_av_list_t *av_cur; 5776cd6a6acSopenharmony_ci for (cur = p->cond_list; cur != NULL; cur = cur->next) { 5786cd6a6acSopenharmony_ci fprintf(fp, "expression: "); 5796cd6a6acSopenharmony_ci display_expr(p, cur->expr, fp); 5806cd6a6acSopenharmony_ci fprintf(fp, "current state: %d\n", cur->cur_state); 5816cd6a6acSopenharmony_ci fprintf(fp, "True list:\n"); 5826cd6a6acSopenharmony_ci for (av_cur = cur->true_list; av_cur != NULL; 5836cd6a6acSopenharmony_ci av_cur = av_cur->next) { 5846cd6a6acSopenharmony_ci fprintf(fp, "\t"); 5856cd6a6acSopenharmony_ci render_av_rule(&av_cur->node->key, &av_cur->node->datum, 5866cd6a6acSopenharmony_ci RENDER_CONDITIONAL, p, fp); 5876cd6a6acSopenharmony_ci } 5886cd6a6acSopenharmony_ci fprintf(fp, "False list:\n"); 5896cd6a6acSopenharmony_ci for (av_cur = cur->false_list; av_cur != NULL; 5906cd6a6acSopenharmony_ci av_cur = av_cur->next) { 5916cd6a6acSopenharmony_ci fprintf(fp, "\t"); 5926cd6a6acSopenharmony_ci render_av_rule(&av_cur->node->key, &av_cur->node->datum, 5936cd6a6acSopenharmony_ci RENDER_CONDITIONAL, p, fp); 5946cd6a6acSopenharmony_ci } 5956cd6a6acSopenharmony_ci } 5966cd6a6acSopenharmony_ci return 0; 5976cd6a6acSopenharmony_ci} 5986cd6a6acSopenharmony_ci 5996cd6a6acSopenharmony_ciint change_bool(char *name, int state, policydb_t * p, FILE * fp) 6006cd6a6acSopenharmony_ci{ 6016cd6a6acSopenharmony_ci cond_bool_datum_t *bool; 6026cd6a6acSopenharmony_ci 6036cd6a6acSopenharmony_ci bool = hashtab_search(p->p_bools.table, name); 6046cd6a6acSopenharmony_ci if (bool == NULL) { 6056cd6a6acSopenharmony_ci fprintf(fp, "Could not find bool %s\n", name); 6066cd6a6acSopenharmony_ci return -1; 6076cd6a6acSopenharmony_ci } 6086cd6a6acSopenharmony_ci bool->state = state; 6096cd6a6acSopenharmony_ci evaluate_conds(p); 6106cd6a6acSopenharmony_ci return 0; 6116cd6a6acSopenharmony_ci} 6126cd6a6acSopenharmony_ci#endif 6136cd6a6acSopenharmony_ci 6146cd6a6acSopenharmony_cistatic int display_avdecl(avrule_decl_t * decl, int field, 6156cd6a6acSopenharmony_ci policydb_t * policy, FILE * out_fp) 6166cd6a6acSopenharmony_ci{ 6176cd6a6acSopenharmony_ci fprintf(out_fp, "decl %u:%s\n", decl->decl_id, 6186cd6a6acSopenharmony_ci (decl->enabled ? " [enabled]" : "")); 6196cd6a6acSopenharmony_ci switch (field) { 6206cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_COND_AVTAB:{ 6216cd6a6acSopenharmony_ci cond_list_t *cond = decl->cond_list; 6226cd6a6acSopenharmony_ci avrule_t *avrule; 6236cd6a6acSopenharmony_ci while (cond) { 6246cd6a6acSopenharmony_ci fprintf(out_fp, "expression: "); 6256cd6a6acSopenharmony_ci display_expr(&policydb, cond->expr, out_fp); 6266cd6a6acSopenharmony_ci fprintf(out_fp, "current state: %d\n", 6276cd6a6acSopenharmony_ci cond->cur_state); 6286cd6a6acSopenharmony_ci fprintf(out_fp, "True list:\n"); 6296cd6a6acSopenharmony_ci avrule = cond->avtrue_list; 6306cd6a6acSopenharmony_ci while (avrule) { 6316cd6a6acSopenharmony_ci display_avrule(avrule, 6326cd6a6acSopenharmony_ci &policydb, out_fp); 6336cd6a6acSopenharmony_ci avrule = avrule->next; 6346cd6a6acSopenharmony_ci } 6356cd6a6acSopenharmony_ci fprintf(out_fp, "False list:\n"); 6366cd6a6acSopenharmony_ci avrule = cond->avfalse_list; 6376cd6a6acSopenharmony_ci while (avrule) { 6386cd6a6acSopenharmony_ci display_avrule(avrule, 6396cd6a6acSopenharmony_ci &policydb, out_fp); 6406cd6a6acSopenharmony_ci avrule = avrule->next; 6416cd6a6acSopenharmony_ci } 6426cd6a6acSopenharmony_ci cond = cond->next; 6436cd6a6acSopenharmony_ci } 6446cd6a6acSopenharmony_ci break; 6456cd6a6acSopenharmony_ci } 6466cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_UNCOND_AVTAB:{ 6476cd6a6acSopenharmony_ci avrule_t *avrule = decl->avrules; 6486cd6a6acSopenharmony_ci if (avrule == NULL) { 6496cd6a6acSopenharmony_ci fprintf(out_fp, " <empty>\n"); 6506cd6a6acSopenharmony_ci } 6516cd6a6acSopenharmony_ci while (avrule != NULL) { 6526cd6a6acSopenharmony_ci if (display_avrule(avrule, policy, out_fp)) 6536cd6a6acSopenharmony_ci return -1; 6546cd6a6acSopenharmony_ci avrule = avrule->next; 6556cd6a6acSopenharmony_ci } 6566cd6a6acSopenharmony_ci break; 6576cd6a6acSopenharmony_ci } 6586cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_ROLE_TYPE_NODE:{ /* role_type_node */ 6596cd6a6acSopenharmony_ci break; 6606cd6a6acSopenharmony_ci } 6616cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_ROLE_TRANS:{ 6626cd6a6acSopenharmony_ci display_role_trans(decl->role_tr_rules, policy, out_fp); 6636cd6a6acSopenharmony_ci break; 6646cd6a6acSopenharmony_ci } 6656cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_ROLE_ALLOW:{ 6666cd6a6acSopenharmony_ci display_role_allow(decl->role_allow_rules, policy, 6676cd6a6acSopenharmony_ci out_fp); 6686cd6a6acSopenharmony_ci break; 6696cd6a6acSopenharmony_ci } 6706cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_REQUIRES:{ 6716cd6a6acSopenharmony_ci if (display_scope_index 6726cd6a6acSopenharmony_ci (&decl->required, policy, out_fp)) { 6736cd6a6acSopenharmony_ci return -1; 6746cd6a6acSopenharmony_ci } 6756cd6a6acSopenharmony_ci break; 6766cd6a6acSopenharmony_ci } 6776cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_DECLARES:{ 6786cd6a6acSopenharmony_ci if (display_scope_index 6796cd6a6acSopenharmony_ci (&decl->declared, policy, out_fp)) { 6806cd6a6acSopenharmony_ci return -1; 6816cd6a6acSopenharmony_ci } 6826cd6a6acSopenharmony_ci break; 6836cd6a6acSopenharmony_ci } 6846cd6a6acSopenharmony_ci case DISPLAY_AVBLOCK_FILENAME_TRANS: 6856cd6a6acSopenharmony_ci display_filename_trans(decl->filename_trans_rules, policy, 6866cd6a6acSopenharmony_ci out_fp); 6876cd6a6acSopenharmony_ci break; 6886cd6a6acSopenharmony_ci default:{ 6896cd6a6acSopenharmony_ci assert(0); 6906cd6a6acSopenharmony_ci } 6916cd6a6acSopenharmony_ci } 6926cd6a6acSopenharmony_ci return 0; /* should never get here */ 6936cd6a6acSopenharmony_ci} 6946cd6a6acSopenharmony_ci 6956cd6a6acSopenharmony_cistatic int display_avblock(int field, policydb_t * policy, 6966cd6a6acSopenharmony_ci FILE * out_fp) 6976cd6a6acSopenharmony_ci{ 6986cd6a6acSopenharmony_ci avrule_block_t *block = policydb.global; 6996cd6a6acSopenharmony_ci while (block != NULL) { 7006cd6a6acSopenharmony_ci avrule_decl_t *decl = block->branch_list; 7016cd6a6acSopenharmony_ci fprintf(out_fp, "--- begin avrule block ---\n"); 7026cd6a6acSopenharmony_ci while (decl != NULL) { 7036cd6a6acSopenharmony_ci if (display_avdecl(decl, field, policy, out_fp)) { 7046cd6a6acSopenharmony_ci return -1; 7056cd6a6acSopenharmony_ci } 7066cd6a6acSopenharmony_ci decl = decl->next; 7076cd6a6acSopenharmony_ci } 7086cd6a6acSopenharmony_ci block = block->next; 7096cd6a6acSopenharmony_ci } 7106cd6a6acSopenharmony_ci return 0; 7116cd6a6acSopenharmony_ci} 7126cd6a6acSopenharmony_ci 7136cd6a6acSopenharmony_cistatic int display_handle_unknown(policydb_t * p, FILE * out_fp) 7146cd6a6acSopenharmony_ci{ 7156cd6a6acSopenharmony_ci if (p->handle_unknown == ALLOW_UNKNOWN) 7166cd6a6acSopenharmony_ci fprintf(out_fp, "Allow unknown classes and perms\n"); 7176cd6a6acSopenharmony_ci else if (p->handle_unknown == DENY_UNKNOWN) 7186cd6a6acSopenharmony_ci fprintf(out_fp, "Deny unknown classes and perms\n"); 7196cd6a6acSopenharmony_ci else if (p->handle_unknown == REJECT_UNKNOWN) 7206cd6a6acSopenharmony_ci fprintf(out_fp, "Reject unknown classes and perms\n"); 7216cd6a6acSopenharmony_ci return 0; 7226cd6a6acSopenharmony_ci} 7236cd6a6acSopenharmony_ci 7246cd6a6acSopenharmony_cistatic int read_policy(char *filename, policydb_t * policy) 7256cd6a6acSopenharmony_ci{ 7266cd6a6acSopenharmony_ci FILE *in_fp; 7276cd6a6acSopenharmony_ci struct policy_file f; 7286cd6a6acSopenharmony_ci int retval; 7296cd6a6acSopenharmony_ci uint32_t buf[1]; 7306cd6a6acSopenharmony_ci 7316cd6a6acSopenharmony_ci if ((in_fp = fopen(filename, "rb")) == NULL) { 7326cd6a6acSopenharmony_ci fprintf(stderr, "Can't open '%s': %s\n", 7336cd6a6acSopenharmony_ci filename, strerror(errno)); 7346cd6a6acSopenharmony_ci exit(1); 7356cd6a6acSopenharmony_ci } 7366cd6a6acSopenharmony_ci policy_file_init(&f); 7376cd6a6acSopenharmony_ci f.type = PF_USE_STDIO; 7386cd6a6acSopenharmony_ci f.fp = in_fp; 7396cd6a6acSopenharmony_ci 7406cd6a6acSopenharmony_ci /* peek at the first byte. if they are indicative of a 7416cd6a6acSopenharmony_ci package use the package reader, otherwise use the normal 7426cd6a6acSopenharmony_ci policy reader */ 7436cd6a6acSopenharmony_ci if (fread(buf, sizeof(uint32_t), 1, in_fp) != 1) { 7446cd6a6acSopenharmony_ci fprintf(stderr, "Could not read from policy.\n"); 7456cd6a6acSopenharmony_ci exit(1); 7466cd6a6acSopenharmony_ci } 7476cd6a6acSopenharmony_ci rewind(in_fp); 7486cd6a6acSopenharmony_ci if (le32_to_cpu(buf[0]) == SEPOL_MODULE_PACKAGE_MAGIC) { 7496cd6a6acSopenharmony_ci sepol_module_package_t *package; 7506cd6a6acSopenharmony_ci if (sepol_module_package_create(&package)) { 7516cd6a6acSopenharmony_ci fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__); 7526cd6a6acSopenharmony_ci exit(1); 7536cd6a6acSopenharmony_ci } 7546cd6a6acSopenharmony_ci sepol_policydb_free(package->policy); 7556cd6a6acSopenharmony_ci package->policy = (sepol_policydb_t *) policy; 7566cd6a6acSopenharmony_ci package->file_contexts = NULL; 7576cd6a6acSopenharmony_ci retval = 7586cd6a6acSopenharmony_ci sepol_module_package_read(package, 7596cd6a6acSopenharmony_ci (sepol_policy_file_t *) & f, 1); 7606cd6a6acSopenharmony_ci package->policy = NULL; 7616cd6a6acSopenharmony_ci sepol_module_package_free(package); 7626cd6a6acSopenharmony_ci } else { 7636cd6a6acSopenharmony_ci if (policydb_init(policy)) { 7646cd6a6acSopenharmony_ci fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__); 7656cd6a6acSopenharmony_ci exit(1); 7666cd6a6acSopenharmony_ci } 7676cd6a6acSopenharmony_ci retval = policydb_read(policy, &f, 1); 7686cd6a6acSopenharmony_ci } 7696cd6a6acSopenharmony_ci fclose(in_fp); 7706cd6a6acSopenharmony_ci return retval; 7716cd6a6acSopenharmony_ci} 7726cd6a6acSopenharmony_ci 7736cd6a6acSopenharmony_cistatic void link_module(policydb_t * base, FILE * out_fp) 7746cd6a6acSopenharmony_ci{ 7756cd6a6acSopenharmony_ci char module_name[80] = { 0 }; 7766cd6a6acSopenharmony_ci int ret; 7776cd6a6acSopenharmony_ci policydb_t module, *mods = &module; 7786cd6a6acSopenharmony_ci 7796cd6a6acSopenharmony_ci if (base->policy_type != POLICY_BASE) { 7806cd6a6acSopenharmony_ci printf("Can only link if initial file was a base policy.\n"); 7816cd6a6acSopenharmony_ci return; 7826cd6a6acSopenharmony_ci } 7836cd6a6acSopenharmony_ci printf("\nModule filename: "); 7846cd6a6acSopenharmony_ci if (fgets(module_name, sizeof(module_name), stdin) == NULL) { 7856cd6a6acSopenharmony_ci fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, 7866cd6a6acSopenharmony_ci strerror(errno)); 7876cd6a6acSopenharmony_ci exit(1); 7886cd6a6acSopenharmony_ci } 7896cd6a6acSopenharmony_ci 7906cd6a6acSopenharmony_ci module_name[strlen(module_name) - 1] = '\0'; /* remove LF */ 7916cd6a6acSopenharmony_ci if (module_name[0] == '\0') { 7926cd6a6acSopenharmony_ci return; 7936cd6a6acSopenharmony_ci } 7946cd6a6acSopenharmony_ci 7956cd6a6acSopenharmony_ci /* read the binary policy */ 7966cd6a6acSopenharmony_ci fprintf(out_fp, "Reading module...\n"); 7976cd6a6acSopenharmony_ci if (read_policy(module_name, mods)) { 7986cd6a6acSopenharmony_ci fprintf(stderr, 7996cd6a6acSopenharmony_ci "%s: error(s) encountered while loading policy\n", 8006cd6a6acSopenharmony_ci module_name); 8016cd6a6acSopenharmony_ci exit(1); 8026cd6a6acSopenharmony_ci } 8036cd6a6acSopenharmony_ci if (module.policy_type != POLICY_MOD) { 8046cd6a6acSopenharmony_ci fprintf(stderr, "This file is not a loadable policy module.\n"); 8056cd6a6acSopenharmony_ci exit(1); 8066cd6a6acSopenharmony_ci } 8076cd6a6acSopenharmony_ci if (policydb_index_classes(&module) || 8086cd6a6acSopenharmony_ci policydb_index_others(NULL, &module, 0)) { 8096cd6a6acSopenharmony_ci fprintf(stderr, "Could not index module.\n"); 8106cd6a6acSopenharmony_ci exit(1); 8116cd6a6acSopenharmony_ci } 8126cd6a6acSopenharmony_ci ret = link_modules(NULL, base, &mods, 1, 0); 8136cd6a6acSopenharmony_ci if (ret != 0) { 8146cd6a6acSopenharmony_ci printf("Link failed (error %d)\n", ret); 8156cd6a6acSopenharmony_ci printf("(You will probably need to restart dismod.)\n"); 8166cd6a6acSopenharmony_ci } 8176cd6a6acSopenharmony_ci policydb_destroy(&module); 8186cd6a6acSopenharmony_ci return; 8196cd6a6acSopenharmony_ci} 8206cd6a6acSopenharmony_ci 8216cd6a6acSopenharmony_cistatic void display_policycaps(policydb_t * p, FILE * fp) 8226cd6a6acSopenharmony_ci{ 8236cd6a6acSopenharmony_ci ebitmap_node_t *node; 8246cd6a6acSopenharmony_ci const char *capname; 8256cd6a6acSopenharmony_ci char buf[64]; 8266cd6a6acSopenharmony_ci unsigned int i; 8276cd6a6acSopenharmony_ci 8286cd6a6acSopenharmony_ci fprintf(fp, "policy capabilities:\n"); 8296cd6a6acSopenharmony_ci ebitmap_for_each_positive_bit(&p->policycaps, node, i) { 8306cd6a6acSopenharmony_ci capname = sepol_polcap_getname(i); 8316cd6a6acSopenharmony_ci if (capname == NULL) { 8326cd6a6acSopenharmony_ci snprintf(buf, sizeof(buf), "unknown (%u)", i); 8336cd6a6acSopenharmony_ci capname = buf; 8346cd6a6acSopenharmony_ci } 8356cd6a6acSopenharmony_ci fprintf(fp, "\t%s\n", capname); 8366cd6a6acSopenharmony_ci } 8376cd6a6acSopenharmony_ci} 8386cd6a6acSopenharmony_ci 8396cd6a6acSopenharmony_cistatic int menu(void) 8406cd6a6acSopenharmony_ci{ 8416cd6a6acSopenharmony_ci printf("\nSelect a command:\n"); 8426cd6a6acSopenharmony_ci printf("1) display unconditional AVTAB\n"); 8436cd6a6acSopenharmony_ci printf("2) display conditional AVTAB\n"); 8446cd6a6acSopenharmony_ci printf("3) display users\n"); 8456cd6a6acSopenharmony_ci printf("4) display bools\n"); 8466cd6a6acSopenharmony_ci printf("5) display roles\n"); 8476cd6a6acSopenharmony_ci printf("6) display types, attributes, and aliases\n"); 8486cd6a6acSopenharmony_ci printf("7) display role transitions\n"); 8496cd6a6acSopenharmony_ci printf("8) display role allows\n"); 8506cd6a6acSopenharmony_ci printf("9) Display policycon\n"); 8516cd6a6acSopenharmony_ci printf("0) Display initial SIDs\n"); 8526cd6a6acSopenharmony_ci printf("\n"); 8536cd6a6acSopenharmony_ci printf("a) Display avrule requirements\n"); 8546cd6a6acSopenharmony_ci printf("b) Display avrule declarations\n"); 8556cd6a6acSopenharmony_ci printf("c) Display policy capabilities\n"); 8566cd6a6acSopenharmony_ci printf("l) Link in a module\n"); 8576cd6a6acSopenharmony_ci printf("u) Display the unknown handling setting\n"); 8586cd6a6acSopenharmony_ci printf("F) Display filename_trans rules\n"); 8596cd6a6acSopenharmony_ci printf("\n"); 8606cd6a6acSopenharmony_ci printf("f) set output file\n"); 8616cd6a6acSopenharmony_ci printf("m) display menu\n"); 8626cd6a6acSopenharmony_ci printf("q) quit\n"); 8636cd6a6acSopenharmony_ci return 0; 8646cd6a6acSopenharmony_ci} 8656cd6a6acSopenharmony_ci 8666cd6a6acSopenharmony_ciint main(int argc, char **argv) 8676cd6a6acSopenharmony_ci{ 8686cd6a6acSopenharmony_ci FILE *out_fp = stdout; 8696cd6a6acSopenharmony_ci char ans[81], OutfileName[121]; 8706cd6a6acSopenharmony_ci 8716cd6a6acSopenharmony_ci if (argc != 2) 8726cd6a6acSopenharmony_ci usage(argv[0]); 8736cd6a6acSopenharmony_ci 8746cd6a6acSopenharmony_ci /* read the binary policy */ 8756cd6a6acSopenharmony_ci fprintf(out_fp, "Reading policy...\n"); 8766cd6a6acSopenharmony_ci if (policydb_init(&policydb)) { 8776cd6a6acSopenharmony_ci fprintf(stderr, "%s: Out of memory!\n", __FUNCTION__); 8786cd6a6acSopenharmony_ci exit(1); 8796cd6a6acSopenharmony_ci } 8806cd6a6acSopenharmony_ci if (read_policy(argv[1], &policydb)) { 8816cd6a6acSopenharmony_ci fprintf(stderr, 8826cd6a6acSopenharmony_ci "%s: error(s) encountered while loading policy\n", 8836cd6a6acSopenharmony_ci argv[0]); 8846cd6a6acSopenharmony_ci exit(1); 8856cd6a6acSopenharmony_ci } 8866cd6a6acSopenharmony_ci 8876cd6a6acSopenharmony_ci if (policydb.policy_type != POLICY_BASE && 8886cd6a6acSopenharmony_ci policydb.policy_type != POLICY_MOD) { 8896cd6a6acSopenharmony_ci fprintf(stderr, 8906cd6a6acSopenharmony_ci "This file is neither a base nor loadable policy module.\n"); 8916cd6a6acSopenharmony_ci exit(1); 8926cd6a6acSopenharmony_ci } 8936cd6a6acSopenharmony_ci 8946cd6a6acSopenharmony_ci if (policydb_index_classes(&policydb)) { 8956cd6a6acSopenharmony_ci fprintf(stderr, "Error indexing classes\n"); 8966cd6a6acSopenharmony_ci exit(1); 8976cd6a6acSopenharmony_ci } 8986cd6a6acSopenharmony_ci 8996cd6a6acSopenharmony_ci if (policydb_index_others(NULL, &policydb, 1)) { 9006cd6a6acSopenharmony_ci fprintf(stderr, "Error indexing others\n"); 9016cd6a6acSopenharmony_ci exit(1); 9026cd6a6acSopenharmony_ci } 9036cd6a6acSopenharmony_ci 9046cd6a6acSopenharmony_ci if (policydb.policy_type == POLICY_BASE) { 9056cd6a6acSopenharmony_ci printf("Binary base policy file loaded.\n"); 9066cd6a6acSopenharmony_ci } else { 9076cd6a6acSopenharmony_ci printf("Binary policy module file loaded.\n"); 9086cd6a6acSopenharmony_ci printf("Module name: %s\n", policydb.name); 9096cd6a6acSopenharmony_ci printf("Module version: %s\n", policydb.version); 9106cd6a6acSopenharmony_ci } 9116cd6a6acSopenharmony_ci 9126cd6a6acSopenharmony_ci printf("Policy version: %d\n\n", policydb.policyvers); 9136cd6a6acSopenharmony_ci menu(); 9146cd6a6acSopenharmony_ci for (;;) { 9156cd6a6acSopenharmony_ci printf("\nCommand (\'m\' for menu): "); 9166cd6a6acSopenharmony_ci if (fgets(ans, sizeof(ans), stdin) == NULL) { 9176cd6a6acSopenharmony_ci fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, 9186cd6a6acSopenharmony_ci strerror(errno)); 9196cd6a6acSopenharmony_ci continue; 9206cd6a6acSopenharmony_ci } 9216cd6a6acSopenharmony_ci 9226cd6a6acSopenharmony_ci switch (ans[0]) { 9236cd6a6acSopenharmony_ci 9246cd6a6acSopenharmony_ci case '1': 9256cd6a6acSopenharmony_ci fprintf(out_fp, "unconditional avtab:\n"); 9266cd6a6acSopenharmony_ci display_avblock(DISPLAY_AVBLOCK_UNCOND_AVTAB, 9276cd6a6acSopenharmony_ci &policydb, out_fp); 9286cd6a6acSopenharmony_ci break; 9296cd6a6acSopenharmony_ci case '2': 9306cd6a6acSopenharmony_ci fprintf(out_fp, "conditional avtab:\n"); 9316cd6a6acSopenharmony_ci display_avblock(DISPLAY_AVBLOCK_COND_AVTAB, 9326cd6a6acSopenharmony_ci &policydb, out_fp); 9336cd6a6acSopenharmony_ci break; 9346cd6a6acSopenharmony_ci case '3': 9356cd6a6acSopenharmony_ci display_users(&policydb, out_fp); 9366cd6a6acSopenharmony_ci break; 9376cd6a6acSopenharmony_ci case '4': 9386cd6a6acSopenharmony_ci display_bools(&policydb, out_fp); 9396cd6a6acSopenharmony_ci break; 9406cd6a6acSopenharmony_ci case '5': 9416cd6a6acSopenharmony_ci if (hashtab_map 9426cd6a6acSopenharmony_ci (policydb.p_roles.table, role_display_callback, 9436cd6a6acSopenharmony_ci out_fp)) 9446cd6a6acSopenharmony_ci exit(1); 9456cd6a6acSopenharmony_ci break; 9466cd6a6acSopenharmony_ci case '6': 9476cd6a6acSopenharmony_ci if (display_types(&policydb, out_fp)) { 9486cd6a6acSopenharmony_ci fprintf(stderr, "Error displaying types\n"); 9496cd6a6acSopenharmony_ci exit(1); 9506cd6a6acSopenharmony_ci } 9516cd6a6acSopenharmony_ci break; 9526cd6a6acSopenharmony_ci case '7': 9536cd6a6acSopenharmony_ci fprintf(out_fp, "role transitions:\n"); 9546cd6a6acSopenharmony_ci display_avblock(DISPLAY_AVBLOCK_ROLE_TRANS, 9556cd6a6acSopenharmony_ci &policydb, out_fp); 9566cd6a6acSopenharmony_ci break; 9576cd6a6acSopenharmony_ci case '8': 9586cd6a6acSopenharmony_ci fprintf(out_fp, "role allows:\n"); 9596cd6a6acSopenharmony_ci display_avblock(DISPLAY_AVBLOCK_ROLE_ALLOW, 9606cd6a6acSopenharmony_ci &policydb, out_fp); 9616cd6a6acSopenharmony_ci break; 9626cd6a6acSopenharmony_ci case '9': 9636cd6a6acSopenharmony_ci display_policycon(out_fp); 9646cd6a6acSopenharmony_ci break; 9656cd6a6acSopenharmony_ci case '0': 9666cd6a6acSopenharmony_ci display_initial_sids(&policydb, out_fp); 9676cd6a6acSopenharmony_ci break; 9686cd6a6acSopenharmony_ci case 'a': 9696cd6a6acSopenharmony_ci fprintf(out_fp, "avrule block requirements:\n"); 9706cd6a6acSopenharmony_ci display_avblock(DISPLAY_AVBLOCK_REQUIRES, 9716cd6a6acSopenharmony_ci &policydb, out_fp); 9726cd6a6acSopenharmony_ci break; 9736cd6a6acSopenharmony_ci case 'b': 9746cd6a6acSopenharmony_ci fprintf(out_fp, "avrule block declarations:\n"); 9756cd6a6acSopenharmony_ci display_avblock(DISPLAY_AVBLOCK_DECLARES, 9766cd6a6acSopenharmony_ci &policydb, out_fp); 9776cd6a6acSopenharmony_ci break; 9786cd6a6acSopenharmony_ci case 'c': 9796cd6a6acSopenharmony_ci display_policycaps(&policydb, out_fp); 9806cd6a6acSopenharmony_ci break; 9816cd6a6acSopenharmony_ci case 'u': 9826cd6a6acSopenharmony_ci case 'U': 9836cd6a6acSopenharmony_ci display_handle_unknown(&policydb, out_fp); 9846cd6a6acSopenharmony_ci break; 9856cd6a6acSopenharmony_ci case 'f': 9866cd6a6acSopenharmony_ci printf 9876cd6a6acSopenharmony_ci ("\nFilename for output (<CR> for screen output): "); 9886cd6a6acSopenharmony_ci if (fgets(OutfileName, sizeof(OutfileName), stdin) == NULL) { 9896cd6a6acSopenharmony_ci fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, 9906cd6a6acSopenharmony_ci strerror(errno)); 9916cd6a6acSopenharmony_ci break; 9926cd6a6acSopenharmony_ci } 9936cd6a6acSopenharmony_ci OutfileName[strlen(OutfileName) - 1] = '\0'; /* fix_string (remove LF) */ 9946cd6a6acSopenharmony_ci if (strlen(OutfileName) == 0) 9956cd6a6acSopenharmony_ci out_fp = stdout; 9966cd6a6acSopenharmony_ci else if ((out_fp = fopen(OutfileName, "w")) == NULL) { 9976cd6a6acSopenharmony_ci fprintf(stderr, "Cannot open output file %s\n", 9986cd6a6acSopenharmony_ci OutfileName); 9996cd6a6acSopenharmony_ci out_fp = stdout; 10006cd6a6acSopenharmony_ci } 10016cd6a6acSopenharmony_ci if (out_fp != stdout) 10026cd6a6acSopenharmony_ci printf("\nOutput to file: %s\n", OutfileName); 10036cd6a6acSopenharmony_ci break; 10046cd6a6acSopenharmony_ci case 'F': 10056cd6a6acSopenharmony_ci fprintf(out_fp, "filename_trans rules:\n"); 10066cd6a6acSopenharmony_ci display_avblock(DISPLAY_AVBLOCK_FILENAME_TRANS, 10076cd6a6acSopenharmony_ci &policydb, out_fp); 10086cd6a6acSopenharmony_ci break; 10096cd6a6acSopenharmony_ci case 'l': 10106cd6a6acSopenharmony_ci link_module(&policydb, out_fp); 10116cd6a6acSopenharmony_ci break; 10126cd6a6acSopenharmony_ci case 'q': 10136cd6a6acSopenharmony_ci policydb_destroy(&policydb); 10146cd6a6acSopenharmony_ci exit(0); 10156cd6a6acSopenharmony_ci break; 10166cd6a6acSopenharmony_ci case 'm': 10176cd6a6acSopenharmony_ci menu(); 10186cd6a6acSopenharmony_ci break; 10196cd6a6acSopenharmony_ci default: 10206cd6a6acSopenharmony_ci printf("\nInvalid choice\n"); 10216cd6a6acSopenharmony_ci menu(); 10226cd6a6acSopenharmony_ci break; 10236cd6a6acSopenharmony_ci 10246cd6a6acSopenharmony_ci } 10256cd6a6acSopenharmony_ci } 10266cd6a6acSopenharmony_ci exit(EXIT_SUCCESS); 10276cd6a6acSopenharmony_ci} 1028