xref: /aosp_15_r20/external/selinux/python/audit2allow/sepolgen-ifgen-attr-helper.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /* Authors: Frank Mayer <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker  *   and Karl MacMillan <[email protected]>
3*2d543d20SAndroid Build Coastguard Worker  *
4*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2003,2010 Tresys Technology, LLC
5*2d543d20SAndroid Build Coastguard Worker  *
6*2d543d20SAndroid Build Coastguard Worker  *	This program is free software; you can redistribute it and/or
7*2d543d20SAndroid Build Coastguard Worker  *  	modify it under the terms of the GNU General Public License as
8*2d543d20SAndroid Build Coastguard Worker  *  	published by the Free Software Foundation, version 2.
9*2d543d20SAndroid Build Coastguard Worker  *
10*2d543d20SAndroid Build Coastguard Worker  * Adapted from dispol.c.
11*2d543d20SAndroid Build Coastguard Worker  *
12*2d543d20SAndroid Build Coastguard Worker  * This program is used by sepolgen-ifgen to get the access for all of
13*2d543d20SAndroid Build Coastguard Worker  * the attributes in the policy so that it can resolve the
14*2d543d20SAndroid Build Coastguard Worker  * typeattribute statements in the interfaces.
15*2d543d20SAndroid Build Coastguard Worker  *
16*2d543d20SAndroid Build Coastguard Worker  * It outputs the attribute access in a similar format to what sepolgen
17*2d543d20SAndroid Build Coastguard Worker  * uses to store interface vectors:
18*2d543d20SAndroid Build Coastguard Worker  *   [Attribute sandbox_x_domain]
19*2d543d20SAndroid Build Coastguard Worker  *   sandbox_x_domain,samba_var_t,file,ioctl,read,getattr,lock,open
20*2d543d20SAndroid Build Coastguard Worker  *   sandbox_x_domain,samba_var_t,dir,getattr,search,open
21*2d543d20SAndroid Build Coastguard Worker  *   sandbox_x_domain,initrc_var_run_t,file,ioctl,read,getattr,lock,open
22*2d543d20SAndroid Build Coastguard Worker  *
23*2d543d20SAndroid Build Coastguard Worker  */
24*2d543d20SAndroid Build Coastguard Worker 
25*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
26*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/avtab.h>
27*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/util.h>
28*2d543d20SAndroid Build Coastguard Worker 
29*2d543d20SAndroid Build Coastguard Worker #include <selinux/selinux.h>
30*2d543d20SAndroid Build Coastguard Worker 
31*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
32*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
33*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
34*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
35*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
36*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.h>
37*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
38*2d543d20SAndroid Build Coastguard Worker 
39*2d543d20SAndroid Build Coastguard Worker struct val_to_name {
40*2d543d20SAndroid Build Coastguard Worker 	unsigned int val;
41*2d543d20SAndroid Build Coastguard Worker 	char *name;
42*2d543d20SAndroid Build Coastguard Worker };
43*2d543d20SAndroid Build Coastguard Worker 
perm_name(hashtab_key_t key,hashtab_datum_t datum,void * data)44*2d543d20SAndroid Build Coastguard Worker static int perm_name(hashtab_key_t key, hashtab_datum_t datum, void *data)
45*2d543d20SAndroid Build Coastguard Worker {
46*2d543d20SAndroid Build Coastguard Worker 	struct val_to_name *v = data;
47*2d543d20SAndroid Build Coastguard Worker 	perm_datum_t *perdatum;
48*2d543d20SAndroid Build Coastguard Worker 
49*2d543d20SAndroid Build Coastguard Worker 	perdatum = (perm_datum_t *) datum;
50*2d543d20SAndroid Build Coastguard Worker 
51*2d543d20SAndroid Build Coastguard Worker 	if (v->val == perdatum->s.value) {
52*2d543d20SAndroid Build Coastguard Worker 		v->name = key;
53*2d543d20SAndroid Build Coastguard Worker 		return 1;
54*2d543d20SAndroid Build Coastguard Worker 	}
55*2d543d20SAndroid Build Coastguard Worker 
56*2d543d20SAndroid Build Coastguard Worker 	return 0;
57*2d543d20SAndroid Build Coastguard Worker }
58*2d543d20SAndroid Build Coastguard Worker 
render_access_mask(uint32_t av,avtab_key_t * key,policydb_t * policydbp,FILE * fp)59*2d543d20SAndroid Build Coastguard Worker static int render_access_mask(uint32_t av, avtab_key_t *key, policydb_t *policydbp,
60*2d543d20SAndroid Build Coastguard Worker 		       FILE *fp)
61*2d543d20SAndroid Build Coastguard Worker {
62*2d543d20SAndroid Build Coastguard Worker 	struct val_to_name v;
63*2d543d20SAndroid Build Coastguard Worker 	class_datum_t *cladatum;
64*2d543d20SAndroid Build Coastguard Worker 	char *perm = NULL;
65*2d543d20SAndroid Build Coastguard Worker 	unsigned int i;
66*2d543d20SAndroid Build Coastguard Worker 	int rc;
67*2d543d20SAndroid Build Coastguard Worker 	uint32_t tclass = key->target_class;
68*2d543d20SAndroid Build Coastguard Worker 
69*2d543d20SAndroid Build Coastguard Worker 	cladatum = policydbp->class_val_to_struct[tclass - 1];
70*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; i < cladatum->permissions.nprim; i++) {
71*2d543d20SAndroid Build Coastguard Worker 		if (av & (1 << i)) {
72*2d543d20SAndroid Build Coastguard Worker 			v.val = i + 1;
73*2d543d20SAndroid Build Coastguard Worker 			rc = hashtab_map(cladatum->permissions.table,
74*2d543d20SAndroid Build Coastguard Worker 					 perm_name, &v);
75*2d543d20SAndroid Build Coastguard Worker 			if (!rc && cladatum->comdatum) {
76*2d543d20SAndroid Build Coastguard Worker 				rc = hashtab_map(cladatum->comdatum->
77*2d543d20SAndroid Build Coastguard Worker 						 permissions.table, perm_name,
78*2d543d20SAndroid Build Coastguard Worker 						 &v);
79*2d543d20SAndroid Build Coastguard Worker 			}
80*2d543d20SAndroid Build Coastguard Worker 			if (rc)
81*2d543d20SAndroid Build Coastguard Worker 				perm = v.name;
82*2d543d20SAndroid Build Coastguard Worker 			if (perm) {
83*2d543d20SAndroid Build Coastguard Worker 				fprintf(fp, ",%s", perm);
84*2d543d20SAndroid Build Coastguard Worker 			}
85*2d543d20SAndroid Build Coastguard Worker 		}
86*2d543d20SAndroid Build Coastguard Worker 	}
87*2d543d20SAndroid Build Coastguard Worker 
88*2d543d20SAndroid Build Coastguard Worker 	return 0;
89*2d543d20SAndroid Build Coastguard Worker }
90*2d543d20SAndroid Build Coastguard Worker 
render_key(avtab_key_t * key,policydb_t * p,FILE * fp)91*2d543d20SAndroid Build Coastguard Worker static int render_key(avtab_key_t *key, policydb_t *p, FILE *fp)
92*2d543d20SAndroid Build Coastguard Worker {
93*2d543d20SAndroid Build Coastguard Worker 	char *stype, *ttype, *tclass;
94*2d543d20SAndroid Build Coastguard Worker 	stype = p->p_type_val_to_name[key->source_type - 1];
95*2d543d20SAndroid Build Coastguard Worker 	ttype = p->p_type_val_to_name[key->target_type - 1];
96*2d543d20SAndroid Build Coastguard Worker 	tclass = p->p_class_val_to_name[key->target_class - 1];
97*2d543d20SAndroid Build Coastguard Worker 	if (stype && ttype) {
98*2d543d20SAndroid Build Coastguard Worker 		fprintf(fp, "%s,%s,%s", stype, ttype, tclass);
99*2d543d20SAndroid Build Coastguard Worker 	} else {
100*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "error rendering key\n");
101*2d543d20SAndroid Build Coastguard Worker 		exit(1);
102*2d543d20SAndroid Build Coastguard Worker 	}
103*2d543d20SAndroid Build Coastguard Worker 
104*2d543d20SAndroid Build Coastguard Worker 	return 0;
105*2d543d20SAndroid Build Coastguard Worker }
106*2d543d20SAndroid Build Coastguard Worker 
107*2d543d20SAndroid Build Coastguard Worker struct callback_data
108*2d543d20SAndroid Build Coastguard Worker {
109*2d543d20SAndroid Build Coastguard Worker 	uint32_t attr;
110*2d543d20SAndroid Build Coastguard Worker 	policydb_t *policy;
111*2d543d20SAndroid Build Coastguard Worker 	FILE *fp;
112*2d543d20SAndroid Build Coastguard Worker };
113*2d543d20SAndroid Build Coastguard Worker 
output_avrule(avtab_key_t * key,avtab_datum_t * datum,void * args)114*2d543d20SAndroid Build Coastguard Worker static int output_avrule(avtab_key_t *key, avtab_datum_t *datum, void *args)
115*2d543d20SAndroid Build Coastguard Worker {
116*2d543d20SAndroid Build Coastguard Worker 	struct callback_data *cb_data = (struct callback_data *)args;
117*2d543d20SAndroid Build Coastguard Worker 
118*2d543d20SAndroid Build Coastguard Worker 	if (key->source_type != cb_data->attr)
119*2d543d20SAndroid Build Coastguard Worker 		return 0;
120*2d543d20SAndroid Build Coastguard Worker 
121*2d543d20SAndroid Build Coastguard Worker 	if (!(key->specified & AVTAB_AV && key->specified & AVTAB_ALLOWED))
122*2d543d20SAndroid Build Coastguard Worker 		return 0;
123*2d543d20SAndroid Build Coastguard Worker 
124*2d543d20SAndroid Build Coastguard Worker 	render_key(key, cb_data->policy, cb_data->fp);
125*2d543d20SAndroid Build Coastguard Worker 	render_access_mask(datum->data, key, cb_data->policy, cb_data->fp);
126*2d543d20SAndroid Build Coastguard Worker 	fprintf(cb_data->fp, "\n");
127*2d543d20SAndroid Build Coastguard Worker 
128*2d543d20SAndroid Build Coastguard Worker 	return 0;
129*2d543d20SAndroid Build Coastguard Worker }
130*2d543d20SAndroid Build Coastguard Worker 
attribute_callback(hashtab_key_t key,hashtab_datum_t datum,void * datap)131*2d543d20SAndroid Build Coastguard Worker static int attribute_callback(hashtab_key_t key, hashtab_datum_t datum, void *datap)
132*2d543d20SAndroid Build Coastguard Worker {
133*2d543d20SAndroid Build Coastguard Worker 	struct callback_data *cb_data = (struct callback_data *)datap;
134*2d543d20SAndroid Build Coastguard Worker 	type_datum_t *t = (type_datum_t *)datum;
135*2d543d20SAndroid Build Coastguard Worker 
136*2d543d20SAndroid Build Coastguard Worker 	if (t->flavor == TYPE_ATTRIB) {
137*2d543d20SAndroid Build Coastguard Worker 		fprintf(cb_data->fp, "[Attribute %s]\n", key);
138*2d543d20SAndroid Build Coastguard Worker 		cb_data->attr = t->s.value;
139*2d543d20SAndroid Build Coastguard Worker 		if (avtab_map(&cb_data->policy->te_avtab, output_avrule, cb_data) < 0)
140*2d543d20SAndroid Build Coastguard Worker 			return -1;
141*2d543d20SAndroid Build Coastguard Worker 		if (avtab_map(&cb_data->policy->te_cond_avtab, output_avrule, cb_data) < 0)
142*2d543d20SAndroid Build Coastguard Worker 			return -1;
143*2d543d20SAndroid Build Coastguard Worker 	}
144*2d543d20SAndroid Build Coastguard Worker 
145*2d543d20SAndroid Build Coastguard Worker 	return 0;
146*2d543d20SAndroid Build Coastguard Worker }
147*2d543d20SAndroid Build Coastguard Worker 
load_policy(const char * filename)148*2d543d20SAndroid Build Coastguard Worker static policydb_t *load_policy(const char *filename)
149*2d543d20SAndroid Build Coastguard Worker {
150*2d543d20SAndroid Build Coastguard Worker 	policydb_t *policydb;
151*2d543d20SAndroid Build Coastguard Worker 	struct policy_file pf;
152*2d543d20SAndroid Build Coastguard Worker 	FILE *fp;
153*2d543d20SAndroid Build Coastguard Worker 	char pathname[PATH_MAX];
154*2d543d20SAndroid Build Coastguard Worker 	int suffix_ver;
155*2d543d20SAndroid Build Coastguard Worker 	int ret;
156*2d543d20SAndroid Build Coastguard Worker 
157*2d543d20SAndroid Build Coastguard Worker 	/* no explicit policy name given, try loaded policy on a SELinux enabled system */
158*2d543d20SAndroid Build Coastguard Worker 	if (!filename) {
159*2d543d20SAndroid Build Coastguard Worker 		filename = selinux_current_policy_path();
160*2d543d20SAndroid Build Coastguard Worker 	}
161*2d543d20SAndroid Build Coastguard Worker 
162*2d543d20SAndroid Build Coastguard Worker 	/*
163*2d543d20SAndroid Build Coastguard Worker 	 * Fallback to default store paths with version suffixes,
164*2d543d20SAndroid Build Coastguard Worker 	 * starting from the maximum supported policy version.
165*2d543d20SAndroid Build Coastguard Worker 	 */
166*2d543d20SAndroid Build Coastguard Worker 	if (!filename) {
167*2d543d20SAndroid Build Coastguard Worker 		for (suffix_ver = sepol_policy_kern_vers_max(); suffix_ver > 0; suffix_ver--) {
168*2d543d20SAndroid Build Coastguard Worker 			snprintf(pathname, sizeof(pathname), "%s.%d", selinux_binary_policy_path(), suffix_ver);
169*2d543d20SAndroid Build Coastguard Worker 
170*2d543d20SAndroid Build Coastguard Worker 			if (access(pathname, F_OK) == 0) {
171*2d543d20SAndroid Build Coastguard Worker 				filename = pathname;
172*2d543d20SAndroid Build Coastguard Worker 				break;
173*2d543d20SAndroid Build Coastguard Worker 			}
174*2d543d20SAndroid Build Coastguard Worker 		}
175*2d543d20SAndroid Build Coastguard Worker 
176*2d543d20SAndroid Build Coastguard Worker 		if (!filename) {
177*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "Can't find any policy at '%s'\n",
178*2d543d20SAndroid Build Coastguard Worker 				selinux_binary_policy_path());
179*2d543d20SAndroid Build Coastguard Worker 			return NULL;
180*2d543d20SAndroid Build Coastguard Worker 		}
181*2d543d20SAndroid Build Coastguard Worker 	}
182*2d543d20SAndroid Build Coastguard Worker 
183*2d543d20SAndroid Build Coastguard Worker 	fp = fopen(filename, "r");
184*2d543d20SAndroid Build Coastguard Worker 	if (fp == NULL) {
185*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't open '%s':  %s\n",
186*2d543d20SAndroid Build Coastguard Worker 			filename, strerror(errno));
187*2d543d20SAndroid Build Coastguard Worker 		return NULL;
188*2d543d20SAndroid Build Coastguard Worker 	}
189*2d543d20SAndroid Build Coastguard Worker 
190*2d543d20SAndroid Build Coastguard Worker 	policy_file_init(&pf);
191*2d543d20SAndroid Build Coastguard Worker 	pf.type = PF_USE_STDIO;
192*2d543d20SAndroid Build Coastguard Worker 	pf.fp = fp;
193*2d543d20SAndroid Build Coastguard Worker 
194*2d543d20SAndroid Build Coastguard Worker 	policydb = malloc(sizeof(policydb_t));
195*2d543d20SAndroid Build Coastguard Worker 	if (policydb == NULL) {
196*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Out of memory!\n");
197*2d543d20SAndroid Build Coastguard Worker 		fclose(fp);
198*2d543d20SAndroid Build Coastguard Worker 		return NULL;
199*2d543d20SAndroid Build Coastguard Worker 	}
200*2d543d20SAndroid Build Coastguard Worker 
201*2d543d20SAndroid Build Coastguard Worker 	if (policydb_init(policydb)) {
202*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Out of memory!\n");
203*2d543d20SAndroid Build Coastguard Worker 		free(policydb);
204*2d543d20SAndroid Build Coastguard Worker 		fclose(fp);
205*2d543d20SAndroid Build Coastguard Worker 		return NULL;
206*2d543d20SAndroid Build Coastguard Worker 	}
207*2d543d20SAndroid Build Coastguard Worker 
208*2d543d20SAndroid Build Coastguard Worker 	ret = policydb_read(policydb, &pf, 1);
209*2d543d20SAndroid Build Coastguard Worker 	if (ret) {
210*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr,
211*2d543d20SAndroid Build Coastguard Worker 			"error(s) encountered while parsing configuration\n");
212*2d543d20SAndroid Build Coastguard Worker 		free(policydb);
213*2d543d20SAndroid Build Coastguard Worker 		fclose(fp);
214*2d543d20SAndroid Build Coastguard Worker 		return NULL;
215*2d543d20SAndroid Build Coastguard Worker 	}
216*2d543d20SAndroid Build Coastguard Worker 
217*2d543d20SAndroid Build Coastguard Worker 	fclose(fp);
218*2d543d20SAndroid Build Coastguard Worker 
219*2d543d20SAndroid Build Coastguard Worker 	return policydb;
220*2d543d20SAndroid Build Coastguard Worker 
221*2d543d20SAndroid Build Coastguard Worker }
222*2d543d20SAndroid Build Coastguard Worker 
usage(char * progname)223*2d543d20SAndroid Build Coastguard Worker static void usage(char *progname)
224*2d543d20SAndroid Build Coastguard Worker {
225*2d543d20SAndroid Build Coastguard Worker 	printf("usage: %s out_file [policy_file]\n", progname);
226*2d543d20SAndroid Build Coastguard Worker }
227*2d543d20SAndroid Build Coastguard Worker 
main(int argc,char ** argv)228*2d543d20SAndroid Build Coastguard Worker int main(int argc, char **argv)
229*2d543d20SAndroid Build Coastguard Worker {
230*2d543d20SAndroid Build Coastguard Worker 	policydb_t *p;
231*2d543d20SAndroid Build Coastguard Worker 	struct callback_data cb_data;
232*2d543d20SAndroid Build Coastguard Worker 	FILE *fp;
233*2d543d20SAndroid Build Coastguard Worker 
234*2d543d20SAndroid Build Coastguard Worker 	if (argc != 2 && argc != 3) {
235*2d543d20SAndroid Build Coastguard Worker 		usage(argv[0]);
236*2d543d20SAndroid Build Coastguard Worker 		return -1;
237*2d543d20SAndroid Build Coastguard Worker 	}
238*2d543d20SAndroid Build Coastguard Worker 
239*2d543d20SAndroid Build Coastguard Worker 	/* Open the policy. */
240*2d543d20SAndroid Build Coastguard Worker 	p = load_policy(argv[2]);
241*2d543d20SAndroid Build Coastguard Worker 	if (p == NULL)
242*2d543d20SAndroid Build Coastguard Worker 		return -1;
243*2d543d20SAndroid Build Coastguard Worker 
244*2d543d20SAndroid Build Coastguard Worker 	/* Open the output policy. */
245*2d543d20SAndroid Build Coastguard Worker 	fp = fopen(argv[1], "w");
246*2d543d20SAndroid Build Coastguard Worker 	if (fp == NULL) {
247*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "error opening output file\n");
248*2d543d20SAndroid Build Coastguard Worker 		policydb_destroy(p);
249*2d543d20SAndroid Build Coastguard Worker 		free(p);
250*2d543d20SAndroid Build Coastguard Worker 		return -1;
251*2d543d20SAndroid Build Coastguard Worker 	}
252*2d543d20SAndroid Build Coastguard Worker 
253*2d543d20SAndroid Build Coastguard Worker 	/* Find all of the attributes and output their access. */
254*2d543d20SAndroid Build Coastguard Worker 	cb_data.policy = p;
255*2d543d20SAndroid Build Coastguard Worker 	cb_data.fp = fp;
256*2d543d20SAndroid Build Coastguard Worker 
257*2d543d20SAndroid Build Coastguard Worker 	if (hashtab_map(p->p_types.table, attribute_callback, &cb_data)) {
258*2d543d20SAndroid Build Coastguard Worker 		printf("error finding attributes\n");
259*2d543d20SAndroid Build Coastguard Worker 	}
260*2d543d20SAndroid Build Coastguard Worker 
261*2d543d20SAndroid Build Coastguard Worker 	policydb_destroy(p);
262*2d543d20SAndroid Build Coastguard Worker 	free(p);
263*2d543d20SAndroid Build Coastguard Worker 	fclose(fp);
264*2d543d20SAndroid Build Coastguard Worker 
265*2d543d20SAndroid Build Coastguard Worker 	return 0;
266*2d543d20SAndroid Build Coastguard Worker }
267