summaryrefslogtreecommitdiffstats
path: root/init/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'init/init.cpp')
-rw-r--r--init/init.cpp158
1 files changed, 7 insertions, 151 deletions
diff --git a/init/init.cpp b/init/init.cpp
index e0cce0e52..ad80c98cf 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -18,15 +18,12 @@
#include <dirent.h>
#include <fcntl.h>
-#include <paths.h>
#include <pthread.h>
-#include <seccomp_policy.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/signalfd.h>
-#include <sys/sysmacros.h>
#include <sys/types.h>
#include <unistd.h>
@@ -43,8 +40,6 @@
#include <cutils/android_reboot.h>
#include <keyutils.h>
#include <libavb/libavb.h>
-#include <private/android_filesystem_config.h>
-#include <selinux/android.h>
#include "action_parser.h"
#include "epoll.h"
@@ -53,6 +48,7 @@
#include "keychords.h"
#include "property_service.h"
#include "reboot.h"
+#include "reboot_utils.h"
#include "security.h"
#include "selinux.h"
#include "sigchld_handler.h"
@@ -417,14 +413,6 @@ static Result<Success> queue_property_triggers_action(const BuiltinArguments& ar
return Success();
}
-static void global_seccomp() {
- 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!";
- }
- });
-}
-
// Set the UDC controller for the ConfigFS USB Gadgets.
// Read the UDC controller in use from "/sys/class/udc".
// In case of multiple UDC controllers select the first one.
@@ -441,40 +429,6 @@ static void set_usb_controller() {
}
}
-static void InstallRebootSignalHandlers() {
- // Instead of panic'ing the kernel as is the default behavior when init crashes,
- // we prefer to reboot to bootloader on development builds, as this will prevent
- // boot looping bad configurations and allow both developers and test farms to easily
- // recover.
- struct sigaction action;
- memset(&action, 0, sizeof(action));
- sigfillset(&action.sa_mask);
- action.sa_handler = [](int signal) {
- // These signal handlers are also caught for processes forked from init, however we do not
- // want them to trigger reboot, so we directly call _exit() for children processes here.
- if (getpid() != 1) {
- _exit(signal);
- }
-
- // Calling DoReboot() or LOG(FATAL) is not a good option as this is a signal handler.
- // RebootSystem uses syscall() which isn't actually async-signal-safe, but our only option
- // and probably good enough given this is already an error case and only enabled for
- // development builds.
- RebootSystem(ANDROID_RB_RESTART2, "bootloader");
- };
- action.sa_flags = SA_RESTART;
- sigaction(SIGABRT, &action, nullptr);
- sigaction(SIGBUS, &action, nullptr);
- sigaction(SIGFPE, &action, nullptr);
- sigaction(SIGILL, &action, nullptr);
- sigaction(SIGSEGV, &action, nullptr);
-#if defined(SIGSTKFLT)
- sigaction(SIGSTKFLT, &action, nullptr);
-#endif
- sigaction(SIGSYS, &action, nullptr);
- sigaction(SIGTRAP, &action, nullptr);
-}
-
static void HandleSigtermSignal(const signalfd_siginfo& siginfo) {
if (siginfo.ssi_pid != 0) {
// Drop any userspace SIGTERM requests.
@@ -611,6 +565,8 @@ static void InitKernelLogging(char* argv[]) {
android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
}
+int first_stage_main(int argc, char** argv);
+
int main(int argc, char** argv) {
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
@@ -622,114 +578,14 @@ int main(int argc, char** argv) {
return SubcontextMain(argc, argv, &function_map);
}
- if (REBOOT_BOOTLOADER_ON_PANIC) {
- InstallRebootSignalHandlers();
+ if (getenv("INIT_SECOND_STAGE") == nullptr) {
+ return first_stage_main(argc, argv);
}
- bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
-
- if (is_first_stage) {
- boot_clock::time_point start_time = boot_clock::now();
-
- std::vector<std::pair<std::string, int>> errors;
-#define CHECKCALL(x) \
- if (x != 0) errors.emplace_back(#x " failed", errno);
-
- // Clear the umask.
- umask(0);
-
- CHECKCALL(clearenv());
- CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));
- // 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.
- CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
- CHECKCALL(mkdir("/dev/pts", 0755));
- CHECKCALL(mkdir("/dev/socket", 0755));
- CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));
-#define MAKE_STR(x) __STRING(x)
- CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)));
-#undef MAKE_STR
- // Don't expose the raw commandline to unprivileged processes.
- CHECKCALL(chmod("/proc/cmdline", 0440));
- gid_t groups[] = { AID_READPROC };
- CHECKCALL(setgroups(arraysize(groups), groups));
- CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
- CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));
-
- CHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)));
-
- if constexpr (WORLD_WRITABLE_KMSG) {
- CHECKCALL(mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)));
- }
-
- CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
- CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
-
- // This is needed for log wrapper, which gets called before ueventd runs.
- CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2)));
- CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));
-
- // Mount staging areas for devices managed by vold
- // See storage config details at http://source.android.com/devices/storage/
- CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
- "mode=0755,uid=0,gid=1000"));
- // /mnt/vendor is used to mount vendor-specific partitions that can not be
- // part of the vendor partition, e.g. because they are mounted read-write.
- CHECKCALL(mkdir("/mnt/vendor", 0755));
- // /mnt/product is used to mount product-specific partitions that can not be
- // part of the product partition, e.g. because they are mounted read-write.
- CHECKCALL(mkdir("/mnt/product", 0755));
-
-#undef CHECKCALL
-
- // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
- // talk to the outside world...
- InitKernelLogging(argv);
-
- if (!errors.empty()) {
- for (const auto& [error_string, error_errno] : errors) {
- LOG(ERROR) << error_string << " " << strerror(error_errno);
- }
- LOG(FATAL) << "Init encountered errors starting first stage, aborting";
- }
-
- LOG(INFO) << "init first stage started!";
-
- if (!DoFirstStageMount()) {
- LOG(FATAL) << "Failed to mount required partitions early ...";
- }
-
- SetInitAvbVersionInRecovery();
-
- // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
- global_seccomp();
-
- // Set up SELinux, loading the SELinux policy.
- SelinuxSetupKernelLogging();
- SelinuxInitialize();
-
- // We're in the kernel domain, so re-exec init to transition to the init domain now
- // that the SELinux policy has been loaded.
- if (selinux_android_restorecon("/init", 0) == -1) {
- PLOG(FATAL) << "restorecon failed of /init failed";
- }
-
- setenv("INIT_SECOND_STAGE", "true", 1);
-
- 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);
-
- char* path = argv[0];
- char* args[] = { path, nullptr };
- execv(path, args);
-
- // execv() only returns if an error happened, in which case we
- // panic and never fall through this conditional.
- PLOG(FATAL) << "execv(\"" << path << "\") failed";
+ if (REBOOT_BOOTLOADER_ON_PANIC) {
+ InstallRebootSignalHandlers();
}
- // At this point we're in the second stage of init.
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";