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