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

Commit f65730e6 authored by Elliott Hughes's avatar Elliott Hughes
Browse files

Revert "Revert "Make init re-exec itself for its SELinux domain transition.""

This reverts commit 42173746.

It turns out that the kernel passes any unrecognized arguments on to init,
and (at least) N6 and N9 have such arguments. My lazy check of argc was
thus insufficient to recognize what stage of init we were in, so we'd
skip to stage 2 and not set up SELinux. And apparently you can get a
very long way with SELinux off... We'll fix that in a later change.

Bug: 19702273
Change-Id: I43b3fb722fed35dd217cb529cbcac9a29aff4e4b
parent 34dd04db
Loading
Loading
Loading
Loading
+45 −14
Original line number Diff line number Diff line
@@ -940,7 +940,13 @@ static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_
    return 0;
}

static void selinux_initialize() {
static void security_failure() {
    ERROR("Security failure; rebooting into recovery mode...\n");
    android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
    while (true) { pause(); }  // never reached
}

static void selinux_initialize(bool in_kernel_domain) {
    Timer t;

    selinux_callback cb;
@@ -953,19 +959,27 @@ static void selinux_initialize() {
        return;
    }

    if (in_kernel_domain) {
        if (write_file("/sys/fs/selinux/checkreqprot", "0") == -1) {
            ERROR("couldn't write to /sys/fs/selinux/checkreqprot: %s\n",
                  strerror(errno));
            security_failure();
        }

        INFO("Loading SELinux policy...\n");
        if (selinux_android_load_policy() < 0) {
        ERROR("SELinux: Failed to load policy; rebooting into recovery mode\n");
        android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
        while (1) { pause(); }  // never reached
            ERROR("failed to load policy: %s\n", strerror(errno));
            security_failure();
        }

    selinux_init_all_handles();
        bool is_enforcing = selinux_is_enforcing();
    INFO("SELinux: security_setenforce(%d)\n", is_enforcing);
        security_setenforce(is_enforcing);

    NOTICE("(Initializing SELinux took %.2fs.)\n", t.duration());
        NOTICE("(Initializing SELinux %s took %.2fs.)\n",
               is_enforcing ? "enforcing" : "non-enforcing", t.duration());
    } else {
        selinux_init_all_handles();
    }
}

int main(int argc, char** argv) {
@@ -1006,7 +1020,8 @@ int main(int argc, char** argv) {
    klog_init();
    klog_set_level(KLOG_NOTICE_LEVEL);

    NOTICE("init started!\n");
    bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
    NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");

    property_init();

@@ -1019,7 +1034,23 @@ int main(int argc, char** argv) {
    // used by init as well as the current required properties.
    export_kernel_boot_props();

    selinux_initialize();
    // Set up SELinux, including loading the SELinux policy if we're in the kernel domain.
    selinux_initialize(is_first_stage);

    // If we're in the kernel domain, re-exec init to transition to the init domain now
    // that the SELinux policy has been loaded.
    if (is_first_stage) {
        if (restorecon("/init") == -1) {
            ERROR("restorecon failed: %s\n", strerror(errno));
            security_failure();
        }
        char* path = argv[0];
        char* args[] = { path, const_cast<char*>("--second-stage"), nullptr };
        if (execv(path, args) == -1) {
            ERROR("execv(\"%s\") failed: %s\n", path, strerror(errno));
            security_failure();
        }
    }

    // These directories were necessarily created before initial policy load
    // and therefore need their security context restored to the proper value.
+0 −7
Original line number Diff line number Diff line
@@ -14,13 +14,6 @@ on early-init
    # Set init and its forked children's oom_adj.
    write /proc/1/oom_score_adj -1000

    # Apply strict SELinux checking of PROT_EXEC on mmap/mprotect calls.
    write /sys/fs/selinux/checkreqprot 0

    # Set the security context for the init process.
    # This should occur before anything else (e.g. ueventd) is started.
    setcon u:r:init:s0

    # Set the security context of /adb_keys if present.
    restorecon /adb_keys