From 79058486d21da9f2c7926196dca83ed446951809 Mon Sep 17 00:00:00 2001 From: Devin Moore Date: Wed, 3 Mar 2021 13:57:43 -0800 Subject: [PATCH] init: handle more bootconfig parameters As parameters are moved from kernel cmdline to bootconfig, first_stage_init needs to be updated to handle the new location. /proc/bootconfig should be checked first, if not present, then check /proc/cmdline. Test: launch_cvd Test: launch_cvd with 4.19 kernel artifacts that do not support bootconfig Test: Both of the above configurations with --num_instances 0 or 4 Test: Both configurations with androidboot.boot_devices or androidboot.boot_device set Bug: 173815685 Change-Id: I03743f922351d58375e8b9a903899b8bc54bd71e --- init/first_stage_console.cpp | 16 ++++++++++++++-- init/first_stage_console.h | 2 +- init/first_stage_init.cpp | 13 ++++++++----- 3 files changed, 23 insertions(+), 8 deletions(-) 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.