diff --git a/init/first_stage_console.cpp b/init/first_stage_console.cpp index 0f0116659..e2ea0ab40 100644 --- a/init/first_stage_console.cpp +++ b/init/first_stage_console.cpp @@ -105,8 +105,20 @@ void StartConsole(const std::string& cmdline) { _exit(127); } -int FirstStageConsole(const std::string& cmdline) { - auto pos = cmdline.find("androidboot.first_stage_console="); +int FirstStageConsole(const std::string& cmdline, const std::string& bootconfig) { + auto pos = bootconfig.find("androidboot.first_stage_console ="); + if (pos != std::string::npos) { + int val = 0; + if (sscanf(bootconfig.c_str() + pos, "androidboot.first_stage_console = \"%d\"", &val) != + 1) { + return FirstStageConsoleParam::DISABLED; + } + if (val <= FirstStageConsoleParam::MAX_PARAM_VALUE && val >= 0) { + return val; + } + } + + pos = cmdline.find("androidboot.first_stage_console="); if (pos != std::string::npos) { int val = 0; if (sscanf(cmdline.c_str() + pos, "androidboot.first_stage_console=%d", &val) != 1) { diff --git a/init/first_stage_console.h b/init/first_stage_console.h index d5744df49..4a30d35ed 100644 --- a/init/first_stage_console.h +++ b/init/first_stage_console.h @@ -29,7 +29,7 @@ enum FirstStageConsoleParam { }; void StartConsole(const std::string& cmdline); -int FirstStageConsole(const std::string& cmdline); +int FirstStageConsole(const std::string& cmdline, const std::string& bootconfig); } // namespace init } // namespace android diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp index ff75aa3c8..b2ab55082 100644 --- a/init/first_stage_init.cpp +++ b/init/first_stage_init.cpp @@ -102,8 +102,9 @@ void FreeRamdisk(DIR* dir, dev_t dev) { } } -bool ForceNormalBoot(const std::string& cmdline) { - return cmdline.find("androidboot.force_normal_boot=1") != std::string::npos; +bool ForceNormalBoot(const std::string& cmdline, const std::string& bootconfig) { + return bootconfig.find("androidboot.force_normal_boot = \"1\"") != std::string::npos || + cmdline.find("androidboot.force_normal_boot=1") != std::string::npos; } } // namespace @@ -211,6 +212,8 @@ int FirstStageMain(int argc, char** argv) { android::base::ReadFileToString("/proc/cmdline", &cmdline); // Don't expose the raw bootconfig to unprivileged processes. chmod("/proc/bootconfig", 0440); + std::string bootconfig; + android::base::ReadFileToString("/proc/bootconfig", &bootconfig); gid_t groups[] = {AID_READPROC}; CHECKCALL(setgroups(arraysize(groups), groups)); CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL)); @@ -278,11 +281,11 @@ int FirstStageMain(int argc, char** argv) { old_root_dir.reset(); } - auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline) : 0; + auto want_console = ALLOW_FIRST_STAGE_CONSOLE ? FirstStageConsole(cmdline, bootconfig) : 0; boot_clock::time_point module_start_time = boot_clock::now(); int module_count = 0; - if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline), want_console, + if (!LoadKernelModules(IsRecoveryMode() && !ForceNormalBoot(cmdline, bootconfig), want_console, module_count)) { if (want_console != FirstStageConsoleParam::DISABLED) { LOG(ERROR) << "Failed to load kernel modules, starting console"; @@ -324,7 +327,7 @@ int FirstStageMain(int argc, char** argv) { LOG(INFO) << "Copied ramdisk prop to " << dest; } - if (ForceNormalBoot(cmdline)) { + if (ForceNormalBoot(cmdline, bootconfig)) { mkdir("/first_stage_ramdisk", 0755); // SwitchRoot() must be called with a mount point as the target, so we bind mount the // target directory to itself here.