diff --git a/init/init.cpp b/init/init.cpp index 3ab0a5287..e5c154893 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #ifndef RECOVERY #include @@ -585,6 +587,43 @@ static void InitKernelLogging(char* argv[]) { android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter); } +static void GlobalSeccomp() { + import_kernel_cmdline(false, [](const std::string& key, const std::string& value, + bool in_qemu) { + if (key == "androidboot.seccomp" && value == "global" && !set_global_seccomp_filter()) { + LOG(FATAL) << "Failed to globally enable seccomp!"; + } + }); +} + +static void SetupSelinux(char** argv) { + android::base::InitLogging(argv, &android::base::KernelLogger, [](const char*) { + RebootSystem(ANDROID_RB_RESTART2, "bootloader"); + }); + + // Set up SELinux, loading the SELinux policy. + SelinuxSetupKernelLogging(); + SelinuxInitialize(); + + // We're in the kernel domain and want to transition to the init domain. File systems that + // store SELabels in their xattrs, such as ext4 do not need an explicit restorecon here, + // but other file systems do. In particular, this is needed for ramdisks such as the + // recovery image for A/B devices. + if (selinux_android_restorecon("/system/bin/init", 0) == -1) { + PLOG(FATAL) << "restorecon failed of /system/bin/init failed"; + } + + setenv("SELINUX_INITIALIZED", "true", 1); + + const char* path = "/system/bin/init"; + const char* args[] = {path, nullptr}; + execv(path, const_cast(args)); + + // execv() only returns if an error happened, in which case we + // panic and never return from this function. + PLOG(FATAL) << "execv(\"" << path << "\") failed"; +} + int main(int argc, char** argv) { if (!strcmp(basename(argv[0]), "ueventd")) { return ueventd_main(argc, argv); @@ -600,9 +639,16 @@ int main(int argc, char** argv) { InstallRebootSignalHandlers(); } + if (getenv("SELINUX_INITIALIZED") == nullptr) { + SetupSelinux(argv); + } + InitKernelLogging(argv); LOG(INFO) << "init second stage started!"; + // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote). + GlobalSeccomp(); + // Set up a session keyring that all processes will have access to. It // will hold things like FBE encryption keys. No process should override // its session keyring. @@ -631,6 +677,7 @@ int main(int argc, char** argv) { if (avb_version) property_set("ro.boot.avb_version", avb_version); // Clean up our environment. + unsetenv("SELINUX_INITIALIZED"); unsetenv("INIT_STARTED_AT"); unsetenv("INIT_SELINUX_TOOK"); unsetenv("INIT_AVB_VERSION"); diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp index 466cde332..0c4a11093 100644 --- a/init/init_first_stage.cpp +++ b/init/init_first_stage.cpp @@ -15,7 +15,6 @@ */ #include -#include #include #include #include @@ -30,11 +29,9 @@ #include #include #include -#include #include "first_stage_mount.h" #include "reboot_utils.h" -#include "selinux.h" #include "util.h" using android::base::boot_clock; @@ -42,15 +39,6 @@ using android::base::boot_clock; namespace android { namespace init { -static void GlobalSeccomp() { - import_kernel_cmdline(false, [](const std::string& key, const std::string& value, - bool in_qemu) { - if (key == "androidboot.seccomp" && value == "global" && !set_global_seccomp_filter()) { - LOG(FATAL) << "Failed to globally enable seccomp!"; - } - }); -} - int main(int argc, char** argv) { if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); @@ -130,22 +118,6 @@ int main(int argc, char** argv) { SetInitAvbVersionInRecovery(); - // Does this need to be done in first stage init or can it be done later? - // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote). - GlobalSeccomp(); - - // Set up SELinux, loading the SELinux policy. - SelinuxSetupKernelLogging(); - SelinuxInitialize(); - - // We're in the kernel domain and want to transition to the init domain when we exec second - // stage init. File systems that store SELabels in their xattrs, such as ext4 do not need an - // explicit restorecon here, but other file systems do. In particular, this is needed for - // ramdisks such as the recovery image for A/B devices. - if (selinux_android_restorecon("/system/bin/init", 0) == -1) { - PLOG(FATAL) << "restorecon failed of /system/bin/init failed"; - } - static constexpr uint32_t kNanosecondsPerMillisecond = 1e6; uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond; setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);