Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f667a324 authored by Nick Kralevich's avatar Nick Kralevich
Browse files

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
parent ccac2be8
Loading
Loading
Loading
Loading
+45 −40
Original line number Original line Diff line number Diff line
@@ -746,7 +746,7 @@ static int console_init_action(int nargs, char **args)
    return 0;
    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, '=');
    char *value = strchr(name, '=');
    int name_len = strlen(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
     * second pass is only necessary for qemu to export all kernel params
     * as props.
     * as props.
     */
     */
    import_kernel_cmdline(0, import_kernel_nv);
    import_kernel_cmdline(false, import_kernel_nv);
    if (qemu[0])
    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)
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();
    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<void(char*,bool)> 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)
static bool selinux_is_disabled(void)
{
{
    if (ALLOW_DISABLE_SELINUX) {
    if (ALLOW_DISABLE_SELINUX) {
@@ -868,12 +891,7 @@ static bool selinux_is_disabled(void)
            // via the kernel command line "selinux=0".
            // via the kernel command line "selinux=0".
            return true;
            return true;
        }
        }

        return selinux_status_from_cmdline() == SELINUX_DISABLED;
        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 false;
    return false;
@@ -882,20 +900,7 @@ static bool selinux_is_disabled(void)
static bool selinux_is_enforcing(void)
static bool selinux_is_enforcing(void)
{
{
    if (ALLOW_DISABLE_SELINUX) {
    if (ALLOW_DISABLE_SELINUX) {
        char tmp[PROP_VALUE_MAX];
        return selinux_status_from_cmdline() == SELINUX_ENFORCING;
        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 true;
    return true;
}
}
@@ -985,20 +990,15 @@ int main(int argc, char** argv) {


    // Get the basic filesystem setup we need put together in the initramdisk
    // 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.
    // 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
    if (is_first_stage) {
    // second stage.
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
    if (is_first_stage) {
        mount("proc", "/proc", "proc", 0, NULL);
        mount("proc", "/proc", "proc", 0, NULL);
        mount("sysfs", "/sys", "sysfs", 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
    // 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
    // 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
    // later on. Now that tmpfs is mounted on /dev, we can actually talk
@@ -1009,6 +1009,10 @@ int main(int argc, char** argv) {


    NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");
    NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");


    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));

        property_init();
        property_init();


        // If arguments are passed both on the command line and in DT,
        // If arguments are passed both on the command line and in DT,
@@ -1019,6 +1023,7 @@ int main(int argc, char** argv) {
        // Propogate the kernel variables to internal variables
        // Propogate the kernel variables to internal variables
        // used by init as well as the current required properties.
        // used by init as well as the current required properties.
        export_kernel_boot_props();
        export_kernel_boot_props();
    }


    // Set up SELinux, including loading the SELinux policy if we're in the kernel domain.
    // Set up SELinux, including loading the SELinux policy if we're in the kernel domain.
    selinux_initialize(is_first_stage);
    selinux_initialize(is_first_stage);
+1 −2
Original line number Original line Diff line number Diff line
@@ -403,8 +403,7 @@ void open_devnull_stdio(void)
    }
    }
}
}


void import_kernel_cmdline(int in_qemu,
void import_kernel_cmdline(bool in_qemu, std::function<void(char*,bool)> import_kernel_nv)
                           void (*import_kernel_nv)(char *name, int in_qemu))
{
{
    char cmdline[2048];
    char cmdline[2048];
    char *ptr;
    char *ptr;
+2 −1
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <sys/types.h>


#include <string>
#include <string>
#include <functional>


#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#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);
void remove_link(const char *oldpath, const char *newpath);
int wait_for_file(const char *filename, int timeout);
int wait_for_file(const char *filename, int timeout);
void open_devnull_stdio(void);
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<void(char*,bool)>);
int make_dir(const char *path, mode_t mode);
int make_dir(const char *path, mode_t mode);
int restorecon(const char *pathname);
int restorecon(const char *pathname);
int restorecon_recursive(const char *pathname);
int restorecon_recursive(const char *pathname);