From f667a3247a7e814355feedbc08c6bbc92a9409b5 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Sat, 25 Apr 2015 17:42:52 -0700 Subject: [PATCH] init: get rid of the remaining double mounts Don't double mount /dev and its subdirectories anymore. Instead, the first stage init is solely responsible for mounting it. Don't have init prepare the property space. This is the responsibility of the second stage init. Don't have SELinux use the property space to determine how we should be running. Instead, create a new function and extract the data we need directly from /proc/cmdline. SELinux needs this information in the first stage init process where the property service isn't available. Change-Id: I5b4f3bec79463a7381a68f30bdda78b5cc122a96 --- init/init.cpp | 85 +++++++++++++++++++++++++++------------------------ init/util.cpp | 3 +- init/util.h | 3 +- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index f76b599b5..dd74538de 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -746,7 +746,7 @@ static int console_init_action(int nargs, char **args) return 0; } -static void import_kernel_nv(char *name, int for_emulator) +static void import_kernel_nv(char *name, bool for_emulator) { char *value = strchr(name, '='); int name_len = strlen(name); @@ -840,9 +840,9 @@ static void process_kernel_cmdline(void) * second pass is only necessary for qemu to export all kernel params * as props. */ - import_kernel_cmdline(0, import_kernel_nv); + import_kernel_cmdline(false, import_kernel_nv); if (qemu[0]) - import_kernel_cmdline(1, import_kernel_nv); + import_kernel_cmdline(true, import_kernel_nv); } static int queue_property_triggers_action(int nargs, char **args) @@ -860,6 +860,29 @@ static void selinux_init_all_handles(void) sehandle_prop = selinux_android_prop_context_handle(); } +enum selinux_enforcing_status { SELINUX_DISABLED, SELINUX_PERMISSIVE, SELINUX_ENFORCING }; + +static selinux_enforcing_status selinux_status_from_cmdline() { + selinux_enforcing_status status = SELINUX_ENFORCING; + + std::function fn = [&](char* name, bool in_qemu) { + char *value = strchr(name, '='); + if (value == nullptr) { return; } + *value++ = '\0'; + if (strcmp(name, "androidboot.selinux") == 0) { + if (strcmp(value, "disabled") == 0) { + status = SELINUX_DISABLED; + } else if (strcmp(value, "permissive") == 0) { + status = SELINUX_PERMISSIVE; + } + } + }; + import_kernel_cmdline(false, fn); + + return status; +} + + static bool selinux_is_disabled(void) { if (ALLOW_DISABLE_SELINUX) { @@ -868,12 +891,7 @@ static bool selinux_is_disabled(void) // via the kernel command line "selinux=0". return true; } - - char tmp[PROP_VALUE_MAX]; - if ((property_get("ro.boot.selinux", tmp) != 0) && (strcmp(tmp, "disabled") == 0)) { - // SELinux is compiled into the kernel, but we've been told to disable it. - return true; - } + return selinux_status_from_cmdline() == SELINUX_DISABLED; } return false; @@ -882,20 +900,7 @@ static bool selinux_is_disabled(void) static bool selinux_is_enforcing(void) { if (ALLOW_DISABLE_SELINUX) { - char tmp[PROP_VALUE_MAX]; - if (property_get("ro.boot.selinux", tmp) == 0) { - // Property is not set. Assume enforcing. - return true; - } - - if (strcmp(tmp, "permissive") == 0) { - // SELinux is in the kernel, but we've been told to go into permissive mode. - return false; - } - - if (strcmp(tmp, "enforcing") != 0) { - ERROR("SELinux: Unknown value of ro.boot.selinux. Got: \"%s\". Assuming enforcing.\n", tmp); - } + return selinux_status_from_cmdline() == SELINUX_ENFORCING; } return true; } @@ -985,20 +990,15 @@ int main(int argc, char** argv) { // Get the basic filesystem setup we need put together in the initramdisk // on / and then we'll let the rc file figure out the rest. - // TODO: avoid mounting tmpfs twice, once in the first stage, and once in the - // second stage. - mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); - mkdir("/dev/pts", 0755); - mkdir("/dev/socket", 0755); - mount("devpts", "/dev/pts", "devpts", 0, NULL); if (is_first_stage) { + mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); + mkdir("/dev/pts", 0755); + mkdir("/dev/socket", 0755); + mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); } - // Indicate that booting is in progress to background fw loaders, etc. - close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); - // We must have some place other than / to create the device nodes for // kmsg and null, otherwise we won't be able to remount / read-only // later on. Now that tmpfs is mounted on /dev, we can actually talk @@ -1009,16 +1009,21 @@ int main(int argc, char** argv) { NOTICE("init%s started!\n", is_first_stage ? "" : " second stage"); - property_init(); + if (!is_first_stage) { + // Indicate that booting is in progress to background fw loaders, etc. + close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); - // If arguments are passed both on the command line and in DT, - // properties set in DT always have priority over the command-line ones. - process_kernel_dt(); - process_kernel_cmdline(); + property_init(); - // Propogate the kernel variables to internal variables - // used by init as well as the current required properties. - export_kernel_boot_props(); + // If arguments are passed both on the command line and in DT, + // properties set in DT always have priority over the command-line ones. + process_kernel_dt(); + process_kernel_cmdline(); + + // Propogate the kernel variables to internal variables + // used by init as well as the current required properties. + export_kernel_boot_props(); + } // Set up SELinux, including loading the SELinux policy if we're in the kernel domain. selinux_initialize(is_first_stage); diff --git a/init/util.cpp b/init/util.cpp index b7fb86779..9343145a7 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -403,8 +403,7 @@ void open_devnull_stdio(void) } } -void import_kernel_cmdline(int in_qemu, - void (*import_kernel_nv)(char *name, int in_qemu)) +void import_kernel_cmdline(bool in_qemu, std::function import_kernel_nv) { char cmdline[2048]; char *ptr; diff --git a/init/util.h b/init/util.h index 8fec7a801..6864acf15 100644 --- a/init/util.h +++ b/init/util.h @@ -21,6 +21,7 @@ #include #include +#include #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) @@ -57,7 +58,7 @@ void make_link(const char *oldpath, const char *newpath); void remove_link(const char *oldpath, const char *newpath); int wait_for_file(const char *filename, int timeout); void open_devnull_stdio(void); -void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu)); +void import_kernel_cmdline(bool in_qemu, std::function); int make_dir(const char *path, mode_t mode); int restorecon(const char *pathname); int restorecon_recursive(const char *pathname);