113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <unistd.h>
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/types.h>
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/stat.h>
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/mman.h>
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/mount.h>
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/utsname.h>
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <fcntl.h>
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h>
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h>
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <ctype.h>
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h>
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h>
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "selinux_internal.h"
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/sepol.h>
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/policydb.h>
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <dlfcn.h>
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "policy.h"
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <limits.h>
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint security_load_policy(void *data, size_t len)
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char path[PATH_MAX];
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int fd, ret;
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (!selinux_mnt) {
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		errno = ENOENT;
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	snprintf(path, sizeof path, "%s/load", selinux_mnt);
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	fd = open(path, O_RDWR);
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fd < 0)
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	ret = write(fd, data, len);
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	close(fd);
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (ret < 0)
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		return -1;
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return 0;
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(security_load_policy)
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint load_setlocaldefs hidden = 1;
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#undef max
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define max(a, b) (((a) > (b)) ? (a) : (b))
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint selinux_mkload_policy(int preservebools)
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int kernvers = security_policyvers();
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int maxvers = kernvers, minvers = DEFAULT_POLICY_VERSION, vers;
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int setlocaldefs = load_setlocaldefs;
544611c09d6b22ff2aebb55388d777bcf8921dd50bStephen Smalley	char path[PATH_MAX];
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	struct stat sb;
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	struct utsname uts;
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size_t size;
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	void *map, *data;
594611c09d6b22ff2aebb55388d777bcf8921dd50bStephen Smalley	int fd, rc = -1, prot;
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_policydb_t *policydb;
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sepol_policy_file_t *pf;
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int usesepol = 0;
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*vers_max)(void) = NULL;
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*vers_min)(void) = NULL;
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*policy_file_create)(sepol_policy_file_t **) = NULL;
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	void (*policy_file_free)(sepol_policy_file_t *) = NULL;
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	void (*policy_file_set_mem)(sepol_policy_file_t *, char*, size_t) = NULL;
6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*policydb_create)(sepol_policydb_t **) = NULL;
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	void (*policydb_free)(sepol_policydb_t *) = NULL;
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*policydb_read)(sepol_policydb_t *, sepol_policy_file_t *) = NULL;
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*policydb_set_vers)(sepol_policydb_t *, unsigned int) = NULL;
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*policydb_to_image)(sepol_handle_t *, sepol_policydb_t *, void **, size_t *) = NULL;
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*genbools_array)(void *data, size_t len, char **names, int *values, int nel) = NULL;
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*genusers)(void *data, size_t len, const char *usersdir, void **newdata, size_t * newlen) = NULL;
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int (*genbools)(void *data, size_t len, char *boolpath) = NULL;
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#ifdef SHARED
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *errormsg = NULL;
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	void *libsepolh = NULL;
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	libsepolh = dlopen("libsepol.so.1", RTLD_NOW);
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (libsepolh) {
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		usesepol = 1;
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dlerror();
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define DLERR() if ((errormsg = dlerror())) goto dlclose;
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policy_file_create = dlsym(libsepolh, "sepol_policy_file_create");
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policy_file_free = dlsym(libsepolh, "sepol_policy_file_free");
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policy_file_set_mem = dlsym(libsepolh, "sepol_policy_file_set_mem");
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_create = dlsym(libsepolh, "sepol_policydb_create");
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_free = dlsym(libsepolh, "sepol_policydb_free");
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_read = dlsym(libsepolh, "sepol_policydb_read");
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_set_vers = dlsym(libsepolh, "sepol_policydb_set_vers");
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_to_image = dlsym(libsepolh, "sepol_policydb_to_image");
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		genbools_array = dlsym(libsepolh, "sepol_genbools_array");
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		genusers = dlsym(libsepolh, "sepol_genusers");
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		genbools = dlsym(libsepolh, "sepol_genbools");
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		DLERR();
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#undef DLERR
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#else
11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	usesepol = 1;
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	vers_max = sepol_policy_kern_vers_max;
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	vers_min = sepol_policy_kern_vers_min;
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policy_file_create = sepol_policy_file_create;
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policy_file_free = sepol_policy_file_free;
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policy_file_set_mem = sepol_policy_file_set_mem;
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policydb_create = sepol_policydb_create;
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policydb_free = sepol_policydb_free;
12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policydb_read = sepol_policydb_read;
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policydb_set_vers = sepol_policydb_set_vers;
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	policydb_to_image = sepol_policydb_to_image;
12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	genbools_array = sepol_genbools_array;
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	genusers = sepol_genusers;
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	genbools = sepol_genbools;
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#endif
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Check whether we need to support local boolean and user definitions.
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (setlocaldefs) {
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (access(selinux_booleans_path(), F_OK) == 0)
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto checkbool;
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		snprintf(path, sizeof path, "%s.local", selinux_booleans_path());
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (access(path, F_OK) == 0)
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto checkbool;
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		snprintf(path, sizeof path, "%s/local.users", selinux_users_path());
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (access(path, F_OK) == 0)
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto checkbool;
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		/* No local definition files, so disable setlocaldefs. */
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		setlocaldefs = 0;
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlecheckbool:
15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * As of Linux 2.6.22, the kernel preserves boolean
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * values across a reload, so we do not need to
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * preserve them in userspace.
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (preservebools && uname(&uts) == 0 && strverscmp(uts.release, "2.6.22") >= 0)
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		preservebools = 0;
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (usesepol) {
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		maxvers = vers_max();
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		minvers = vers_min();
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!setlocaldefs && !preservebools)
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			maxvers = max(kernvers, maxvers);
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	vers = maxvers;
16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      search:
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	snprintf(path, sizeof(path), "%s.%d",
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		 selinux_binary_policy_path(), vers);
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	fd = open(path, O_RDONLY);
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	while (fd < 0 && errno == ENOENT
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	       && --vers >= minvers) {
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		/* Check prior versions to see if old policy is available */
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		snprintf(path, sizeof(path), "%s.%d",
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			 selinux_binary_policy_path(), vers);
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fd = open(path, O_RDONLY);
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fd < 0) {
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr,
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			"SELinux:  Could not open policy file <= %s.%d:  %s\n",
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			selinux_binary_policy_path(), maxvers, strerror(errno));
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto dlclose;
18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (fstat(fd, &sb) < 0) {
18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr,
18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			"SELinux:  Could not stat policy file %s:  %s\n",
18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			path, strerror(errno));
18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto close;
18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	prot = PROT_READ;
19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (setlocaldefs || preservebools)
19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		prot |= PROT_WRITE;
19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	size = sb.st_size;
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0);
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (map == MAP_FAILED) {
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr,
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			"SELinux:  Could not map policy file %s:  %s\n",
20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			path, strerror(errno));
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto close;
20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (vers > kernvers && usesepol) {
20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		/* Need to downgrade to kernel-supported version. */
20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (policy_file_create(&pf))
20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto unmap;
20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (policydb_create(&policydb)) {
20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			policy_file_free(pf);
21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto unmap;
21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policy_file_set_mem(pf, data, size);
21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (policydb_read(policydb, pf)) {
21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			policy_file_free(pf);
21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			policydb_free(policydb);
21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto unmap;
21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (policydb_set_vers(policydb, kernvers) ||
21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    policydb_to_image(NULL, policydb, &data, &size)) {
22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			/* Downgrade failed, keep searching. */
22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr,
22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				"SELinux:  Could not downgrade policy file %s, searching for an older version.\n",
22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				path);
22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			policy_file_free(pf);
22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			policydb_free(policydb);
22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			munmap(map, sb.st_size);
22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			close(fd);
22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			vers--;
22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			goto search;
23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policy_file_free(pf);
23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		policydb_free(policydb);
23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (usesepol) {
23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (setlocaldefs) {
23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			void *olddata = data;
23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			size_t oldsize = size;
23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			rc = genusers(olddata, oldsize, selinux_users_path(),
24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				      &data, &size);
24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (rc < 0) {
24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				/* Fall back to the prior image if genusers failed. */
24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				data = olddata;
24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				size = oldsize;
24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				rc = 0;
24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			} else {
24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				if (olddata != map)
24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					free(olddata);
24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#ifndef DISABLE_BOOL
25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (preservebools) {
2544611c09d6b22ff2aebb55388d777bcf8921dd50bStephen Smalley			int *values, len, i;
2554611c09d6b22ff2aebb55388d777bcf8921dd50bStephen Smalley			char **names;
25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			rc = security_get_boolean_names(&names, &len);
25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (!rc) {
25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				values = malloc(sizeof(int) * len);
25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				if (!values)
26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					goto unmap;
26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				for (i = 0; i < len; i++)
26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					values[i] =
26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						security_get_boolean_active(names[i]);
26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				(void)genbools_array(data, size, names, values,
26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle						     len);
26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				free(values);
26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				for (i = 0; i < len; i++)
26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle					free(names[i]);
26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				free(names);
27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		} else if (setlocaldefs) {
27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			(void)genbools(data, size,
27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				       (char *)selinux_booleans_path());
27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#endif
27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	rc = security_load_policy(data, size);
28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (rc)
28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr,
28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			"SELinux:  Could not load policy file %s:  %s\n",
28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			path, strerror(errno));
28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      unmap:
28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (data != map)
28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		free(data);
28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	munmap(map, sb.st_size);
29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      close:
29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	close(fd);
29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      dlclose:
29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#ifdef SHARED
29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (errormsg)
29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fprintf(stderr, "libselinux:  %s\n", errormsg);
29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (libsepolh)
29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		dlclose(libsepolh);
29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#endif
29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return rc;
30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(selinux_mkload_policy)
30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/*
30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Mount point for selinuxfs.
30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This definition is private to the function below.
30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Everything else uses the location determined during
30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * libselinux startup via /proc/mounts (see init_selinuxmnt).
30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * We only need the hardcoded definition for the initial mount
31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * required for the initial policy load.
31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */
31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint selinux_init_load_policy(int *enforce)
31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{
31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1;
31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	FILE *cfg;
31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	char *buf;
31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Reread the selinux configuration in case it has changed.
32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Example:  Caller has chroot'd and is now loading policy from
32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * chroot'd environment.
32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
3237d19f9df510daef5dc929df5854c2dda2a64f475Chad Sellers	selinux_reset_config();
32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Get desired mode (disabled, permissive, enforcing) from
32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * /etc/selinux/config.
32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	selinux_getenforcemode(&seconfig);
33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Check for an override of the mode via the kernel command line. */
3325c6729b4d26fe6b3e64f9301efe6b0fa7d5c8487Daniel J Walsh	rc = mount("proc", "/proc", "proc", 0, 0);
33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	cfg = fopen("/proc/cmdline", "r");
33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (cfg) {
33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		char *tmp;
33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		buf = malloc(selinux_page_size);
33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (!buf) {
33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fclose(cfg);
33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			return -1;
34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (fgets(buf, selinux_page_size, cfg) &&
34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		    (tmp = strstr(buf, "enforcing="))) {
34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			if (tmp == buf || isspace(*(tmp - 1))) {
34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				secmdline =
34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle				    atoi(tmp + sizeof("enforcing=") - 1);
34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			}
34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		fclose(cfg);
34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		free(buf);
35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
3517610baa968ad499667c60c222cba326b737c532aStephen Smalley#ifndef MNT_DETACH
35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define MNT_DETACH 2
3537610baa968ad499667c60c222cba326b737c532aStephen Smalley#endif
35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (rc == 0)
35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		umount2("/proc", MNT_DETACH);
35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Determine the final desired mode.
35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Command line argument takes precedence, then config file.
36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (secmdline >= 0)
36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		*enforce = secmdline;
36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else if (seconfig >= 0)
36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		*enforce = seconfig;
36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	else
36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		*enforce = 0;	/* unspecified or disabled */
36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Check for the existence of SELinux via selinuxfs, and
37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * mount it if present for use in the calls below.
37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
372b82b7e02dfcd46db75a94352815830fdb651fa94Daniel P. Berrange	const char *mntpoint = NULL;
373ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen	/* First make sure /sys is mounted */
374ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen	if (mount("sysfs", "/sys", "sysfs", 0, 0) == 0 || errno == EBUSY) {
375ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen		if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
376ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen			mntpoint = SELINUXMNT;
377ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen		} else {
378ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen			/* check old mountpoint */
379ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen			if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
380ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen				mntpoint = OLDSELINUXMNT;
381ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen			}
382ef3e072f581b2418f9bb1703170ad34f32c9408dSven Vermeulen		}
383e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh	} else {
384e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh		/* check old mountpoint */
385e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh		if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) {
386e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh			mntpoint = OLDSELINUXMNT;
387e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh		}
388e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh	}
389e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh
390e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh	if (! mntpoint ) {
391b3b19fdce58ff6ddfa6dfb8e5576c922c96e1e45Eric Paris		if (errno == ENODEV || !selinuxfs_exists()) {
39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			/*
39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			 * SELinux was disabled in the kernel, either
39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			 * omitted entirely or disabled at boot via selinux=0.
39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			 * This takes precedence over any config or
39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			 * commandline enforcing setting.
39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			 */
39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			*enforce = 0;
39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		} else {
40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			/* Only emit this error if selinux was not disabled */
40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			fprintf(stderr, "Mount failed for selinuxfs on %s:  %s\n", SELINUXMNT, strerror(errno));
40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto noload;
40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
406e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh	set_selinuxmnt(mntpoint);
40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Note:  The following code depends on having selinuxfs
41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * already mounted and selinuxmnt set above.
41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (seconfig == -1) {
41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		/* Runtime disable of SELinux. */
41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		rc = security_disable();
41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		if (rc == 0) {
41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle			/* Successfully disabled, so umount selinuxfs too. */
418e3cab998b48ab293a9962faf9779d70ca339c65dDaniel J Walsh			umount(selinux_mnt);
4191629d2f89a8c5f758413b87b94740aaaa5f21144Daniel J Walsh			fini_selinuxmnt();
420241fac27288a431198ac2fa72198b5a799a91775Will Woods			goto noload;
421241fac27288a431198ac2fa72198b5a799a91775Will Woods		} else {
422241fac27288a431198ac2fa72198b5a799a91775Will Woods			/*
423241fac27288a431198ac2fa72198b5a799a91775Will Woods			 * It's possible that this failed because policy has
424241fac27288a431198ac2fa72198b5a799a91775Will Woods			 * already been loaded. We can't disable SELinux now,
425241fac27288a431198ac2fa72198b5a799a91775Will Woods			 * so the best we can do is force it to be permissive.
426241fac27288a431198ac2fa72198b5a799a91775Will Woods			 */
427241fac27288a431198ac2fa72198b5a799a91775Will Woods			*enforce = 0;
42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		}
42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * If necessary, change the kernel enforcing status to match
43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * the desired mode.
43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	orig_enforce = rc = security_getenforce();
43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (rc < 0)
43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		goto noload;
43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	if (orig_enforce != *enforce) {
43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle		rc = security_setenforce(*enforce);
440b985905d2f58836993acf03edc0395acd1f3f7f1Stephen Smalley		if (rc < 0) {
441b985905d2f58836993acf03edc0395acd1f3f7f1Stephen Smalley			fprintf(stderr, "SELinux:  Unable to switch to %s mode:  %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno));
442b985905d2f58836993acf03edc0395acd1f3f7f1Stephen Smalley			if (*enforce)
443b985905d2f58836993acf03edc0395acd1f3f7f1Stephen Smalley				goto noload;
444b985905d2f58836993acf03edc0395acd1f3f7f1Stephen Smalley		}
44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	}
44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
447241fac27288a431198ac2fa72198b5a799a91775Will Woods	if (seconfig == -1)
448241fac27288a431198ac2fa72198b5a799a91775Will Woods		goto noload;
449241fac27288a431198ac2fa72198b5a799a91775Will Woods
45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/* Load the policy. */
45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return selinux_mkload_policy(0);
45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle      noload:
45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	/*
45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Only return 0 on a successful completion of policy load.
45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * In any other case, we want to return an error so that init
45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * knows not to proceed with the re-exec for the domain transition.
45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * Depending on the *enforce setting, init will halt (> 0) or proceed
45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 * normally (otherwise).
46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	 */
46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	return -1;
46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle}
463