diff options
author | Elliott Hughes <enh@google.com> | 2015-04-24 03:28:45 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-24 03:28:45 +0000 |
commit | 77434ab362b3234accf16499aaf2a5340d568553 (patch) | |
tree | f50eb8af97135e7e04ccec9cccec841999e10ffe /init | |
parent | 44f1356e42a64fefb194b5c74b62402f4ec2881e (diff) | |
parent | ef68fd3f807438fd9aae3b8f104f3a85ef9eb699 (diff) | |
download | system_core-77434ab362b3234accf16499aaf2a5340d568553.zip system_core-77434ab362b3234accf16499aaf2a5340d568553.tar.gz system_core-77434ab362b3234accf16499aaf2a5340d568553.tar.bz2 |
am ef68fd3f: am d4656784: Merge "Make init re-exec itself for its SELinux domain transition."
* commit 'ef68fd3f807438fd9aae3b8f104f3a85ef9eb699':
Make init re-exec itself for its SELinux domain transition.
Diffstat (limited to 'init')
-rw-r--r-- | init/init.cpp | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/init/init.cpp b/init/init.cpp index b1d65db..ed20661 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -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; } - 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 - } + 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(); + } - selinux_init_all_handles(); - bool is_enforcing = selinux_is_enforcing(); - INFO("SELinux: security_setenforce(%d)\n", is_enforcing); - security_setenforce(is_enforcing); + INFO("Loading SELinux policy...\n"); + if (selinux_android_load_policy() < 0) { + ERROR("failed to load policy: %s\n", strerror(errno)); + security_failure(); + } + + bool is_enforcing = selinux_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); + 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. |