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