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