xref: /aosp_15_r20/external/selinux/semodule-utils/semodule_package/semodule_unpackage.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 #include <sepol/module.h>
2 #include <getopt.h>
3 #include <fcntl.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/mman.h>
11 #include <fcntl.h>
12 #include <errno.h>
13 
usage(const char * progname)14 static void usage(const char *progname)
15 {
16 	printf("usage: %s ppfile modfile [fcfile]\n", progname);
17 }
18 
main(int argc,char ** argv)19 int main(int argc, char **argv)
20 {
21 	struct sepol_module_package *pkg = NULL;
22 	struct sepol_policy_file *in = NULL, *out = NULL;
23 	FILE *fp = NULL;
24 	size_t len;
25 	const char *ppfile, *modfile, *fcfile = NULL, *fcdata;
26 	int ret;
27 
28 	if (argc < 3) {
29 		usage(argv[0]);
30 		return EXIT_FAILURE;
31 	}
32 
33 	ppfile = argv[1];
34 	modfile = argv[2];
35 	if (argc >= 4)
36 		fcfile = argv[3];
37 
38 	if (sepol_module_package_create(&pkg)) {
39 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
40 		goto failure;
41 	}
42 
43 	if (sepol_policy_file_create(&in)) {
44 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
45 		goto failure;
46 	}
47 
48 	fp = fopen(ppfile, "r");
49 	if (!fp) {
50 		fprintf(stderr, "%s:  Could not open file %s:  %s\n", argv[0], ppfile, strerror(errno));
51 		goto failure;
52 	}
53 	sepol_policy_file_set_fp(in, fp);
54 
55 	if (sepol_module_package_read(pkg, in, 0) == -1) {
56 		fprintf(stderr, "%s:  Error while reading policy module from %s\n",
57 			argv[0], ppfile);
58 		goto failure;
59 	}
60 
61 	sepol_policy_file_free(in);
62 	in = NULL;
63 	fclose(fp);
64 	fp = NULL;
65 
66 	if (sepol_policy_file_create(&out)) {
67 		fprintf(stderr, "%s:  Out of memory\n", argv[0]);
68 		goto failure;
69 	}
70 
71 	fp = fopen(modfile, "w");
72 	if (!fp) {
73 		fprintf(stderr, "%s:  Could not open file %s:  %s\n", argv[0], modfile, strerror(errno));
74 		goto failure;
75 	}
76 	sepol_policy_file_set_fp(out, fp);
77 
78 	if (sepol_policydb_write(sepol_module_package_get_policy(pkg), out)) {
79 		fprintf(stderr, "%s:  Error while writing module to %s\n", argv[0], modfile);
80 		goto failure;
81 	}
82 
83 	ret = fclose(fp);
84 	fp = NULL;
85 	if (ret) {
86 		fprintf(stderr, "%s:  Error while closing file %s:  %s\n", argv[0], modfile, strerror(errno));
87 		goto failure;
88 	}
89 
90 	sepol_policy_file_free(out);
91 	out = NULL;
92 
93 	len = sepol_module_package_get_file_contexts_len(pkg);
94 	if (fcfile && len) {
95 		fp = fopen(fcfile, "w");
96 		if (!fp) {
97 			fprintf(stderr, "%s:  Could not open file %s:  %s\n", argv[0], fcfile, strerror(errno));
98 			goto failure;
99 		}
100 		fcdata = sepol_module_package_get_file_contexts(pkg);
101 		if (fwrite(fcdata, 1, len, fp) != len) {
102 			fprintf(stderr, "%s:  Could not write file %s:  %s\n", argv[0], fcfile, strerror(errno));
103 			goto failure;
104 		}
105 
106 		ret = fclose(fp);
107 		fp = NULL;
108 		if (ret) {
109 			fprintf(stderr, "%s:  Could not close file %s:  %s\n", argv[0], fcfile, strerror(errno));
110 			goto failure;
111 		}
112 	}
113 
114 	ret = EXIT_SUCCESS;
115 	goto cleanup;
116 
117 failure:
118 	ret = EXIT_FAILURE;
119 
120 cleanup:
121 	if (fp)
122 		fclose(fp);
123 	sepol_policy_file_free(out);
124 	sepol_module_package_free(pkg);
125 	sepol_policy_file_free(in);
126 
127 	return ret;
128 }
129