1*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
2*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
3*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
4*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.h>
5*2d543d20SAndroid Build Coastguard Worker #include <sys/mount.h>
6*2d543d20SAndroid Build Coastguard Worker #include <sys/utsname.h>
7*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
8*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
9*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
10*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
11*2d543d20SAndroid Build Coastguard Worker #include <string.h>
12*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
13*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
14*2d543d20SAndroid Build Coastguard Worker #ifndef ANDROID
15*2d543d20SAndroid Build Coastguard Worker #include <sepol/sepol.h>
16*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb.h>
17*2d543d20SAndroid Build Coastguard Worker #endif
18*2d543d20SAndroid Build Coastguard Worker #include <dlfcn.h>
19*2d543d20SAndroid Build Coastguard Worker #include "policy.h"
20*2d543d20SAndroid Build Coastguard Worker #include <limits.h>
21*2d543d20SAndroid Build Coastguard Worker
22*2d543d20SAndroid Build Coastguard Worker #ifndef MNT_DETACH
23*2d543d20SAndroid Build Coastguard Worker #define MNT_DETACH 2
24*2d543d20SAndroid Build Coastguard Worker #endif
25*2d543d20SAndroid Build Coastguard Worker
security_load_policy(const void * data,size_t len)26*2d543d20SAndroid Build Coastguard Worker int security_load_policy(const void *data, size_t len)
27*2d543d20SAndroid Build Coastguard Worker {
28*2d543d20SAndroid Build Coastguard Worker char path[PATH_MAX];
29*2d543d20SAndroid Build Coastguard Worker int fd, ret;
30*2d543d20SAndroid Build Coastguard Worker
31*2d543d20SAndroid Build Coastguard Worker if (!selinux_mnt) {
32*2d543d20SAndroid Build Coastguard Worker errno = ENOENT;
33*2d543d20SAndroid Build Coastguard Worker return -1;
34*2d543d20SAndroid Build Coastguard Worker }
35*2d543d20SAndroid Build Coastguard Worker
36*2d543d20SAndroid Build Coastguard Worker snprintf(path, sizeof path, "%s/load", selinux_mnt);
37*2d543d20SAndroid Build Coastguard Worker fd = open(path, O_RDWR | O_CLOEXEC);
38*2d543d20SAndroid Build Coastguard Worker if (fd < 0)
39*2d543d20SAndroid Build Coastguard Worker return -1;
40*2d543d20SAndroid Build Coastguard Worker
41*2d543d20SAndroid Build Coastguard Worker ret = write(fd, data, len);
42*2d543d20SAndroid Build Coastguard Worker close(fd);
43*2d543d20SAndroid Build Coastguard Worker if (ret < 0)
44*2d543d20SAndroid Build Coastguard Worker return -1;
45*2d543d20SAndroid Build Coastguard Worker return 0;
46*2d543d20SAndroid Build Coastguard Worker }
47*2d543d20SAndroid Build Coastguard Worker
48*2d543d20SAndroid Build Coastguard Worker
49*2d543d20SAndroid Build Coastguard Worker #ifndef ANDROID
50*2d543d20SAndroid Build Coastguard Worker #undef max
51*2d543d20SAndroid Build Coastguard Worker #define max(a, b) (((a) > (b)) ? (a) : (b))
52*2d543d20SAndroid Build Coastguard Worker
selinux_mkload_policy(int preservebools)53*2d543d20SAndroid Build Coastguard Worker int selinux_mkload_policy(int preservebools __attribute__((unused)))
54*2d543d20SAndroid Build Coastguard Worker {
55*2d543d20SAndroid Build Coastguard Worker int kernvers = security_policyvers();
56*2d543d20SAndroid Build Coastguard Worker int maxvers = kernvers, minvers = DEFAULT_POLICY_VERSION, vers;
57*2d543d20SAndroid Build Coastguard Worker char path[PATH_MAX];
58*2d543d20SAndroid Build Coastguard Worker struct stat sb;
59*2d543d20SAndroid Build Coastguard Worker size_t size;
60*2d543d20SAndroid Build Coastguard Worker void *map, *data;
61*2d543d20SAndroid Build Coastguard Worker int fd, rc = -1;
62*2d543d20SAndroid Build Coastguard Worker sepol_policydb_t *policydb;
63*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_t *pf;
64*2d543d20SAndroid Build Coastguard Worker int usesepol = 0;
65*2d543d20SAndroid Build Coastguard Worker int (*vers_max)(void) = NULL;
66*2d543d20SAndroid Build Coastguard Worker int (*vers_min)(void) = NULL;
67*2d543d20SAndroid Build Coastguard Worker int (*policy_file_create)(sepol_policy_file_t **) = NULL;
68*2d543d20SAndroid Build Coastguard Worker void (*policy_file_free)(sepol_policy_file_t *) = NULL;
69*2d543d20SAndroid Build Coastguard Worker void (*policy_file_set_mem)(sepol_policy_file_t *, char*, size_t) = NULL;
70*2d543d20SAndroid Build Coastguard Worker int (*policydb_create)(sepol_policydb_t **) = NULL;
71*2d543d20SAndroid Build Coastguard Worker void (*policydb_free)(sepol_policydb_t *) = NULL;
72*2d543d20SAndroid Build Coastguard Worker int (*policydb_read)(sepol_policydb_t *, sepol_policy_file_t *) = NULL;
73*2d543d20SAndroid Build Coastguard Worker int (*policydb_set_vers)(sepol_policydb_t *, unsigned int) = NULL;
74*2d543d20SAndroid Build Coastguard Worker int (*policydb_to_image)(sepol_handle_t *, sepol_policydb_t *, void **, size_t *) = NULL;
75*2d543d20SAndroid Build Coastguard Worker
76*2d543d20SAndroid Build Coastguard Worker #ifdef SHARED
77*2d543d20SAndroid Build Coastguard Worker char *errormsg = NULL;
78*2d543d20SAndroid Build Coastguard Worker void *libsepolh = NULL;
79*2d543d20SAndroid Build Coastguard Worker libsepolh = dlopen("libsepol.so.2", RTLD_NOW);
80*2d543d20SAndroid Build Coastguard Worker if (libsepolh) {
81*2d543d20SAndroid Build Coastguard Worker usesepol = 1;
82*2d543d20SAndroid Build Coastguard Worker dlerror();
83*2d543d20SAndroid Build Coastguard Worker #define DLERR() do { if ((errormsg = dlerror())) goto dlclose; } while (0)
84*2d543d20SAndroid Build Coastguard Worker vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
85*2d543d20SAndroid Build Coastguard Worker DLERR();
86*2d543d20SAndroid Build Coastguard Worker vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
87*2d543d20SAndroid Build Coastguard Worker DLERR();
88*2d543d20SAndroid Build Coastguard Worker
89*2d543d20SAndroid Build Coastguard Worker policy_file_create = dlsym(libsepolh, "sepol_policy_file_create");
90*2d543d20SAndroid Build Coastguard Worker DLERR();
91*2d543d20SAndroid Build Coastguard Worker policy_file_free = dlsym(libsepolh, "sepol_policy_file_free");
92*2d543d20SAndroid Build Coastguard Worker DLERR();
93*2d543d20SAndroid Build Coastguard Worker policy_file_set_mem = dlsym(libsepolh, "sepol_policy_file_set_mem");
94*2d543d20SAndroid Build Coastguard Worker DLERR();
95*2d543d20SAndroid Build Coastguard Worker policydb_create = dlsym(libsepolh, "sepol_policydb_create");
96*2d543d20SAndroid Build Coastguard Worker DLERR();
97*2d543d20SAndroid Build Coastguard Worker policydb_free = dlsym(libsepolh, "sepol_policydb_free");
98*2d543d20SAndroid Build Coastguard Worker DLERR();
99*2d543d20SAndroid Build Coastguard Worker policydb_read = dlsym(libsepolh, "sepol_policydb_read");
100*2d543d20SAndroid Build Coastguard Worker DLERR();
101*2d543d20SAndroid Build Coastguard Worker policydb_set_vers = dlsym(libsepolh, "sepol_policydb_set_vers");
102*2d543d20SAndroid Build Coastguard Worker DLERR();
103*2d543d20SAndroid Build Coastguard Worker policydb_to_image = dlsym(libsepolh, "sepol_policydb_to_image");
104*2d543d20SAndroid Build Coastguard Worker DLERR();
105*2d543d20SAndroid Build Coastguard Worker #undef DLERR
106*2d543d20SAndroid Build Coastguard Worker }
107*2d543d20SAndroid Build Coastguard Worker #else
108*2d543d20SAndroid Build Coastguard Worker usesepol = 1;
109*2d543d20SAndroid Build Coastguard Worker vers_max = sepol_policy_kern_vers_max;
110*2d543d20SAndroid Build Coastguard Worker vers_min = sepol_policy_kern_vers_min;
111*2d543d20SAndroid Build Coastguard Worker policy_file_create = sepol_policy_file_create;
112*2d543d20SAndroid Build Coastguard Worker policy_file_free = sepol_policy_file_free;
113*2d543d20SAndroid Build Coastguard Worker policy_file_set_mem = sepol_policy_file_set_mem;
114*2d543d20SAndroid Build Coastguard Worker policydb_create = sepol_policydb_create;
115*2d543d20SAndroid Build Coastguard Worker policydb_free = sepol_policydb_free;
116*2d543d20SAndroid Build Coastguard Worker policydb_read = sepol_policydb_read;
117*2d543d20SAndroid Build Coastguard Worker policydb_set_vers = sepol_policydb_set_vers;
118*2d543d20SAndroid Build Coastguard Worker policydb_to_image = sepol_policydb_to_image;
119*2d543d20SAndroid Build Coastguard Worker #endif
120*2d543d20SAndroid Build Coastguard Worker
121*2d543d20SAndroid Build Coastguard Worker if (usesepol) {
122*2d543d20SAndroid Build Coastguard Worker maxvers = max(kernvers, vers_max());
123*2d543d20SAndroid Build Coastguard Worker minvers = vers_min();
124*2d543d20SAndroid Build Coastguard Worker }
125*2d543d20SAndroid Build Coastguard Worker
126*2d543d20SAndroid Build Coastguard Worker vers = maxvers;
127*2d543d20SAndroid Build Coastguard Worker search:
128*2d543d20SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "%s.%d",
129*2d543d20SAndroid Build Coastguard Worker selinux_binary_policy_path(), vers);
130*2d543d20SAndroid Build Coastguard Worker fd = open(path, O_RDONLY | O_CLOEXEC);
131*2d543d20SAndroid Build Coastguard Worker while (fd < 0 && errno == ENOENT
132*2d543d20SAndroid Build Coastguard Worker && --vers >= minvers) {
133*2d543d20SAndroid Build Coastguard Worker /* Check prior versions to see if old policy is available */
134*2d543d20SAndroid Build Coastguard Worker snprintf(path, sizeof(path), "%s.%d",
135*2d543d20SAndroid Build Coastguard Worker selinux_binary_policy_path(), vers);
136*2d543d20SAndroid Build Coastguard Worker fd = open(path, O_RDONLY | O_CLOEXEC);
137*2d543d20SAndroid Build Coastguard Worker }
138*2d543d20SAndroid Build Coastguard Worker if (fd < 0) {
139*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
140*2d543d20SAndroid Build Coastguard Worker "SELinux: Could not open policy file <= %s.%d: %m\n",
141*2d543d20SAndroid Build Coastguard Worker selinux_binary_policy_path(), maxvers);
142*2d543d20SAndroid Build Coastguard Worker goto dlclose;
143*2d543d20SAndroid Build Coastguard Worker }
144*2d543d20SAndroid Build Coastguard Worker
145*2d543d20SAndroid Build Coastguard Worker if (fstat(fd, &sb) < 0) {
146*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
147*2d543d20SAndroid Build Coastguard Worker "SELinux: Could not stat policy file %s: %m\n",
148*2d543d20SAndroid Build Coastguard Worker path);
149*2d543d20SAndroid Build Coastguard Worker goto close;
150*2d543d20SAndroid Build Coastguard Worker }
151*2d543d20SAndroid Build Coastguard Worker
152*2d543d20SAndroid Build Coastguard Worker size = sb.st_size;
153*2d543d20SAndroid Build Coastguard Worker data = map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
154*2d543d20SAndroid Build Coastguard Worker if (map == MAP_FAILED) {
155*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
156*2d543d20SAndroid Build Coastguard Worker "SELinux: Could not map policy file %s: %m\n",
157*2d543d20SAndroid Build Coastguard Worker path);
158*2d543d20SAndroid Build Coastguard Worker goto close;
159*2d543d20SAndroid Build Coastguard Worker }
160*2d543d20SAndroid Build Coastguard Worker
161*2d543d20SAndroid Build Coastguard Worker if (vers > kernvers && usesepol) {
162*2d543d20SAndroid Build Coastguard Worker /* Need to downgrade to kernel-supported version. */
163*2d543d20SAndroid Build Coastguard Worker if (policy_file_create(&pf))
164*2d543d20SAndroid Build Coastguard Worker goto unmap;
165*2d543d20SAndroid Build Coastguard Worker if (policydb_create(&policydb)) {
166*2d543d20SAndroid Build Coastguard Worker policy_file_free(pf);
167*2d543d20SAndroid Build Coastguard Worker goto unmap;
168*2d543d20SAndroid Build Coastguard Worker }
169*2d543d20SAndroid Build Coastguard Worker policy_file_set_mem(pf, data, size);
170*2d543d20SAndroid Build Coastguard Worker if (policydb_read(policydb, pf)) {
171*2d543d20SAndroid Build Coastguard Worker policy_file_free(pf);
172*2d543d20SAndroid Build Coastguard Worker policydb_free(policydb);
173*2d543d20SAndroid Build Coastguard Worker goto unmap;
174*2d543d20SAndroid Build Coastguard Worker }
175*2d543d20SAndroid Build Coastguard Worker if (policydb_set_vers(policydb, kernvers) ||
176*2d543d20SAndroid Build Coastguard Worker policydb_to_image(NULL, policydb, &data, &size)) {
177*2d543d20SAndroid Build Coastguard Worker /* Downgrade failed, keep searching. */
178*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
179*2d543d20SAndroid Build Coastguard Worker "SELinux: Could not downgrade policy file %s, searching for an older version.\n",
180*2d543d20SAndroid Build Coastguard Worker path);
181*2d543d20SAndroid Build Coastguard Worker policy_file_free(pf);
182*2d543d20SAndroid Build Coastguard Worker policydb_free(policydb);
183*2d543d20SAndroid Build Coastguard Worker munmap(map, sb.st_size);
184*2d543d20SAndroid Build Coastguard Worker close(fd);
185*2d543d20SAndroid Build Coastguard Worker vers--;
186*2d543d20SAndroid Build Coastguard Worker goto search;
187*2d543d20SAndroid Build Coastguard Worker }
188*2d543d20SAndroid Build Coastguard Worker policy_file_free(pf);
189*2d543d20SAndroid Build Coastguard Worker policydb_free(policydb);
190*2d543d20SAndroid Build Coastguard Worker }
191*2d543d20SAndroid Build Coastguard Worker
192*2d543d20SAndroid Build Coastguard Worker rc = security_load_policy(data, size);
193*2d543d20SAndroid Build Coastguard Worker
194*2d543d20SAndroid Build Coastguard Worker if (rc)
195*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
196*2d543d20SAndroid Build Coastguard Worker "SELinux: Could not load policy file %s: %m\n",
197*2d543d20SAndroid Build Coastguard Worker path);
198*2d543d20SAndroid Build Coastguard Worker
199*2d543d20SAndroid Build Coastguard Worker unmap:
200*2d543d20SAndroid Build Coastguard Worker if (data != map)
201*2d543d20SAndroid Build Coastguard Worker free(data);
202*2d543d20SAndroid Build Coastguard Worker munmap(map, sb.st_size);
203*2d543d20SAndroid Build Coastguard Worker close:
204*2d543d20SAndroid Build Coastguard Worker close(fd);
205*2d543d20SAndroid Build Coastguard Worker dlclose:
206*2d543d20SAndroid Build Coastguard Worker #ifdef SHARED
207*2d543d20SAndroid Build Coastguard Worker if (errormsg)
208*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "libselinux: %s\n", errormsg);
209*2d543d20SAndroid Build Coastguard Worker if (libsepolh)
210*2d543d20SAndroid Build Coastguard Worker dlclose(libsepolh);
211*2d543d20SAndroid Build Coastguard Worker #endif
212*2d543d20SAndroid Build Coastguard Worker return rc;
213*2d543d20SAndroid Build Coastguard Worker }
214*2d543d20SAndroid Build Coastguard Worker
215*2d543d20SAndroid Build Coastguard Worker
216*2d543d20SAndroid Build Coastguard Worker /*
217*2d543d20SAndroid Build Coastguard Worker * Mount point for selinuxfs.
218*2d543d20SAndroid Build Coastguard Worker * This definition is private to the function below.
219*2d543d20SAndroid Build Coastguard Worker * Everything else uses the location determined during
220*2d543d20SAndroid Build Coastguard Worker * libselinux startup via /proc/mounts (see init_selinuxmnt).
221*2d543d20SAndroid Build Coastguard Worker * We only need the hardcoded definition for the initial mount
222*2d543d20SAndroid Build Coastguard Worker * required for the initial policy load.
223*2d543d20SAndroid Build Coastguard Worker */
selinux_init_load_policy(int * enforce)224*2d543d20SAndroid Build Coastguard Worker int selinux_init_load_policy(int *enforce)
225*2d543d20SAndroid Build Coastguard Worker {
226*2d543d20SAndroid Build Coastguard Worker int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1;
227*2d543d20SAndroid Build Coastguard Worker FILE *cfg;
228*2d543d20SAndroid Build Coastguard Worker char *buf;
229*2d543d20SAndroid Build Coastguard Worker
230*2d543d20SAndroid Build Coastguard Worker /*
231*2d543d20SAndroid Build Coastguard Worker * Reread the selinux configuration in case it has changed.
232*2d543d20SAndroid Build Coastguard Worker * Example: Caller has chroot'd and is now loading policy from
233*2d543d20SAndroid Build Coastguard Worker * chroot'd environment.
234*2d543d20SAndroid Build Coastguard Worker */
235*2d543d20SAndroid Build Coastguard Worker selinux_reset_config();
236*2d543d20SAndroid Build Coastguard Worker
237*2d543d20SAndroid Build Coastguard Worker /*
238*2d543d20SAndroid Build Coastguard Worker * Get desired mode (disabled, permissive, enforcing) from
239*2d543d20SAndroid Build Coastguard Worker * /etc/selinux/config.
240*2d543d20SAndroid Build Coastguard Worker */
241*2d543d20SAndroid Build Coastguard Worker selinux_getenforcemode(&seconfig);
242*2d543d20SAndroid Build Coastguard Worker
243*2d543d20SAndroid Build Coastguard Worker /* Check for an override of the mode via the kernel command line. */
244*2d543d20SAndroid Build Coastguard Worker rc = mount("proc", "/proc", "proc", 0, 0);
245*2d543d20SAndroid Build Coastguard Worker cfg = fopen("/proc/cmdline", "re");
246*2d543d20SAndroid Build Coastguard Worker if (cfg) {
247*2d543d20SAndroid Build Coastguard Worker char *tmp;
248*2d543d20SAndroid Build Coastguard Worker buf = malloc(selinux_page_size);
249*2d543d20SAndroid Build Coastguard Worker if (!buf) {
250*2d543d20SAndroid Build Coastguard Worker fclose(cfg);
251*2d543d20SAndroid Build Coastguard Worker return -1;
252*2d543d20SAndroid Build Coastguard Worker }
253*2d543d20SAndroid Build Coastguard Worker if (fgets(buf, selinux_page_size, cfg) &&
254*2d543d20SAndroid Build Coastguard Worker (tmp = strstr(buf, "enforcing="))) {
255*2d543d20SAndroid Build Coastguard Worker if (tmp == buf || isspace((unsigned char)*(tmp - 1))) {
256*2d543d20SAndroid Build Coastguard Worker secmdline =
257*2d543d20SAndroid Build Coastguard Worker atoi(tmp + sizeof("enforcing=") - 1);
258*2d543d20SAndroid Build Coastguard Worker }
259*2d543d20SAndroid Build Coastguard Worker }
260*2d543d20SAndroid Build Coastguard Worker fclose(cfg);
261*2d543d20SAndroid Build Coastguard Worker free(buf);
262*2d543d20SAndroid Build Coastguard Worker }
263*2d543d20SAndroid Build Coastguard Worker
264*2d543d20SAndroid Build Coastguard Worker /*
265*2d543d20SAndroid Build Coastguard Worker * Determine the final desired mode.
266*2d543d20SAndroid Build Coastguard Worker * Command line argument takes precedence, then config file.
267*2d543d20SAndroid Build Coastguard Worker */
268*2d543d20SAndroid Build Coastguard Worker if (secmdline >= 0)
269*2d543d20SAndroid Build Coastguard Worker *enforce = secmdline;
270*2d543d20SAndroid Build Coastguard Worker else if (seconfig >= 0)
271*2d543d20SAndroid Build Coastguard Worker *enforce = seconfig;
272*2d543d20SAndroid Build Coastguard Worker else
273*2d543d20SAndroid Build Coastguard Worker *enforce = 0; /* unspecified or disabled */
274*2d543d20SAndroid Build Coastguard Worker
275*2d543d20SAndroid Build Coastguard Worker /*
276*2d543d20SAndroid Build Coastguard Worker * Check for the existence of SELinux via selinuxfs, and
277*2d543d20SAndroid Build Coastguard Worker * mount it if present for use in the calls below.
278*2d543d20SAndroid Build Coastguard Worker */
279*2d543d20SAndroid Build Coastguard Worker const char *mntpoint = NULL;
280*2d543d20SAndroid Build Coastguard Worker /* First make sure /sys is mounted */
281*2d543d20SAndroid Build Coastguard Worker if (mount("sysfs", "/sys", "sysfs", 0, 0) == 0 || errno == EBUSY) {
282*2d543d20SAndroid Build Coastguard Worker /* MS_NODEV can't be set because of /sys/fs/selinux/null device, used by Android */
283*2d543d20SAndroid Build Coastguard Worker if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, MS_NOEXEC | MS_NOSUID, 0) == 0 || errno == EBUSY) {
284*2d543d20SAndroid Build Coastguard Worker mntpoint = SELINUXMNT;
285*2d543d20SAndroid Build Coastguard Worker } else {
286*2d543d20SAndroid Build Coastguard Worker /* check old mountpoint */
287*2d543d20SAndroid Build Coastguard Worker if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
288*2d543d20SAndroid Build Coastguard Worker mntpoint = OLDSELINUXMNT;
289*2d543d20SAndroid Build Coastguard Worker }
290*2d543d20SAndroid Build Coastguard Worker }
291*2d543d20SAndroid Build Coastguard Worker } else {
292*2d543d20SAndroid Build Coastguard Worker /* check old mountpoint */
293*2d543d20SAndroid Build Coastguard Worker if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
294*2d543d20SAndroid Build Coastguard Worker mntpoint = OLDSELINUXMNT;
295*2d543d20SAndroid Build Coastguard Worker }
296*2d543d20SAndroid Build Coastguard Worker }
297*2d543d20SAndroid Build Coastguard Worker
298*2d543d20SAndroid Build Coastguard Worker if (! mntpoint ) {
299*2d543d20SAndroid Build Coastguard Worker if (errno == ENODEV || !selinuxfs_exists()) {
300*2d543d20SAndroid Build Coastguard Worker /*
301*2d543d20SAndroid Build Coastguard Worker * SELinux was disabled in the kernel, either
302*2d543d20SAndroid Build Coastguard Worker * omitted entirely or disabled at boot via selinux=0.
303*2d543d20SAndroid Build Coastguard Worker * This takes precedence over any config or
304*2d543d20SAndroid Build Coastguard Worker * commandline enforcing setting.
305*2d543d20SAndroid Build Coastguard Worker */
306*2d543d20SAndroid Build Coastguard Worker *enforce = 0;
307*2d543d20SAndroid Build Coastguard Worker } else {
308*2d543d20SAndroid Build Coastguard Worker /* Only emit this error if selinux was not disabled */
309*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "Mount failed for selinuxfs on %s: %m\n", SELINUXMNT);
310*2d543d20SAndroid Build Coastguard Worker }
311*2d543d20SAndroid Build Coastguard Worker
312*2d543d20SAndroid Build Coastguard Worker if (rc == 0)
313*2d543d20SAndroid Build Coastguard Worker umount2("/proc", MNT_DETACH);
314*2d543d20SAndroid Build Coastguard Worker
315*2d543d20SAndroid Build Coastguard Worker goto noload;
316*2d543d20SAndroid Build Coastguard Worker }
317*2d543d20SAndroid Build Coastguard Worker set_selinuxmnt(mntpoint);
318*2d543d20SAndroid Build Coastguard Worker
319*2d543d20SAndroid Build Coastguard Worker if (rc == 0)
320*2d543d20SAndroid Build Coastguard Worker umount2("/proc", MNT_DETACH);
321*2d543d20SAndroid Build Coastguard Worker
322*2d543d20SAndroid Build Coastguard Worker /*
323*2d543d20SAndroid Build Coastguard Worker * Note: The following code depends on having selinuxfs
324*2d543d20SAndroid Build Coastguard Worker * already mounted and selinuxmnt set above.
325*2d543d20SAndroid Build Coastguard Worker */
326*2d543d20SAndroid Build Coastguard Worker
327*2d543d20SAndroid Build Coastguard Worker if (seconfig == -1) {
328*2d543d20SAndroid Build Coastguard Worker /* Runtime disable of SELinux. */
329*2d543d20SAndroid Build Coastguard Worker IGNORE_DEPRECATED_DECLARATION_BEGIN
330*2d543d20SAndroid Build Coastguard Worker rc = security_disable();
331*2d543d20SAndroid Build Coastguard Worker IGNORE_DEPRECATED_DECLARATION_END
332*2d543d20SAndroid Build Coastguard Worker if (rc == 0) {
333*2d543d20SAndroid Build Coastguard Worker /* Successfully disabled, so umount selinuxfs too. */
334*2d543d20SAndroid Build Coastguard Worker umount(selinux_mnt);
335*2d543d20SAndroid Build Coastguard Worker fini_selinuxmnt();
336*2d543d20SAndroid Build Coastguard Worker goto noload;
337*2d543d20SAndroid Build Coastguard Worker } else {
338*2d543d20SAndroid Build Coastguard Worker /*
339*2d543d20SAndroid Build Coastguard Worker * It's possible that this failed because policy has
340*2d543d20SAndroid Build Coastguard Worker * already been loaded. We can't disable SELinux now,
341*2d543d20SAndroid Build Coastguard Worker * so the best we can do is force it to be permissive.
342*2d543d20SAndroid Build Coastguard Worker */
343*2d543d20SAndroid Build Coastguard Worker *enforce = 0;
344*2d543d20SAndroid Build Coastguard Worker }
345*2d543d20SAndroid Build Coastguard Worker }
346*2d543d20SAndroid Build Coastguard Worker
347*2d543d20SAndroid Build Coastguard Worker /*
348*2d543d20SAndroid Build Coastguard Worker * If necessary, change the kernel enforcing status to match
349*2d543d20SAndroid Build Coastguard Worker * the desired mode.
350*2d543d20SAndroid Build Coastguard Worker */
351*2d543d20SAndroid Build Coastguard Worker orig_enforce = rc = security_getenforce();
352*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
353*2d543d20SAndroid Build Coastguard Worker goto noload;
354*2d543d20SAndroid Build Coastguard Worker if (orig_enforce != *enforce) {
355*2d543d20SAndroid Build Coastguard Worker rc = security_setenforce(*enforce);
356*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
357*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "SELinux: Unable to switch to %s mode: %m\n", (*enforce ? "enforcing" : "permissive"));
358*2d543d20SAndroid Build Coastguard Worker if (*enforce)
359*2d543d20SAndroid Build Coastguard Worker goto noload;
360*2d543d20SAndroid Build Coastguard Worker }
361*2d543d20SAndroid Build Coastguard Worker }
362*2d543d20SAndroid Build Coastguard Worker
363*2d543d20SAndroid Build Coastguard Worker if (seconfig == -1) {
364*2d543d20SAndroid Build Coastguard Worker umount(selinux_mnt);
365*2d543d20SAndroid Build Coastguard Worker fini_selinuxmnt();
366*2d543d20SAndroid Build Coastguard Worker goto noload;
367*2d543d20SAndroid Build Coastguard Worker }
368*2d543d20SAndroid Build Coastguard Worker
369*2d543d20SAndroid Build Coastguard Worker /* Load the policy. */
370*2d543d20SAndroid Build Coastguard Worker return selinux_mkload_policy(0);
371*2d543d20SAndroid Build Coastguard Worker
372*2d543d20SAndroid Build Coastguard Worker noload:
373*2d543d20SAndroid Build Coastguard Worker /*
374*2d543d20SAndroid Build Coastguard Worker * Only return 0 on a successful completion of policy load.
375*2d543d20SAndroid Build Coastguard Worker * In any other case, we want to return an error so that init
376*2d543d20SAndroid Build Coastguard Worker * knows not to proceed with the re-exec for the domain transition.
377*2d543d20SAndroid Build Coastguard Worker * Depending on the *enforce setting, init will halt (> 0) or proceed
378*2d543d20SAndroid Build Coastguard Worker * normally (otherwise).
379*2d543d20SAndroid Build Coastguard Worker */
380*2d543d20SAndroid Build Coastguard Worker return -1;
381*2d543d20SAndroid Build Coastguard Worker }
382*2d543d20SAndroid Build Coastguard Worker #endif
383