xref: /aosp_15_r20/external/selinux/semodule-utils/semodule_link/semodule_link.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /* Authors: Karl MacMillan <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker  *
3*2d543d20SAndroid Build Coastguard Worker  * Copyright (C) 2004 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 #include <sepol/module.h>
10*2d543d20SAndroid Build Coastguard Worker 
11*2d543d20SAndroid Build Coastguard Worker #include <getopt.h>
12*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
13*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
14*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
15*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.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 <stdlib.h>
19*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
20*2d543d20SAndroid Build Coastguard Worker #include <string.h>
21*2d543d20SAndroid Build Coastguard Worker 
22*2d543d20SAndroid Build Coastguard Worker #define LINKPOLICY_VERSION "1.0"
23*2d543d20SAndroid Build Coastguard Worker 
usage(const char * program_name)24*2d543d20SAndroid Build Coastguard Worker static void usage(const char *program_name)
25*2d543d20SAndroid Build Coastguard Worker {
26*2d543d20SAndroid Build Coastguard Worker 	printf("usage: %s [-hVv] [-o outfile] basemodpkg modpkg1 [modpkg2]...\n",
27*2d543d20SAndroid Build Coastguard Worker 	       program_name);
28*2d543d20SAndroid Build Coastguard Worker }
29*2d543d20SAndroid Build Coastguard Worker 
load_module(const char * filename,const char * progname)30*2d543d20SAndroid Build Coastguard Worker static sepol_module_package_t *load_module(const char *filename, const char *progname)
31*2d543d20SAndroid Build Coastguard Worker {
32*2d543d20SAndroid Build Coastguard Worker 	int ret;
33*2d543d20SAndroid Build Coastguard Worker 	FILE *fp = NULL;
34*2d543d20SAndroid Build Coastguard Worker 	struct sepol_policy_file *pf = NULL;
35*2d543d20SAndroid Build Coastguard Worker 	sepol_module_package_t *p = NULL;
36*2d543d20SAndroid Build Coastguard Worker 
37*2d543d20SAndroid Build Coastguard Worker 	if (sepol_module_package_create(&p)) {
38*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Out of memory\n", progname);
39*2d543d20SAndroid Build Coastguard Worker 		goto bad;
40*2d543d20SAndroid Build Coastguard Worker 	}
41*2d543d20SAndroid Build Coastguard Worker 	if (sepol_policy_file_create(&pf)) {
42*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Out of memory\n", progname);
43*2d543d20SAndroid Build Coastguard Worker 		goto bad;
44*2d543d20SAndroid Build Coastguard Worker 	}
45*2d543d20SAndroid Build Coastguard Worker 	fp = fopen(filename, "re");
46*2d543d20SAndroid Build Coastguard Worker 	if (!fp) {
47*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Could not open package %s:  %s\n", progname,
48*2d543d20SAndroid Build Coastguard Worker 			filename, strerror(errno));
49*2d543d20SAndroid Build Coastguard Worker 		goto bad;
50*2d543d20SAndroid Build Coastguard Worker 	}
51*2d543d20SAndroid Build Coastguard Worker 	sepol_policy_file_set_fp(pf, fp);
52*2d543d20SAndroid Build Coastguard Worker 
53*2d543d20SAndroid Build Coastguard Worker 	printf("%s:  loading package from file %s\n", progname, filename);
54*2d543d20SAndroid Build Coastguard Worker 
55*2d543d20SAndroid Build Coastguard Worker 	ret = sepol_module_package_read(p, pf, 0);
56*2d543d20SAndroid Build Coastguard Worker 	if (ret) {
57*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Error while reading package from %s\n",
58*2d543d20SAndroid Build Coastguard Worker 			progname, filename);
59*2d543d20SAndroid Build Coastguard Worker 		goto bad;
60*2d543d20SAndroid Build Coastguard Worker 	}
61*2d543d20SAndroid Build Coastguard Worker 	fclose(fp);
62*2d543d20SAndroid Build Coastguard Worker 	sepol_policy_file_free(pf);
63*2d543d20SAndroid Build Coastguard Worker 	return p;
64*2d543d20SAndroid Build Coastguard Worker       bad:
65*2d543d20SAndroid Build Coastguard Worker 	sepol_module_package_free(p);
66*2d543d20SAndroid Build Coastguard Worker 	sepol_policy_file_free(pf);
67*2d543d20SAndroid Build Coastguard Worker 	if (fp)
68*2d543d20SAndroid Build Coastguard Worker 		fclose(fp);
69*2d543d20SAndroid Build Coastguard Worker 	return NULL;
70*2d543d20SAndroid Build Coastguard Worker }
71*2d543d20SAndroid Build Coastguard Worker 
main(int argc,char ** argv)72*2d543d20SAndroid Build Coastguard Worker int main(int argc, char **argv)
73*2d543d20SAndroid Build Coastguard Worker {
74*2d543d20SAndroid Build Coastguard Worker 	int ch, i, ret, show_version = 0, verbose = 0, num_mods = 0;
75*2d543d20SAndroid Build Coastguard Worker 	const char *basename, *outname = NULL;
76*2d543d20SAndroid Build Coastguard Worker 	sepol_module_package_t *base = NULL, **mods = NULL;
77*2d543d20SAndroid Build Coastguard Worker 	struct sepol_policy_file *pf = NULL;
78*2d543d20SAndroid Build Coastguard Worker 
79*2d543d20SAndroid Build Coastguard Worker 	while ((ch = getopt(argc, argv, "ho:Vv")) != EOF) {
80*2d543d20SAndroid Build Coastguard Worker 		switch (ch) {
81*2d543d20SAndroid Build Coastguard Worker 		case 'h':
82*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
83*2d543d20SAndroid Build Coastguard Worker 			return EXIT_SUCCESS;
84*2d543d20SAndroid Build Coastguard Worker 		case 'V':
85*2d543d20SAndroid Build Coastguard Worker 			show_version = 1;
86*2d543d20SAndroid Build Coastguard Worker 			break;
87*2d543d20SAndroid Build Coastguard Worker 		case 'v':
88*2d543d20SAndroid Build Coastguard Worker 			verbose = 1;
89*2d543d20SAndroid Build Coastguard Worker 			break;
90*2d543d20SAndroid Build Coastguard Worker 		case 'o':
91*2d543d20SAndroid Build Coastguard Worker 			outname = optarg;
92*2d543d20SAndroid Build Coastguard Worker 			break;
93*2d543d20SAndroid Build Coastguard Worker 		default:
94*2d543d20SAndroid Build Coastguard Worker 			usage(argv[0]);
95*2d543d20SAndroid Build Coastguard Worker 			return EXIT_FAILURE;
96*2d543d20SAndroid Build Coastguard Worker 		}
97*2d543d20SAndroid Build Coastguard Worker 	}
98*2d543d20SAndroid Build Coastguard Worker 
99*2d543d20SAndroid Build Coastguard Worker 	if (show_version) {
100*2d543d20SAndroid Build Coastguard Worker 		printf("%s\n", LINKPOLICY_VERSION);
101*2d543d20SAndroid Build Coastguard Worker 		return EXIT_SUCCESS;
102*2d543d20SAndroid Build Coastguard Worker 	}
103*2d543d20SAndroid Build Coastguard Worker 
104*2d543d20SAndroid Build Coastguard Worker 	/* check args */
105*2d543d20SAndroid Build Coastguard Worker 	if (argc < 3 || optind + 2 > argc) {
106*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr,
107*2d543d20SAndroid Build Coastguard Worker 			"%s:  You must provide the base module package and at least one other module package\n",
108*2d543d20SAndroid Build Coastguard Worker 			argv[0]);
109*2d543d20SAndroid Build Coastguard Worker 		usage(argv[0]);
110*2d543d20SAndroid Build Coastguard Worker 		return EXIT_FAILURE;
111*2d543d20SAndroid Build Coastguard Worker 	}
112*2d543d20SAndroid Build Coastguard Worker 
113*2d543d20SAndroid Build Coastguard Worker 	basename = argv[optind++];
114*2d543d20SAndroid Build Coastguard Worker 	base = load_module(basename, argv[0]);
115*2d543d20SAndroid Build Coastguard Worker 	if (!base) {
116*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr,
117*2d543d20SAndroid Build Coastguard Worker 			"%s:  Could not load base module from file %s\n",
118*2d543d20SAndroid Build Coastguard Worker 			argv[0], basename);
119*2d543d20SAndroid Build Coastguard Worker 		goto failure;
120*2d543d20SAndroid Build Coastguard Worker 	}
121*2d543d20SAndroid Build Coastguard Worker 
122*2d543d20SAndroid Build Coastguard Worker 	num_mods = argc - optind;
123*2d543d20SAndroid Build Coastguard Worker 	mods = calloc(num_mods, sizeof(sepol_module_package_t *));
124*2d543d20SAndroid Build Coastguard Worker 	if (!mods) {
125*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
126*2d543d20SAndroid Build Coastguard Worker 		goto failure;
127*2d543d20SAndroid Build Coastguard Worker 	}
128*2d543d20SAndroid Build Coastguard Worker 
129*2d543d20SAndroid Build Coastguard Worker 	for (i = 0; optind < argc; optind++, i++) {
130*2d543d20SAndroid Build Coastguard Worker 		mods[i] = load_module(argv[optind], argv[0]);
131*2d543d20SAndroid Build Coastguard Worker 		if (!mods[i]) {
132*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr,
133*2d543d20SAndroid Build Coastguard Worker 				"%s:  Could not load module from file %s\n",
134*2d543d20SAndroid Build Coastguard Worker 				argv[0], argv[optind]);
135*2d543d20SAndroid Build Coastguard Worker 			goto failure;
136*2d543d20SAndroid Build Coastguard Worker 		}
137*2d543d20SAndroid Build Coastguard Worker 	}
138*2d543d20SAndroid Build Coastguard Worker 
139*2d543d20SAndroid Build Coastguard Worker 	if (sepol_link_packages(NULL, base, mods, num_mods, verbose)) {
140*2d543d20SAndroid Build Coastguard Worker 		fprintf(stderr, "%s:  Error while linking packages\n", argv[0]);
141*2d543d20SAndroid Build Coastguard Worker 		goto failure;
142*2d543d20SAndroid Build Coastguard Worker 	}
143*2d543d20SAndroid Build Coastguard Worker 
144*2d543d20SAndroid Build Coastguard Worker 	if (outname) {
145*2d543d20SAndroid Build Coastguard Worker 		FILE *outfile = fopen(outname, "we");
146*2d543d20SAndroid Build Coastguard Worker 		if (!outfile) {
147*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  Could not open output file %s:  %s\n",
148*2d543d20SAndroid Build Coastguard Worker 				argv[0], outname, strerror(errno));
149*2d543d20SAndroid Build Coastguard Worker 			goto failure;
150*2d543d20SAndroid Build Coastguard Worker 		}
151*2d543d20SAndroid Build Coastguard Worker 
152*2d543d20SAndroid Build Coastguard Worker 		if (sepol_policy_file_create(&pf)) {
153*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  Out of memory\n", argv[0]);
154*2d543d20SAndroid Build Coastguard Worker 			fclose(outfile);
155*2d543d20SAndroid Build Coastguard Worker 			goto failure;
156*2d543d20SAndroid Build Coastguard Worker 		}
157*2d543d20SAndroid Build Coastguard Worker 		sepol_policy_file_set_fp(pf, outfile);
158*2d543d20SAndroid Build Coastguard Worker 		if (sepol_module_package_write(base, pf)) {
159*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  Error writing linked package.\n",
160*2d543d20SAndroid Build Coastguard Worker 				argv[0]);
161*2d543d20SAndroid Build Coastguard Worker 			sepol_policy_file_free(pf);
162*2d543d20SAndroid Build Coastguard Worker 			fclose(outfile);
163*2d543d20SAndroid Build Coastguard Worker 			goto failure;
164*2d543d20SAndroid Build Coastguard Worker 		}
165*2d543d20SAndroid Build Coastguard Worker 		sepol_policy_file_free(pf);
166*2d543d20SAndroid Build Coastguard Worker 
167*2d543d20SAndroid Build Coastguard Worker 		if (fclose(outfile)) {
168*2d543d20SAndroid Build Coastguard Worker 			fprintf(stderr, "%s:  Error closing linked package:  %s\n",
169*2d543d20SAndroid Build Coastguard Worker 				argv[0], strerror(errno));
170*2d543d20SAndroid Build Coastguard Worker 			goto failure;
171*2d543d20SAndroid Build Coastguard Worker 		}
172*2d543d20SAndroid Build Coastguard Worker 	}
173*2d543d20SAndroid Build Coastguard Worker 
174*2d543d20SAndroid Build Coastguard Worker 	ret = EXIT_SUCCESS;
175*2d543d20SAndroid Build Coastguard Worker 	goto cleanup;
176*2d543d20SAndroid Build Coastguard Worker 
177*2d543d20SAndroid Build Coastguard Worker failure:
178*2d543d20SAndroid Build Coastguard Worker 	ret = EXIT_FAILURE;
179*2d543d20SAndroid Build Coastguard Worker 
180*2d543d20SAndroid Build Coastguard Worker cleanup:
181*2d543d20SAndroid Build Coastguard Worker 	if (mods) {
182*2d543d20SAndroid Build Coastguard Worker 		for (i = 0; i < num_mods; i++)
183*2d543d20SAndroid Build Coastguard Worker 			sepol_module_package_free(mods[i]);
184*2d543d20SAndroid Build Coastguard Worker 		free(mods);
185*2d543d20SAndroid Build Coastguard Worker 	}
186*2d543d20SAndroid Build Coastguard Worker 	sepol_module_package_free(base);
187*2d543d20SAndroid Build Coastguard Worker 
188*2d543d20SAndroid Build Coastguard Worker 	return ret;
189*2d543d20SAndroid Build Coastguard Worker }
190