xref: /aosp_15_r20/external/selinux/checkpolicy/checkmodule.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /*
2*2d543d20SAndroid Build Coastguard Worker  * Authors: Joshua Brindle <[email protected]>
3*2d543d20SAndroid Build Coastguard Worker  *	    Karl MacMillan <[email protected]>
4*2d543d20SAndroid Build Coastguard Worker  *          Jason Tang     <[email protected]>
5*2d543d20SAndroid Build Coastguard Worker  *
6*2d543d20SAndroid Build Coastguard Worker  *
7*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2004-5 Tresys Technology, LLC
8*2d543d20SAndroid Build Coastguard Worker  *	This program is free software; you can redistribute it and/or modify
9*2d543d20SAndroid Build Coastguard Worker  *  	it under the terms of the GNU General Public License as published by
10*2d543d20SAndroid Build Coastguard Worker  *	the Free Software Foundation, version 2.
11*2d543d20SAndroid Build Coastguard Worker  */
12*2d543d20SAndroid Build Coastguard Worker 
13*2d543d20SAndroid Build Coastguard Worker #include <getopt.h>
14*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
15*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
16*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
17*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
18*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
19*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
20*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
21*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.h>
22*2d543d20SAndroid Build Coastguard Worker #include <libgen.h>
23*2d543d20SAndroid Build Coastguard Worker 
24*2d543d20SAndroid Build Coastguard Worker #include <sepol/module_to_cil.h>
25*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
26*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
27*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/conditional.h>
28*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/hierarchy.h>
29*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/expand.h>
30*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/link.h>
31*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/sidtab.h>
32*2d543d20SAndroid Build Coastguard Worker 
33*2d543d20SAndroid Build Coastguard Worker #include "queue.h"
34*2d543d20SAndroid Build Coastguard Worker #include "parse_util.h"
35*2d543d20SAndroid Build Coastguard Worker 
36*2d543d20SAndroid Build Coastguard Worker static sidtab_t sidtab;
37*2d543d20SAndroid Build Coastguard Worker 
38*2d543d20SAndroid Build Coastguard Worker extern int mlspol;
39*2d543d20SAndroid Build Coastguard Worker extern int werror;
40*2d543d20SAndroid Build Coastguard Worker 
41*2d543d20SAndroid Build Coastguard Worker static int handle_unknown = SEPOL_DENY_UNKNOWN;
42*2d543d20SAndroid Build Coastguard Worker static const char *txtfile = "policy.conf";
43*2d543d20SAndroid Build Coastguard Worker static const char *binfile = "policy";
44*2d543d20SAndroid Build Coastguard Worker 
read_binary_policy(policydb_t * p,const char * file,const char * progname)45*2d543d20SAndroid Build Coastguard Worker static int read_binary_policy(policydb_t * p, const char *file, const char *progname)
46*2d543d20SAndroid Build Coastguard Worker {
47*2d543d20SAndroid Build Coastguard Worker 	int fd;
48*2d543d20SAndroid Build Coastguard Worker 	struct stat sb;
49*2d543d20SAndroid Build Coastguard Worker 	void *map;
50*2d543d20SAndroid Build Coastguard Worker 	struct policy_file f, *fp;
51*2d543d20SAndroid Build Coastguard Worker 
52*2d543d20SAndroid Build Coastguard Worker 	fd = open(file, O_RDONLY);
53*2d543d20SAndroid Build Coastguard Worker 	if (fd < 0) {
54*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't open '%s':  %s\n",
55*2d543d20SAndroid Build Coastguard Worker 			file, strerror(errno));
56*2d543d20SAndroid Build Coastguard Worker 		return -1;
57*2d543d20SAndroid Build Coastguard Worker 	}
58*2d543d20SAndroid Build Coastguard Worker 	if (fstat(fd, &sb) < 0) {
59*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't stat '%s':  %s\n",
60*2d543d20SAndroid Build Coastguard Worker 			file, strerror(errno));
61*2d543d20SAndroid Build Coastguard Worker 		close(fd);
62*2d543d20SAndroid Build Coastguard Worker 		return -1;
63*2d543d20SAndroid Build Coastguard Worker 	}
64*2d543d20SAndroid Build Coastguard Worker 	map =
65*2d543d20SAndroid Build Coastguard Worker 	    mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
66*2d543d20SAndroid Build Coastguard Worker 	close(fd);
67*2d543d20SAndroid Build Coastguard Worker 	if (map == MAP_FAILED) {
68*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "Can't map '%s':  %s\n", file, strerror(errno));
69*2d543d20SAndroid Build Coastguard Worker 		return -1;
70*2d543d20SAndroid Build Coastguard Worker 	}
71*2d543d20SAndroid Build Coastguard Worker 	policy_file_init(&f);
72*2d543d20SAndroid Build Coastguard Worker 	f.type = PF_USE_MEMORY;
73*2d543d20SAndroid Build Coastguard Worker 	f.data = map;
74*2d543d20SAndroid Build Coastguard Worker 	f.len = sb.st_size;
75*2d543d20SAndroid Build Coastguard Worker 	fp = &f;
76*2d543d20SAndroid Build Coastguard Worker 
77*2d543d20SAndroid Build Coastguard Worker 	if (policydb_init(p)) {
78*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  policydb_init:  Out of memory!\n",
79*2d543d20SAndroid Build Coastguard Worker 			progname);
80*2d543d20SAndroid Build Coastguard Worker 		return -1;
81*2d543d20SAndroid Build Coastguard Worker 	}
82*2d543d20SAndroid Build Coastguard Worker 	if (policydb_read(p, fp, 1)) {
83*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr,
84*2d543d20SAndroid Build Coastguard Worker 			"%s:  error(s) encountered while parsing configuration\n",
85*2d543d20SAndroid Build Coastguard Worker 			progname);
86*2d543d20SAndroid Build Coastguard Worker 		return -1;
87*2d543d20SAndroid Build Coastguard Worker 	}
88*2d543d20SAndroid Build Coastguard Worker 
89*2d543d20SAndroid Build Coastguard Worker 	/* Check Policy Consistency */
90*2d543d20SAndroid Build Coastguard Worker 	if (p->mls) {
91*2d543d20SAndroid Build Coastguard Worker 		if (!mlspol) {
92*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  MLS policy, but non-MLS"
93*2d543d20SAndroid Build Coastguard Worker 				" is specified\n", progname);
94*2d543d20SAndroid Build Coastguard Worker 			return -1;
95*2d543d20SAndroid Build Coastguard Worker 		}
96*2d543d20SAndroid Build Coastguard Worker 	} else {
97*2d543d20SAndroid Build Coastguard Worker 		if (mlspol) {
98*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  non-MLS policy, but MLS"
99*2d543d20SAndroid Build Coastguard Worker 				" is specified\n", progname);
100*2d543d20SAndroid Build Coastguard Worker 			return -1;
101*2d543d20SAndroid Build Coastguard Worker 		}
102*2d543d20SAndroid Build Coastguard Worker 	}
103*2d543d20SAndroid Build Coastguard Worker 	return 0;
104*2d543d20SAndroid Build Coastguard Worker }
105*2d543d20SAndroid Build Coastguard Worker 
write_binary_policy(policydb_t * p,FILE * outfp,unsigned int policy_type,unsigned int policyvers)106*2d543d20SAndroid Build Coastguard Worker static int write_binary_policy(policydb_t * p, FILE *outfp, unsigned int policy_type, unsigned int policyvers)
107*2d543d20SAndroid Build Coastguard Worker {
108*2d543d20SAndroid Build Coastguard Worker 	struct policy_file pf;
109*2d543d20SAndroid Build Coastguard Worker 
110*2d543d20SAndroid Build Coastguard Worker 	p->policy_type = policy_type;
111*2d543d20SAndroid Build Coastguard Worker 	p->policyvers = policyvers;
112*2d543d20SAndroid Build Coastguard Worker 	p->handle_unknown = handle_unknown;
113*2d543d20SAndroid Build Coastguard Worker 
114*2d543d20SAndroid Build Coastguard Worker 	policy_file_init(&pf);
115*2d543d20SAndroid Build Coastguard Worker 	pf.type = PF_USE_STDIO;
116*2d543d20SAndroid Build Coastguard Worker 	pf.fp = outfp;
117*2d543d20SAndroid Build Coastguard Worker 	return policydb_write(p, &pf);
118*2d543d20SAndroid Build Coastguard Worker }
119*2d543d20SAndroid Build Coastguard Worker 
usage(const char * progname)120*2d543d20SAndroid Build Coastguard Worker static __attribute__((__noreturn__)) void usage(const char *progname)
121*2d543d20SAndroid Build Coastguard Worker {
122*2d543d20SAndroid Build Coastguard Worker 	printf("usage:  %s [-h] [-V] [-b] [-C] [-E] [-U handle_unknown] [-m] [-M] [-N] [-o FILE] [-c VERSION] [INPUT]\n", progname);
123*2d543d20SAndroid Build Coastguard Worker 	printf("Build base and policy modules.\n");
124*2d543d20SAndroid Build Coastguard Worker 	printf("Options:\n");
125*2d543d20SAndroid Build Coastguard Worker 	printf("  INPUT      build module from INPUT (else read from \"%s\")\n",
126*2d543d20SAndroid Build Coastguard Worker 	       txtfile);
127*2d543d20SAndroid Build Coastguard Worker 	printf("  -V         show policy versions created by this program\n");
128*2d543d20SAndroid Build Coastguard Worker 	printf("  -b         treat input as a binary policy file\n");
129*2d543d20SAndroid Build Coastguard Worker 	printf("  -C         output CIL policy instead of binary policy\n");
130*2d543d20SAndroid Build Coastguard Worker 	printf("  -E         treat warnings as errors\n");
131*2d543d20SAndroid Build Coastguard Worker 	printf("  -h         print usage\n");
132*2d543d20SAndroid Build Coastguard Worker 	printf("  -U OPTION  How to handle unknown classes and permissions\n");
133*2d543d20SAndroid Build Coastguard Worker 	printf("               deny: Deny unknown kernel checks\n");
134*2d543d20SAndroid Build Coastguard Worker 	printf("               reject: Reject loading of policy with unknowns\n");
135*2d543d20SAndroid Build Coastguard Worker 	printf("               allow: Allow unknown kernel checks\n");
136*2d543d20SAndroid Build Coastguard Worker 	printf("  -m         build a policy module instead of a base module\n");
137*2d543d20SAndroid Build Coastguard Worker 	printf("  -M         enable MLS policy\n");
138*2d543d20SAndroid Build Coastguard Worker 	printf("  -N         do not check neverallow rules\n");
139*2d543d20SAndroid Build Coastguard Worker 	printf("  -o FILE    write module to FILE (else just check syntax)\n");
140*2d543d20SAndroid Build Coastguard Worker 	printf("  -c VERSION build a policy module targeting a modular policy version (%d-%d)\n",
141*2d543d20SAndroid Build Coastguard Worker 	       MOD_POLICYDB_VERSION_MIN, MOD_POLICYDB_VERSION_MAX);
142*2d543d20SAndroid Build Coastguard Worker 	exit(1);
143*2d543d20SAndroid Build Coastguard Worker }
144*2d543d20SAndroid Build Coastguard Worker 
main(int argc,char ** argv)145*2d543d20SAndroid Build Coastguard Worker int main(int argc, char **argv)
146*2d543d20SAndroid Build Coastguard Worker {
147*2d543d20SAndroid Build Coastguard Worker 	const char *file = txtfile, *outfile = NULL;
148*2d543d20SAndroid Build Coastguard Worker 	unsigned int binary = 0, cil = 0, disable_neverallow = 0;
149*2d543d20SAndroid Build Coastguard Worker 	unsigned int policy_type = POLICY_BASE;
150*2d543d20SAndroid Build Coastguard Worker 	unsigned int policyvers = MOD_POLICYDB_VERSION_MAX;
151*2d543d20SAndroid Build Coastguard Worker 	int ch;
152*2d543d20SAndroid Build Coastguard Worker 	int show_version = 0;
153*2d543d20SAndroid Build Coastguard Worker 	policydb_t modpolicydb;
154*2d543d20SAndroid Build Coastguard Worker 	const struct option long_options[] = {
155*2d543d20SAndroid Build Coastguard Worker 		{"help", no_argument, NULL, 'h'},
156*2d543d20SAndroid Build Coastguard Worker 		{"output", required_argument, NULL, 'o'},
157*2d543d20SAndroid Build Coastguard Worker 		{"binary", no_argument, NULL, 'b'},
158*2d543d20SAndroid Build Coastguard Worker 		{"version", no_argument, NULL, 'V'},
159*2d543d20SAndroid Build Coastguard Worker 		{"handle-unknown", required_argument, NULL, 'U'},
160*2d543d20SAndroid Build Coastguard Worker 		{"mls", no_argument, NULL, 'M'},
161*2d543d20SAndroid Build Coastguard Worker 		{"disable-neverallow", no_argument, NULL, 'N'},
162*2d543d20SAndroid Build Coastguard Worker 		{"cil", no_argument, NULL, 'C'},
163*2d543d20SAndroid Build Coastguard Worker 		{"werror", no_argument, NULL, 'E'},
164*2d543d20SAndroid Build Coastguard Worker 		{NULL, 0, NULL, 0}
165*2d543d20SAndroid Build Coastguard Worker 	};
166*2d543d20SAndroid Build Coastguard Worker 
167*2d543d20SAndroid Build Coastguard Worker 	while ((ch = getopt_long(argc, argv, "ho:bVEU:mMNCc:", long_options, NULL)) != -1) {
168*2d543d20SAndroid Build Coastguard Worker 		switch (ch) {
169*2d543d20SAndroid Build Coastguard Worker 		case 'h':
170*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
171*2d543d20SAndroid Build Coastguard Worker 			break;
172*2d543d20SAndroid Build Coastguard Worker 		case 'o':
173*2d543d20SAndroid Build Coastguard Worker 			outfile = optarg;
174*2d543d20SAndroid Build Coastguard Worker 			break;
175*2d543d20SAndroid Build Coastguard Worker 		case 'b':
176*2d543d20SAndroid Build Coastguard Worker 			binary = 1;
177*2d543d20SAndroid Build Coastguard Worker 			file = binfile;
178*2d543d20SAndroid Build Coastguard Worker 			break;
179*2d543d20SAndroid Build Coastguard Worker 		case 'V':
180*2d543d20SAndroid Build Coastguard Worker 			show_version = 1;
181*2d543d20SAndroid Build Coastguard Worker 			break;
182*2d543d20SAndroid Build Coastguard Worker 		case 'E':
183*2d543d20SAndroid Build Coastguard Worker 			werror = 1;
184*2d543d20SAndroid Build Coastguard Worker 			break;
185*2d543d20SAndroid Build Coastguard Worker 		case 'U':
186*2d543d20SAndroid Build Coastguard Worker 			if (!strcasecmp(optarg, "deny")) {
187*2d543d20SAndroid Build Coastguard Worker 				handle_unknown = DENY_UNKNOWN;
188*2d543d20SAndroid Build Coastguard Worker 				break;
189*2d543d20SAndroid Build Coastguard Worker 			}
190*2d543d20SAndroid Build Coastguard Worker 			if (!strcasecmp(optarg, "reject")) {
191*2d543d20SAndroid Build Coastguard Worker 				handle_unknown = REJECT_UNKNOWN;
192*2d543d20SAndroid Build Coastguard Worker 				break;
193*2d543d20SAndroid Build Coastguard Worker 			}
194*2d543d20SAndroid Build Coastguard Worker 			if (!strcasecmp(optarg, "allow")) {
195*2d543d20SAndroid Build Coastguard Worker 				handle_unknown = ALLOW_UNKNOWN;
196*2d543d20SAndroid Build Coastguard Worker 				break;
197*2d543d20SAndroid Build Coastguard Worker 			}
198*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
199*2d543d20SAndroid Build Coastguard Worker 		case 'm':
200*2d543d20SAndroid Build Coastguard Worker 			policy_type = POLICY_MOD;
201*2d543d20SAndroid Build Coastguard Worker 			break;
202*2d543d20SAndroid Build Coastguard Worker 		case 'M':
203*2d543d20SAndroid Build Coastguard Worker 			mlspol = 1;
204*2d543d20SAndroid Build Coastguard Worker 			break;
205*2d543d20SAndroid Build Coastguard Worker 		case 'N':
206*2d543d20SAndroid Build Coastguard Worker 			disable_neverallow = 1;
207*2d543d20SAndroid Build Coastguard Worker 			break;
208*2d543d20SAndroid Build Coastguard Worker 		case 'C':
209*2d543d20SAndroid Build Coastguard Worker 			cil = 1;
210*2d543d20SAndroid Build Coastguard Worker 			break;
211*2d543d20SAndroid Build Coastguard Worker 		case 'c': {
212*2d543d20SAndroid Build Coastguard Worker 			long int n;
213*2d543d20SAndroid Build Coastguard Worker 			errno = 0;
214*2d543d20SAndroid Build Coastguard Worker 			n = strtol(optarg, NULL, 10);
215*2d543d20SAndroid Build Coastguard Worker 			if (errno) {
216*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr,
217*2d543d20SAndroid Build Coastguard Worker 					"Invalid policyvers specified: %s\n",
218*2d543d20SAndroid Build Coastguard Worker 					optarg);
219*2d543d20SAndroid Build Coastguard Worker 				usage(argv[0]);
220*2d543d20SAndroid Build Coastguard Worker 			}
221*2d543d20SAndroid Build Coastguard Worker 
222*2d543d20SAndroid Build Coastguard Worker 			if (n < MOD_POLICYDB_VERSION_MIN
223*2d543d20SAndroid Build Coastguard Worker 			    || n > MOD_POLICYDB_VERSION_MAX) {
224*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr,
225*2d543d20SAndroid Build Coastguard Worker 					"policyvers value %ld not in range %d-%d\n",
226*2d543d20SAndroid Build Coastguard Worker 					n, MOD_POLICYDB_VERSION_MIN,
227*2d543d20SAndroid Build Coastguard Worker 					MOD_POLICYDB_VERSION_MAX);
228*2d543d20SAndroid Build Coastguard Worker 				usage(argv[0]);
229*2d543d20SAndroid Build Coastguard Worker 			}
230*2d543d20SAndroid Build Coastguard Worker 
231*2d543d20SAndroid Build Coastguard Worker 			policyvers = n;
232*2d543d20SAndroid Build Coastguard Worker 			break;
233*2d543d20SAndroid Build Coastguard Worker 		}
234*2d543d20SAndroid Build Coastguard Worker 		default:
235*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
236*2d543d20SAndroid Build Coastguard Worker 		}
237*2d543d20SAndroid Build Coastguard Worker 	}
238*2d543d20SAndroid Build Coastguard Worker 
239*2d543d20SAndroid Build Coastguard Worker 	if (show_version) {
240*2d543d20SAndroid Build Coastguard Worker 		printf("Module versions %d-%d\n",
241*2d543d20SAndroid Build Coastguard Worker 		       MOD_POLICYDB_VERSION_MIN, MOD_POLICYDB_VERSION_MAX);
242*2d543d20SAndroid Build Coastguard Worker 		exit(0);
243*2d543d20SAndroid Build Coastguard Worker 	}
244*2d543d20SAndroid Build Coastguard Worker 
245*2d543d20SAndroid Build Coastguard Worker 	if (handle_unknown && (policy_type != POLICY_BASE)) {
246*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Handling of unknown classes and permissions is only valid in the base module.\n", argv[0]);
247*2d543d20SAndroid Build Coastguard Worker 		exit(1);
248*2d543d20SAndroid Build Coastguard Worker 	}
249*2d543d20SAndroid Build Coastguard Worker 
250*2d543d20SAndroid Build Coastguard Worker 	if (binary && (policy_type != POLICY_BASE)) {
251*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  -b and -m are incompatible with each other.\n", argv[0]);
252*2d543d20SAndroid Build Coastguard Worker 		exit(1);
253*2d543d20SAndroid Build Coastguard Worker 	}
254*2d543d20SAndroid Build Coastguard Worker 
255*2d543d20SAndroid Build Coastguard Worker 	if (optind != argc) {
256*2d543d20SAndroid Build Coastguard Worker 		file = argv[optind++];
257*2d543d20SAndroid Build Coastguard Worker 		if (optind != argc)
258*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
259*2d543d20SAndroid Build Coastguard Worker 	}
260*2d543d20SAndroid Build Coastguard Worker 
261*2d543d20SAndroid Build Coastguard Worker 	/* Set policydb and sidtab used by libsepol service functions
262*2d543d20SAndroid Build Coastguard Worker 	   to my structures, so that I can directly populate and
263*2d543d20SAndroid Build Coastguard Worker 	   manipulate them. */
264*2d543d20SAndroid Build Coastguard Worker 	sepol_set_policydb(&modpolicydb);
265*2d543d20SAndroid Build Coastguard Worker 	sepol_set_sidtab(&sidtab);
266*2d543d20SAndroid Build Coastguard Worker 
267*2d543d20SAndroid Build Coastguard Worker 	if (binary) {
268*2d543d20SAndroid Build Coastguard Worker 		if (read_binary_policy(&modpolicydb, file, argv[0]) == -1) {
269*2d543d20SAndroid Build Coastguard Worker 			exit(1);
270*2d543d20SAndroid Build Coastguard Worker 		}
271*2d543d20SAndroid Build Coastguard Worker 	} else {
272*2d543d20SAndroid Build Coastguard Worker 		if (policydb_init(&modpolicydb)) {
273*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s: out of memory!\n", argv[0]);
274*2d543d20SAndroid Build Coastguard Worker 			exit(1);
275*2d543d20SAndroid Build Coastguard Worker 		}
276*2d543d20SAndroid Build Coastguard Worker 
277*2d543d20SAndroid Build Coastguard Worker 		modpolicydb.policy_type = policy_type;
278*2d543d20SAndroid Build Coastguard Worker 		modpolicydb.mls = mlspol;
279*2d543d20SAndroid Build Coastguard Worker 		modpolicydb.handle_unknown = handle_unknown;
280*2d543d20SAndroid Build Coastguard Worker 		modpolicydb.policyvers = policyvers;
281*2d543d20SAndroid Build Coastguard Worker 
282*2d543d20SAndroid Build Coastguard Worker 		if (read_source_policy(&modpolicydb, file, argv[0]) == -1) {
283*2d543d20SAndroid Build Coastguard Worker 			exit(1);
284*2d543d20SAndroid Build Coastguard Worker 		}
285*2d543d20SAndroid Build Coastguard Worker 
286*2d543d20SAndroid Build Coastguard Worker 		if (hierarchy_check_constraints(NULL, &modpolicydb)) {
287*2d543d20SAndroid Build Coastguard Worker 			exit(1);
288*2d543d20SAndroid Build Coastguard Worker 		}
289*2d543d20SAndroid Build Coastguard Worker 	}
290*2d543d20SAndroid Build Coastguard Worker 
291*2d543d20SAndroid Build Coastguard Worker 	if (policy_type != POLICY_BASE && outfile) {
292*2d543d20SAndroid Build Coastguard Worker 		char *out_name;
293*2d543d20SAndroid Build Coastguard Worker 		char *separator;
294*2d543d20SAndroid Build Coastguard Worker 		char *mod_name = modpolicydb.name;
295*2d543d20SAndroid Build Coastguard Worker 		char *out_path = strdup(outfile);
296*2d543d20SAndroid Build Coastguard Worker 		if (out_path == NULL) {
297*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  out of memory\n", argv[0]);
298*2d543d20SAndroid Build Coastguard Worker 			exit(1);
299*2d543d20SAndroid Build Coastguard Worker 		}
300*2d543d20SAndroid Build Coastguard Worker 		out_name = basename(out_path);
301*2d543d20SAndroid Build Coastguard Worker 		separator = strrchr(out_name, '.');
302*2d543d20SAndroid Build Coastguard Worker 		if (separator) {
303*2d543d20SAndroid Build Coastguard Worker 			*separator = '\0';
304*2d543d20SAndroid Build Coastguard Worker 		}
305*2d543d20SAndroid Build Coastguard Worker 		if (strcmp(mod_name, out_name) != 0) {
306*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr,	"%s:  Module name %s is different than the output base filename %s\n", argv[0], mod_name, out_name);
307*2d543d20SAndroid Build Coastguard Worker 			exit(1);
308*2d543d20SAndroid Build Coastguard Worker 		}
309*2d543d20SAndroid Build Coastguard Worker 		free(out_path);
310*2d543d20SAndroid Build Coastguard Worker 	}
311*2d543d20SAndroid Build Coastguard Worker 
312*2d543d20SAndroid Build Coastguard Worker 	if (modpolicydb.policy_type == POLICY_BASE && !cil) {
313*2d543d20SAndroid Build Coastguard Worker 		/* Verify that we can successfully expand the base module. */
314*2d543d20SAndroid Build Coastguard Worker 		policydb_t kernpolicydb;
315*2d543d20SAndroid Build Coastguard Worker 
316*2d543d20SAndroid Build Coastguard Worker 		if (policydb_init(&kernpolicydb)) {
317*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  policydb_init failed\n", argv[0]);
318*2d543d20SAndroid Build Coastguard Worker 			exit(1);
319*2d543d20SAndroid Build Coastguard Worker 		}
320*2d543d20SAndroid Build Coastguard Worker 		if (link_modules(NULL, &modpolicydb, NULL, 0, 0)) {
321*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  link modules failed\n", argv[0]);
322*2d543d20SAndroid Build Coastguard Worker 			exit(1);
323*2d543d20SAndroid Build Coastguard Worker 		}
324*2d543d20SAndroid Build Coastguard Worker 		if (expand_module(NULL, &modpolicydb, &kernpolicydb, /*verbose=*/0, !disable_neverallow)) {
325*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  expand module failed\n", argv[0]);
326*2d543d20SAndroid Build Coastguard Worker 			exit(1);
327*2d543d20SAndroid Build Coastguard Worker 		}
328*2d543d20SAndroid Build Coastguard Worker 		policydb_destroy(&kernpolicydb);
329*2d543d20SAndroid Build Coastguard Worker 	}
330*2d543d20SAndroid Build Coastguard Worker 
331*2d543d20SAndroid Build Coastguard Worker 	if (policydb_load_isids(&modpolicydb, &sidtab))
332*2d543d20SAndroid Build Coastguard Worker 		exit(1);
333*2d543d20SAndroid Build Coastguard Worker 
334*2d543d20SAndroid Build Coastguard Worker 	sepol_sidtab_destroy(&sidtab);
335*2d543d20SAndroid Build Coastguard Worker 
336*2d543d20SAndroid Build Coastguard Worker 	if (outfile) {
337*2d543d20SAndroid Build Coastguard Worker 		FILE *outfp = fopen(outfile, "w");
338*2d543d20SAndroid Build Coastguard Worker 
339*2d543d20SAndroid Build Coastguard Worker 		if (!outfp) {
340*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  error opening %s:  %s\n", argv[0], outfile, strerror(errno));
341*2d543d20SAndroid Build Coastguard Worker 			exit(1);
342*2d543d20SAndroid Build Coastguard Worker 		}
343*2d543d20SAndroid Build Coastguard Worker 
344*2d543d20SAndroid Build Coastguard Worker 		if (!cil) {
345*2d543d20SAndroid Build Coastguard Worker 			if (write_binary_policy(&modpolicydb, outfp, policy_type, policyvers) != 0) {
346*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  error writing %s\n", argv[0], outfile);
347*2d543d20SAndroid Build Coastguard Worker 				exit(1);
348*2d543d20SAndroid Build Coastguard Worker 			}
349*2d543d20SAndroid Build Coastguard Worker 		} else {
350*2d543d20SAndroid Build Coastguard Worker 			if (sepol_module_policydb_to_cil(outfp, &modpolicydb, 0) != 0) {
351*2d543d20SAndroid Build Coastguard Worker 				fprintf(stderr, "%s:  error writing %s\n", argv[0], outfile);
352*2d543d20SAndroid Build Coastguard Worker 				exit(1);
353*2d543d20SAndroid Build Coastguard Worker 			}
354*2d543d20SAndroid Build Coastguard Worker 		}
355*2d543d20SAndroid Build Coastguard Worker 
356*2d543d20SAndroid Build Coastguard Worker 		if (fclose(outfp)) {
357*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  error closing %s:  %s\n", argv[0], outfile, strerror(errno));
358*2d543d20SAndroid Build Coastguard Worker 			exit(1);
359*2d543d20SAndroid Build Coastguard Worker 		}
360*2d543d20SAndroid Build Coastguard Worker 	} else if (cil) {
361*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  No file to write CIL was specified\n", argv[0]);
362*2d543d20SAndroid Build Coastguard Worker 		exit(1);
363*2d543d20SAndroid Build Coastguard Worker 	}
364*2d543d20SAndroid Build Coastguard Worker 
365*2d543d20SAndroid Build Coastguard Worker 	policydb_destroy(&modpolicydb);
366*2d543d20SAndroid Build Coastguard Worker 
367*2d543d20SAndroid Build Coastguard Worker 	return 0;
368*2d543d20SAndroid Build Coastguard Worker }
369*2d543d20SAndroid Build Coastguard Worker 
370*2d543d20SAndroid Build Coastguard Worker /* FLASK */
371