int main(int argc, char **argv) { int ret, opt, quiet=0, preservebools = 1, nargs; char *migscs = NULL; #ifdef USE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif while ((opt = getopt(argc, argv, "bmq")) > 0) { switch (opt) { case 'b': preservebools = 0; break; case 'm': migscs = optarg; break; case 'q': quiet = 1; sepol_debug(0); break; default: usage(argv[0]); } } nargs = argc - optind; if (nargs > 2) usage(argv[0]); if (nargs >= 1) { fprintf(stderr, "%s: Warning! Policy file argument (%s) is no longer supported, installed policy is always loaded. Continuing...\n", argv[0], argv[optind++]); } if (nargs == 2) { fprintf(stderr, "%s: Warning! Boolean file argument (%s) is no longer supported, installed booleans file is always used. Continuing...\n", argv[0], argv[optind++]); } if (migscs != NULL) { ret = selinux_load_migscs(migscs); if (ret) { fprintf(stderr, "%s: Can't load migscs %s: %s\n", argv[0], migscs, strerror(errno)); exit(2); } } ret = selinux_mkload_policy(preservebools); if (ret < 0) { fprintf(stderr, _("%s: Can't load policy: %s\n"), argv[0], strerror(errno)); exit(2); } exit(0); }
/* * Mount point for selinuxfs. * This definition is private to the function below. * Everything else uses the location determined during * libselinux startup via /proc/mounts (see init_selinuxmnt). * We only need the hardcoded definition for the initial mount * required for the initial policy load. */ int selinux_init_load_policy(int *enforce) { int rc = 0, orig_enforce = 0, seconfig = -2, secmdline = -1; FILE *cfg; char *buf; /* * Reread the selinux configuration in case it has changed. * Example: Caller has chroot'd and is now loading policy from * chroot'd environment. */ selinux_reset_config(); /* * Get desired mode (disabled, permissive, enforcing) from * /etc/selinux/config. */ selinux_getenforcemode(&seconfig); /* Check for an override of the mode via the kernel command line. */ rc = mount("proc", "/proc", "proc", 0, 0); cfg = fopen("/proc/cmdline", "r"); if (cfg) { char *tmp; buf = malloc(selinux_page_size); if (!buf) { fclose(cfg); return -1; } if (fgets(buf, selinux_page_size, cfg) && (tmp = strstr(buf, "enforcing="))) { if (tmp == buf || isspace(*(tmp - 1))) { secmdline = atoi(tmp + sizeof("enforcing=") - 1); } } fclose(cfg); free(buf); } #ifndef MNT_DETACH #define MNT_DETACH 2 #endif if (rc == 0) umount2("/proc", MNT_DETACH); /* * Determine the final desired mode. * Command line argument takes precedence, then config file. */ if (secmdline >= 0) *enforce = secmdline; else if (seconfig >= 0) *enforce = seconfig; else *enforce = 0; /* unspecified or disabled */ /* * Check for the existence of SELinux via selinuxfs, and * mount it if present for use in the calls below. */ if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, 0) < 0 && errno != EBUSY) { if (errno == ENODEV) { /* * SELinux was disabled in the kernel, either * omitted entirely or disabled at boot via selinux=0. * This takes precedence over any config or * commandline enforcing setting. */ *enforce = 0; } else { /* Only emit this error if selinux was not disabled */ fprintf(stderr, "Mount failed for selinuxfs on %s: %s\n", SELINUXMNT, strerror(errno)); } goto noload; } set_selinuxmnt(SELINUXMNT); /* * Note: The following code depends on having selinuxfs * already mounted and selinuxmnt set above. */ if (seconfig == -1) { /* Runtime disable of SELinux. */ rc = security_disable(); if (rc == 0) { /* Successfully disabled, so umount selinuxfs too. */ umount(SELINUXMNT); fini_selinuxmnt(); } /* * If we failed to disable, SELinux will still be * effectively permissive, because no policy is loaded. * No need to call security_setenforce(0) here. */ goto noload; } /* * If necessary, change the kernel enforcing status to match * the desired mode. */ orig_enforce = rc = security_getenforce(); if (rc < 0) goto noload; if (orig_enforce != *enforce) { rc = security_setenforce(*enforce); if (rc < 0) { fprintf(stderr, "SELinux: Unable to switch to %s mode: %s\n", (*enforce ? "enforcing" : "permissive"), strerror(errno)); if (*enforce) goto noload; } } /* Load the policy. */ return selinux_mkload_policy(0); noload: /* * Only return 0 on a successful completion of policy load. * In any other case, we want to return an error so that init * knows not to proceed with the re-exec for the domain transition. * Depending on the *enforce setting, init will halt (> 0) or proceed * normally (otherwise). */ return -1; }