16cd6a6acSopenharmony_ci#include <unistd.h> 26cd6a6acSopenharmony_ci#include <sys/types.h> 36cd6a6acSopenharmony_ci#include <sys/stat.h> 46cd6a6acSopenharmony_ci#include <sys/mman.h> 56cd6a6acSopenharmony_ci#include <sys/mount.h> 66cd6a6acSopenharmony_ci#include <sys/utsname.h> 76cd6a6acSopenharmony_ci#include <fcntl.h> 86cd6a6acSopenharmony_ci#include <stdlib.h> 96cd6a6acSopenharmony_ci#include <stdio.h> 106cd6a6acSopenharmony_ci#include <ctype.h> 116cd6a6acSopenharmony_ci#include <string.h> 126cd6a6acSopenharmony_ci#include <errno.h> 136cd6a6acSopenharmony_ci#include "selinux_internal.h" 146cd6a6acSopenharmony_ci#ifndef ANDROID 156cd6a6acSopenharmony_ci#include <sepol/sepol.h> 166cd6a6acSopenharmony_ci#include <sepol/policydb.h> 176cd6a6acSopenharmony_ci#endif 186cd6a6acSopenharmony_ci#include <dlfcn.h> 196cd6a6acSopenharmony_ci#include "policy.h" 206cd6a6acSopenharmony_ci#include <limits.h> 216cd6a6acSopenharmony_ci 226cd6a6acSopenharmony_ci#ifndef MNT_DETACH 236cd6a6acSopenharmony_ci#define MNT_DETACH 2 246cd6a6acSopenharmony_ci#endif 256cd6a6acSopenharmony_ci 266cd6a6acSopenharmony_ciint security_load_policy(const void *data, size_t len) 276cd6a6acSopenharmony_ci{ 286cd6a6acSopenharmony_ci char path[PATH_MAX]; 296cd6a6acSopenharmony_ci int fd, ret; 306cd6a6acSopenharmony_ci 316cd6a6acSopenharmony_ci if (!selinux_mnt) { 326cd6a6acSopenharmony_ci errno = ENOENT; 336cd6a6acSopenharmony_ci return -1; 346cd6a6acSopenharmony_ci } 356cd6a6acSopenharmony_ci 366cd6a6acSopenharmony_ci snprintf(path, sizeof path, "%s/load", selinux_mnt); 376cd6a6acSopenharmony_ci fd = open(path, O_RDWR | O_CLOEXEC); 386cd6a6acSopenharmony_ci if (fd < 0) 396cd6a6acSopenharmony_ci return -1; 406cd6a6acSopenharmony_ci 416cd6a6acSopenharmony_ci ret = write(fd, data, len); 426cd6a6acSopenharmony_ci close(fd); 436cd6a6acSopenharmony_ci if (ret < 0) 446cd6a6acSopenharmony_ci return -1; 456cd6a6acSopenharmony_ci return 0; 466cd6a6acSopenharmony_ci} 476cd6a6acSopenharmony_ci 486cd6a6acSopenharmony_ci 496cd6a6acSopenharmony_ci#ifndef ANDROID 506cd6a6acSopenharmony_ci#undef max 516cd6a6acSopenharmony_ci#define max(a, b) (((a) > (b)) ? (a) : (b)) 526cd6a6acSopenharmony_ci 536cd6a6acSopenharmony_ciint selinux_mkload_policy(int preservebools __attribute__((unused))) 546cd6a6acSopenharmony_ci{ 556cd6a6acSopenharmony_ci int kernvers = security_policyvers(); 566cd6a6acSopenharmony_ci int maxvers = kernvers, minvers = DEFAULT_POLICY_VERSION, vers; 576cd6a6acSopenharmony_ci char path[PATH_MAX]; 586cd6a6acSopenharmony_ci struct stat sb; 596cd6a6acSopenharmony_ci size_t size; 606cd6a6acSopenharmony_ci void *map, *data; 616cd6a6acSopenharmony_ci int fd, rc = -1; 626cd6a6acSopenharmony_ci sepol_policydb_t *policydb; 636cd6a6acSopenharmony_ci sepol_policy_file_t *pf; 646cd6a6acSopenharmony_ci int usesepol = 0; 656cd6a6acSopenharmony_ci int (*vers_max)(void) = NULL; 666cd6a6acSopenharmony_ci int (*vers_min)(void) = NULL; 676cd6a6acSopenharmony_ci int (*policy_file_create)(sepol_policy_file_t **) = NULL; 686cd6a6acSopenharmony_ci void (*policy_file_free)(sepol_policy_file_t *) = NULL; 696cd6a6acSopenharmony_ci void (*policy_file_set_mem)(sepol_policy_file_t *, char*, size_t) = NULL; 706cd6a6acSopenharmony_ci int (*policydb_create)(sepol_policydb_t **) = NULL; 716cd6a6acSopenharmony_ci void (*policydb_free)(sepol_policydb_t *) = NULL; 726cd6a6acSopenharmony_ci int (*policydb_read)(sepol_policydb_t *, sepol_policy_file_t *) = NULL; 736cd6a6acSopenharmony_ci int (*policydb_set_vers)(sepol_policydb_t *, unsigned int) = NULL; 746cd6a6acSopenharmony_ci int (*policydb_to_image)(sepol_handle_t *, sepol_policydb_t *, void **, size_t *) = NULL; 756cd6a6acSopenharmony_ci 766cd6a6acSopenharmony_ci#ifdef SHARED 776cd6a6acSopenharmony_ci char *errormsg = NULL; 786cd6a6acSopenharmony_ci void *libsepolh = NULL; 796cd6a6acSopenharmony_ci libsepolh = dlopen("libsepol.so.2", RTLD_NOW); 806cd6a6acSopenharmony_ci if (libsepolh) { 816cd6a6acSopenharmony_ci usesepol = 1; 826cd6a6acSopenharmony_ci dlerror(); 836cd6a6acSopenharmony_ci#define DLERR() do { if ((errormsg = dlerror())) goto dlclose; } while (0) 846cd6a6acSopenharmony_ci vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max"); 856cd6a6acSopenharmony_ci DLERR(); 866cd6a6acSopenharmony_ci vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min"); 876cd6a6acSopenharmony_ci DLERR(); 886cd6a6acSopenharmony_ci 896cd6a6acSopenharmony_ci policy_file_create = dlsym(libsepolh, "sepol_policy_file_create"); 906cd6a6acSopenharmony_ci DLERR(); 916cd6a6acSopenharmony_ci policy_file_free = dlsym(libsepolh, "sepol_policy_file_free"); 926cd6a6acSopenharmony_ci DLERR(); 936cd6a6acSopenharmony_ci policy_file_set_mem = dlsym(libsepolh, "sepol_policy_file_set_mem"); 946cd6a6acSopenharmony_ci DLERR(); 956cd6a6acSopenharmony_ci policydb_create = dlsym(libsepolh, "sepol_policydb_create"); 966cd6a6acSopenharmony_ci DLERR(); 976cd6a6acSopenharmony_ci policydb_free = dlsym(libsepolh, "sepol_policydb_free"); 986cd6a6acSopenharmony_ci DLERR(); 996cd6a6acSopenharmony_ci policydb_read = dlsym(libsepolh, "sepol_policydb_read"); 1006cd6a6acSopenharmony_ci DLERR(); 1016cd6a6acSopenharmony_ci policydb_set_vers = dlsym(libsepolh, "sepol_policydb_set_vers"); 1026cd6a6acSopenharmony_ci DLERR(); 1036cd6a6acSopenharmony_ci policydb_to_image = dlsym(libsepolh, "sepol_policydb_to_image"); 1046cd6a6acSopenharmony_ci DLERR(); 1056cd6a6acSopenharmony_ci#undef DLERR 1066cd6a6acSopenharmony_ci } 1076cd6a6acSopenharmony_ci#else 1086cd6a6acSopenharmony_ci usesepol = 1; 1096cd6a6acSopenharmony_ci vers_max = sepol_policy_kern_vers_max; 1106cd6a6acSopenharmony_ci vers_min = sepol_policy_kern_vers_min; 1116cd6a6acSopenharmony_ci policy_file_create = sepol_policy_file_create; 1126cd6a6acSopenharmony_ci policy_file_free = sepol_policy_file_free; 1136cd6a6acSopenharmony_ci policy_file_set_mem = sepol_policy_file_set_mem; 1146cd6a6acSopenharmony_ci policydb_create = sepol_policydb_create; 1156cd6a6acSopenharmony_ci policydb_free = sepol_policydb_free; 1166cd6a6acSopenharmony_ci policydb_read = sepol_policydb_read; 1176cd6a6acSopenharmony_ci policydb_set_vers = sepol_policydb_set_vers; 1186cd6a6acSopenharmony_ci policydb_to_image = sepol_policydb_to_image; 1196cd6a6acSopenharmony_ci#endif 1206cd6a6acSopenharmony_ci 1216cd6a6acSopenharmony_ci if (usesepol) { 1226cd6a6acSopenharmony_ci maxvers = max(kernvers, vers_max()); 1236cd6a6acSopenharmony_ci minvers = vers_min(); 1246cd6a6acSopenharmony_ci } 1256cd6a6acSopenharmony_ci 1266cd6a6acSopenharmony_ci vers = maxvers; 1276cd6a6acSopenharmony_ci search: 1286cd6a6acSopenharmony_ci snprintf(path, sizeof(path), "%s.%d", 1296cd6a6acSopenharmony_ci selinux_binary_policy_path(), vers); 1306cd6a6acSopenharmony_ci fd = open(path, O_RDONLY | O_CLOEXEC); 1316cd6a6acSopenharmony_ci while (fd < 0 && errno == ENOENT 1326cd6a6acSopenharmony_ci && --vers >= minvers) { 1336cd6a6acSopenharmony_ci /* Check prior versions to see if old policy is available */ 1346cd6a6acSopenharmony_ci snprintf(path, sizeof(path), "%s.%d", 1356cd6a6acSopenharmony_ci selinux_binary_policy_path(), vers); 1366cd6a6acSopenharmony_ci fd = open(path, O_RDONLY | O_CLOEXEC); 1376cd6a6acSopenharmony_ci } 1386cd6a6acSopenharmony_ci if (fd < 0) { 1396cd6a6acSopenharmony_ci fprintf(stderr, 1406cd6a6acSopenharmony_ci "SELinux: Could not open policy file <= %s.%d: %m\n", 1416cd6a6acSopenharmony_ci selinux_binary_policy_path(), maxvers); 1426cd6a6acSopenharmony_ci goto dlclose; 1436cd6a6acSopenharmony_ci } 1446cd6a6acSopenharmony_ci 1456cd6a6acSopenharmony_ci if (fstat(fd, &sb) < 0) { 1466cd6a6acSopenharmony_ci fprintf(stderr, 1476cd6a6acSopenharmony_ci "SELinux: Could not stat policy file %s: %m\n", 1486cd6a6acSopenharmony_ci path); 1496cd6a6acSopenharmony_ci goto close; 1506cd6a6acSopenharmony_ci } 1516cd6a6acSopenharmony_ci 1526cd6a6acSopenharmony_ci size = sb.st_size; 1536cd6a6acSopenharmony_ci data = map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); 1546cd6a6acSopenharmony_ci if (map == MAP_FAILED) { 1556cd6a6acSopenharmony_ci fprintf(stderr, 1566cd6a6acSopenharmony_ci "SELinux: Could not map policy file %s: %m\n", 1576cd6a6acSopenharmony_ci path); 1586cd6a6acSopenharmony_ci goto close; 1596cd6a6acSopenharmony_ci } 1606cd6a6acSopenharmony_ci 1616cd6a6acSopenharmony_ci if (vers > kernvers && usesepol) { 1626cd6a6acSopenharmony_ci /* Need to downgrade to kernel-supported version. */ 1636cd6a6acSopenharmony_ci if (policy_file_create(&pf)) 1646cd6a6acSopenharmony_ci goto unmap; 1656cd6a6acSopenharmony_ci if (policydb_create(&policydb)) { 1666cd6a6acSopenharmony_ci policy_file_free(pf); 1676cd6a6acSopenharmony_ci goto unmap; 1686cd6a6acSopenharmony_ci } 1696cd6a6acSopenharmony_ci policy_file_set_mem(pf, data, size); 1706cd6a6acSopenharmony_ci if (policydb_read(policydb, pf)) { 1716cd6a6acSopenharmony_ci policy_file_free(pf); 1726cd6a6acSopenharmony_ci policydb_free(policydb); 1736cd6a6acSopenharmony_ci goto unmap; 1746cd6a6acSopenharmony_ci } 1756cd6a6acSopenharmony_ci if (policydb_set_vers(policydb, kernvers) || 1766cd6a6acSopenharmony_ci policydb_to_image(NULL, policydb, &data, &size)) { 1776cd6a6acSopenharmony_ci /* Downgrade failed, keep searching. */ 1786cd6a6acSopenharmony_ci fprintf(stderr, 1796cd6a6acSopenharmony_ci "SELinux: Could not downgrade policy file %s, searching for an older version.\n", 1806cd6a6acSopenharmony_ci path); 1816cd6a6acSopenharmony_ci policy_file_free(pf); 1826cd6a6acSopenharmony_ci policydb_free(policydb); 1836cd6a6acSopenharmony_ci munmap(map, sb.st_size); 1846cd6a6acSopenharmony_ci close(fd); 1856cd6a6acSopenharmony_ci vers--; 1866cd6a6acSopenharmony_ci goto search; 1876cd6a6acSopenharmony_ci } 1886cd6a6acSopenharmony_ci policy_file_free(pf); 1896cd6a6acSopenharmony_ci policydb_free(policydb); 1906cd6a6acSopenharmony_ci } 1916cd6a6acSopenharmony_ci 1926cd6a6acSopenharmony_ci rc = security_load_policy(data, size); 1936cd6a6acSopenharmony_ci 1946cd6a6acSopenharmony_ci if (rc) 1956cd6a6acSopenharmony_ci fprintf(stderr, 1966cd6a6acSopenharmony_ci "SELinux: Could not load policy file %s: %m\n", 1976cd6a6acSopenharmony_ci path); 1986cd6a6acSopenharmony_ci 1996cd6a6acSopenharmony_ci unmap: 2006cd6a6acSopenharmony_ci if (data != map) 2016cd6a6acSopenharmony_ci free(data); 2026cd6a6acSopenharmony_ci munmap(map, sb.st_size); 2036cd6a6acSopenharmony_ci close: 2046cd6a6acSopenharmony_ci close(fd); 2056cd6a6acSopenharmony_ci dlclose: 2066cd6a6acSopenharmony_ci#ifdef SHARED 2076cd6a6acSopenharmony_ci if (errormsg) 2086cd6a6acSopenharmony_ci fprintf(stderr, "libselinux: %s\n", errormsg); 2096cd6a6acSopenharmony_ci if (libsepolh) 2106cd6a6acSopenharmony_ci dlclose(libsepolh); 2116cd6a6acSopenharmony_ci#endif 2126cd6a6acSopenharmony_ci return rc; 2136cd6a6acSopenharmony_ci} 2146cd6a6acSopenharmony_ci 2156cd6a6acSopenharmony_ci 2166cd6a6acSopenharmony_ci/* 2176cd6a6acSopenharmony_ci * Mount point for selinuxfs. 2186cd6a6acSopenharmony_ci * This definition is private to the function below. 2196cd6a6acSopenharmony_ci * Everything else uses the location determined during 2206cd6a6acSopenharmony_ci * libselinux startup via /proc/mounts (see init_selinuxmnt). 2216cd6a6acSopenharmony_ci * We only need the hardcoded definition for the initial mount 2226cd6a6acSopenharmony_ci * required for the initial policy load. 2236cd6a6acSopenharmony_ci */ 2246cd6a6acSopenharmony_ciint selinux_init_load_policy(int *enforce) 2256cd6a6acSopenharmony_ci{ 2266cd6a6acSopenharmony_ci int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1; 2276cd6a6acSopenharmony_ci FILE *cfg; 2286cd6a6acSopenharmony_ci char *buf; 2296cd6a6acSopenharmony_ci 2306cd6a6acSopenharmony_ci /* 2316cd6a6acSopenharmony_ci * Reread the selinux configuration in case it has changed. 2326cd6a6acSopenharmony_ci * Example: Caller has chroot'd and is now loading policy from 2336cd6a6acSopenharmony_ci * chroot'd environment. 2346cd6a6acSopenharmony_ci */ 2356cd6a6acSopenharmony_ci selinux_reset_config(); 2366cd6a6acSopenharmony_ci 2376cd6a6acSopenharmony_ci /* 2386cd6a6acSopenharmony_ci * Get desired mode (disabled, permissive, enforcing) from 2396cd6a6acSopenharmony_ci * /etc/selinux/config. 2406cd6a6acSopenharmony_ci */ 2416cd6a6acSopenharmony_ci selinux_getenforcemode(&seconfig); 2426cd6a6acSopenharmony_ci 2436cd6a6acSopenharmony_ci /* Check for an override of the mode via the kernel command line. */ 2446cd6a6acSopenharmony_ci rc = mount("proc", "/proc", "proc", 0, 0); 2456cd6a6acSopenharmony_ci cfg = fopen("/proc/cmdline", "re"); 2466cd6a6acSopenharmony_ci if (cfg) { 2476cd6a6acSopenharmony_ci char *tmp; 2486cd6a6acSopenharmony_ci buf = malloc(selinux_page_size); 2496cd6a6acSopenharmony_ci if (!buf) { 2506cd6a6acSopenharmony_ci fclose(cfg); 2516cd6a6acSopenharmony_ci return -1; 2526cd6a6acSopenharmony_ci } 2536cd6a6acSopenharmony_ci if (fgets(buf, selinux_page_size, cfg) && 2546cd6a6acSopenharmony_ci (tmp = strstr(buf, "enforcing="))) { 2556cd6a6acSopenharmony_ci if (tmp == buf || isspace(*(tmp - 1))) { 2566cd6a6acSopenharmony_ci secmdline = 2576cd6a6acSopenharmony_ci atoi(tmp + sizeof("enforcing=") - 1); 2586cd6a6acSopenharmony_ci } 2596cd6a6acSopenharmony_ci } 2606cd6a6acSopenharmony_ci fclose(cfg); 2616cd6a6acSopenharmony_ci free(buf); 2626cd6a6acSopenharmony_ci } 2636cd6a6acSopenharmony_ci 2646cd6a6acSopenharmony_ci /* 2656cd6a6acSopenharmony_ci * Determine the final desired mode. 2666cd6a6acSopenharmony_ci * Command line argument takes precedence, then config file. 2676cd6a6acSopenharmony_ci */ 2686cd6a6acSopenharmony_ci if (secmdline >= 0) 2696cd6a6acSopenharmony_ci *enforce = secmdline; 2706cd6a6acSopenharmony_ci else if (seconfig >= 0) 2716cd6a6acSopenharmony_ci *enforce = seconfig; 2726cd6a6acSopenharmony_ci else 2736cd6a6acSopenharmony_ci *enforce = 0; /* unspecified or disabled */ 2746cd6a6acSopenharmony_ci 2756cd6a6acSopenharmony_ci /* 2766cd6a6acSopenharmony_ci * Check for the existence of SELinux via selinuxfs, and 2776cd6a6acSopenharmony_ci * mount it if present for use in the calls below. 2786cd6a6acSopenharmony_ci */ 2796cd6a6acSopenharmony_ci const char *mntpoint = NULL; 2806cd6a6acSopenharmony_ci /* First make sure /sys is mounted */ 2816cd6a6acSopenharmony_ci if (mount("sysfs", "/sys", "sysfs", 0, 0) == 0 || errno == EBUSY) { 2826cd6a6acSopenharmony_ci /* MS_NODEV can't be set because of /sys/fs/selinux/null device, used by Android */ 2836cd6a6acSopenharmony_ci if (mount(SELINUXFS, SELINUXMNT, SELINUXFS, MS_NOEXEC | MS_NOSUID, 0) == 0 || errno == EBUSY) { 2846cd6a6acSopenharmony_ci mntpoint = SELINUXMNT; 2856cd6a6acSopenharmony_ci } else { 2866cd6a6acSopenharmony_ci /* check old mountpoint */ 2876cd6a6acSopenharmony_ci if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) { 2886cd6a6acSopenharmony_ci mntpoint = OLDSELINUXMNT; 2896cd6a6acSopenharmony_ci } 2906cd6a6acSopenharmony_ci } 2916cd6a6acSopenharmony_ci } else { 2926cd6a6acSopenharmony_ci /* check old mountpoint */ 2936cd6a6acSopenharmony_ci if (mount(SELINUXFS, OLDSELINUXMNT, SELINUXFS, 0, 0) == 0 || errno == EBUSY) { 2946cd6a6acSopenharmony_ci mntpoint = OLDSELINUXMNT; 2956cd6a6acSopenharmony_ci } 2966cd6a6acSopenharmony_ci } 2976cd6a6acSopenharmony_ci 2986cd6a6acSopenharmony_ci if (! mntpoint ) { 2996cd6a6acSopenharmony_ci if (errno == ENODEV || !selinuxfs_exists()) { 3006cd6a6acSopenharmony_ci /* 3016cd6a6acSopenharmony_ci * SELinux was disabled in the kernel, either 3026cd6a6acSopenharmony_ci * omitted entirely or disabled at boot via selinux=0. 3036cd6a6acSopenharmony_ci * This takes precedence over any config or 3046cd6a6acSopenharmony_ci * commandline enforcing setting. 3056cd6a6acSopenharmony_ci */ 3066cd6a6acSopenharmony_ci *enforce = 0; 3076cd6a6acSopenharmony_ci } else { 3086cd6a6acSopenharmony_ci /* Only emit this error if selinux was not disabled */ 3096cd6a6acSopenharmony_ci fprintf(stderr, "Mount failed for selinuxfs on %s: %m\n", SELINUXMNT); 3106cd6a6acSopenharmony_ci } 3116cd6a6acSopenharmony_ci 3126cd6a6acSopenharmony_ci if (rc == 0) 3136cd6a6acSopenharmony_ci umount2("/proc", MNT_DETACH); 3146cd6a6acSopenharmony_ci 3156cd6a6acSopenharmony_ci goto noload; 3166cd6a6acSopenharmony_ci } 3176cd6a6acSopenharmony_ci set_selinuxmnt(mntpoint); 3186cd6a6acSopenharmony_ci 3196cd6a6acSopenharmony_ci if (rc == 0) 3206cd6a6acSopenharmony_ci umount2("/proc", MNT_DETACH); 3216cd6a6acSopenharmony_ci 3226cd6a6acSopenharmony_ci /* 3236cd6a6acSopenharmony_ci * Note: The following code depends on having selinuxfs 3246cd6a6acSopenharmony_ci * already mounted and selinuxmnt set above. 3256cd6a6acSopenharmony_ci */ 3266cd6a6acSopenharmony_ci 3276cd6a6acSopenharmony_ci if (seconfig == -1) { 3286cd6a6acSopenharmony_ci /* Runtime disable of SELinux. */ 3296cd6a6acSopenharmony_ci rc = security_disable(); 3306cd6a6acSopenharmony_ci if (rc == 0) { 3316cd6a6acSopenharmony_ci /* Successfully disabled, so umount selinuxfs too. */ 3326cd6a6acSopenharmony_ci umount(selinux_mnt); 3336cd6a6acSopenharmony_ci fini_selinuxmnt(); 3346cd6a6acSopenharmony_ci goto noload; 3356cd6a6acSopenharmony_ci } else { 3366cd6a6acSopenharmony_ci /* 3376cd6a6acSopenharmony_ci * It's possible that this failed because policy has 3386cd6a6acSopenharmony_ci * already been loaded. We can't disable SELinux now, 3396cd6a6acSopenharmony_ci * so the best we can do is force it to be permissive. 3406cd6a6acSopenharmony_ci */ 3416cd6a6acSopenharmony_ci *enforce = 0; 3426cd6a6acSopenharmony_ci } 3436cd6a6acSopenharmony_ci } 3446cd6a6acSopenharmony_ci 3456cd6a6acSopenharmony_ci /* 3466cd6a6acSopenharmony_ci * If necessary, change the kernel enforcing status to match 3476cd6a6acSopenharmony_ci * the desired mode. 3486cd6a6acSopenharmony_ci */ 3496cd6a6acSopenharmony_ci orig_enforce = rc = security_getenforce(); 3506cd6a6acSopenharmony_ci if (rc < 0) 3516cd6a6acSopenharmony_ci goto noload; 3526cd6a6acSopenharmony_ci if (orig_enforce != *enforce) { 3536cd6a6acSopenharmony_ci rc = security_setenforce(*enforce); 3546cd6a6acSopenharmony_ci if (rc < 0) { 3556cd6a6acSopenharmony_ci fprintf(stderr, "SELinux: Unable to switch to %s mode: %m\n", (*enforce ? "enforcing" : "permissive")); 3566cd6a6acSopenharmony_ci if (*enforce) 3576cd6a6acSopenharmony_ci goto noload; 3586cd6a6acSopenharmony_ci } 3596cd6a6acSopenharmony_ci } 3606cd6a6acSopenharmony_ci 3616cd6a6acSopenharmony_ci if (seconfig == -1) { 3626cd6a6acSopenharmony_ci umount(selinux_mnt); 3636cd6a6acSopenharmony_ci fini_selinuxmnt(); 3646cd6a6acSopenharmony_ci goto noload; 3656cd6a6acSopenharmony_ci } 3666cd6a6acSopenharmony_ci 3676cd6a6acSopenharmony_ci /* Load the policy. */ 3686cd6a6acSopenharmony_ci return selinux_mkload_policy(0); 3696cd6a6acSopenharmony_ci 3706cd6a6acSopenharmony_ci noload: 3716cd6a6acSopenharmony_ci /* 3726cd6a6acSopenharmony_ci * Only return 0 on a successful completion of policy load. 3736cd6a6acSopenharmony_ci * In any other case, we want to return an error so that init 3746cd6a6acSopenharmony_ci * knows not to proceed with the re-exec for the domain transition. 3756cd6a6acSopenharmony_ci * Depending on the *enforce setting, init will halt (> 0) or proceed 3766cd6a6acSopenharmony_ci * normally (otherwise). 3776cd6a6acSopenharmony_ci */ 3786cd6a6acSopenharmony_ci return -1; 3796cd6a6acSopenharmony_ci} 3806cd6a6acSopenharmony_ci#endif 381