Loading fs_mgr/fs_mgr_boot_config.cpp +56 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ #include "fs_mgr_priv.h" std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline) { std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline) { static constexpr char quote = '"'; std::vector<std::pair<std::string, std::string>> result; Loading Loading @@ -60,12 +60,50 @@ std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const return result; } std::vector<std::pair<std::string, std::string>> fs_mgr_parse_proc_bootconfig( const std::string& cmdline) { static constexpr char quote = '"'; std::vector<std::pair<std::string, std::string>> result; for (auto& line : android::base::Split(cmdline, "\n")) { line.erase(std::remove(line.begin(), line.end(), quote), line.end()); auto equal_sign = line.find('='); if (equal_sign == line.npos) { if (!line.empty()) { // no difference between <key> and <key>= result.emplace_back(std::move(line), ""); } } else { result.emplace_back(android::base::Trim(line.substr(0, equal_sign)), android::base::Trim(line.substr(equal_sign + 1))); } } return result; } bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig, const std::string& android_key, std::string* out_val) { FS_MGR_CHECK(out_val != nullptr); const std::string bootconfig_key("androidboot." + android_key); for (const auto& [key, value] : fs_mgr_parse_proc_bootconfig(bootconfig)) { if (key == bootconfig_key) { *out_val = value; return true; } } *out_val = ""; return false; } bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& android_key, std::string* out_val) { FS_MGR_CHECK(out_val != nullptr); const std::string cmdline_key("androidboot." + android_key); for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) { for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) { if (key == cmdline_key) { *out_val = value; return true; Loading @@ -76,6 +114,17 @@ bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::s return false; } // Tries to get the given boot config value from bootconfig. // Returns true if successfully found, false otherwise. bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val) { std::string bootconfig; if (!android::base::ReadFileToString("/proc/bootconfig", &bootconfig)) return false; if (!bootconfig.empty() && bootconfig.back() == '\n') { bootconfig.pop_back(); } return fs_mgr_get_boot_config_from_bootconfig(bootconfig, key, out_val); } // Tries to get the given boot config value from kernel cmdline. // Returns true if successfully found, false otherwise. bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) { Loading Loading @@ -110,6 +159,11 @@ bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { return true; } // next, check if we have the property in bootconfig if (fs_mgr_get_boot_config_from_bootconfig_source(key, out_val)) { return true; } // finally, fallback to kernel cmdline, properties may not be ready yet if (fs_mgr_get_boot_config_from_kernel_cmdline(key, out_val)) { return true; Loading fs_mgr/fs_mgr_fstab.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -854,7 +854,7 @@ std::set<std::string> GetBootDevices() { if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) { std::set<std::string> boot_devices; const std::string cmdline_key = "androidboot.boot_device"; for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) { for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) { if (key == cmdline_key) { boot_devices.emplace(value); } Loading fs_mgr/fs_mgr_priv_boot_config.h +6 −1 Original line number Diff line number Diff line Loading @@ -22,11 +22,16 @@ #include <utility> #include <vector> std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline); std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline); bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& key, std::string* out_val); bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val); bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val); std::vector<std::pair<std::string, std::string>> fs_mgr_parse_proc_bootconfig( const std::string& bootconfig); bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig, const std::string& key, std::string* out_val); bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val); #endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */ fs_mgr/tests/fs_mgr_test.cpp +86 −2 Original line number Diff line number Diff line Loading @@ -119,10 +119,73 @@ const std::vector<std::pair<std::string, std::string>> result_space = { {"terminator", "truncated"}, }; const std::string bootconfig = "androidboot.bootdevice = \" \"1d84000.ufshc\"\n" "androidboot.baseband = \"sdy\"\n" "androidboot.keymaster = \"1\"\n" "androidboot.serialno = \"BLAHBLAHBLAH\"\n" "androidboot.slot_suffix = \"_a\"\n" "androidboot.hardware.platform = \"sdw813\"\n" "androidboot.hardware = \"foo\"\n" "androidboot.revision = \"EVT1.0\"\n" "androidboot.bootloader = \"burp-0.1-7521\"\n" "androidboot.hardware.sku = \"mary\"\n" "androidboot.hardware.radio.subtype = \"0\"\n" "androidboot.dtbo_idx = \"2\"\n" "androidboot.mode = \"normal\"\n" "androidboot.hardware.ddr = \"1GB,combuchi,LPDDR4X\"\n" "androidboot.ddr_info = \"combuchiandroidboot.ddr_size=2GB\"\n" "androidboot.hardware.ufs = \"2GB,combushi\"\n" "androidboot.boottime = \"0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123\"\n" "androidboot.ramdump = \"disabled\"\n" "androidboot.vbmeta.device = \"PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb\"\n" "androidboot.vbmeta.avb_version = \"1.1\"\n" "androidboot.vbmeta.device_state = \"unlocked\"\n" "androidboot.vbmeta.hash_alg = \"sha256\"\n" "androidboot.vbmeta.size = \"5248\"\n" "androidboot.vbmeta.digest = \"" "ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860\"\n" "androidboot.vbmeta.invalidate_on_error = \"yes\"\n" "androidboot.veritymode = \"enforcing\"\n" "androidboot.verifiedbootstate = \"orange\"\n" "androidboot.space = \"sha256 5248 androidboot.nospace = nope\"\n"; const std::vector<std::pair<std::string, std::string>> bootconfig_result_space = { {"androidboot.bootdevice", "1d84000.ufshc"}, {"androidboot.baseband", "sdy"}, {"androidboot.keymaster", "1"}, {"androidboot.serialno", "BLAHBLAHBLAH"}, {"androidboot.slot_suffix", "_a"}, {"androidboot.hardware.platform", "sdw813"}, {"androidboot.hardware", "foo"}, {"androidboot.revision", "EVT1.0"}, {"androidboot.bootloader", "burp-0.1-7521"}, {"androidboot.hardware.sku", "mary"}, {"androidboot.hardware.radio.subtype", "0"}, {"androidboot.dtbo_idx", "2"}, {"androidboot.mode", "normal"}, {"androidboot.hardware.ddr", "1GB,combuchi,LPDDR4X"}, {"androidboot.ddr_info", "combuchiandroidboot.ddr_size=2GB"}, {"androidboot.hardware.ufs", "2GB,combushi"}, {"androidboot.boottime", "0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123"}, {"androidboot.ramdump", "disabled"}, {"androidboot.vbmeta.device", "PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb"}, {"androidboot.vbmeta.avb_version", "1.1"}, {"androidboot.vbmeta.device_state", "unlocked"}, {"androidboot.vbmeta.hash_alg", "sha256"}, {"androidboot.vbmeta.size", "5248"}, {"androidboot.vbmeta.digest", "ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860"}, {"androidboot.vbmeta.invalidate_on_error", "yes"}, {"androidboot.veritymode", "enforcing"}, {"androidboot.verifiedbootstate", "orange"}, {"androidboot.space", "sha256 5248 androidboot.nospace = nope"}, }; } // namespace TEST(fs_mgr, fs_mgr_parse_boot_config) { EXPECT_EQ(result_space, fs_mgr_parse_boot_config(cmdline)); TEST(fs_mgr, fs_mgr_parse_cmdline) { EXPECT_EQ(result_space, fs_mgr_parse_cmdline(cmdline)); } TEST(fs_mgr, fs_mgr_get_boot_config_from_kernel_cmdline) { Loading @@ -140,6 +203,27 @@ TEST(fs_mgr, fs_mgr_get_boot_config_from_kernel_cmdline) { EXPECT_TRUE(content.empty()) << content; } TEST(fs_mgr, fs_mgr_parse_bootconfig) { EXPECT_EQ(bootconfig_result_space, fs_mgr_parse_proc_bootconfig(bootconfig)); } TEST(fs_mgr, fs_mgr_get_boot_config_from_bootconfig) { std::string content; for (const auto& entry : bootconfig_result_space) { static constexpr char androidboot[] = "androidboot."; if (!android::base::StartsWith(entry.first, androidboot)) continue; auto key = entry.first.substr(strlen(androidboot)); EXPECT_TRUE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, key, &content)) << " for " << key; EXPECT_EQ(entry.second, content); } EXPECT_FALSE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, "vbmeta.avb_versio", &content)); EXPECT_TRUE(content.empty()) << content; EXPECT_FALSE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, "nospace", &content)); EXPECT_TRUE(content.empty()) << content; } TEST(fs_mgr, fs_mgr_read_fstab_file_proc_mounts) { Fstab fstab; ASSERT_TRUE(ReadFstabFromFile("/proc/mounts", &fstab)); Loading init/first_stage_init.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,8 @@ int FirstStageMain(int argc, char** argv) { CHECKCALL(chmod("/proc/cmdline", 0440)); std::string cmdline; android::base::ReadFileToString("/proc/cmdline", &cmdline); // Don't expose the raw bootconfig to unprivileged processes. chmod("/proc/bootconfig", 0440); gid_t groups[] = {AID_READPROC}; CHECKCALL(setgroups(arraysize(groups), groups)); CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL)); Loading Loading
fs_mgr/fs_mgr_boot_config.cpp +56 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ #include "fs_mgr_priv.h" std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline) { std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline) { static constexpr char quote = '"'; std::vector<std::pair<std::string, std::string>> result; Loading Loading @@ -60,12 +60,50 @@ std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const return result; } std::vector<std::pair<std::string, std::string>> fs_mgr_parse_proc_bootconfig( const std::string& cmdline) { static constexpr char quote = '"'; std::vector<std::pair<std::string, std::string>> result; for (auto& line : android::base::Split(cmdline, "\n")) { line.erase(std::remove(line.begin(), line.end(), quote), line.end()); auto equal_sign = line.find('='); if (equal_sign == line.npos) { if (!line.empty()) { // no difference between <key> and <key>= result.emplace_back(std::move(line), ""); } } else { result.emplace_back(android::base::Trim(line.substr(0, equal_sign)), android::base::Trim(line.substr(equal_sign + 1))); } } return result; } bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig, const std::string& android_key, std::string* out_val) { FS_MGR_CHECK(out_val != nullptr); const std::string bootconfig_key("androidboot." + android_key); for (const auto& [key, value] : fs_mgr_parse_proc_bootconfig(bootconfig)) { if (key == bootconfig_key) { *out_val = value; return true; } } *out_val = ""; return false; } bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& android_key, std::string* out_val) { FS_MGR_CHECK(out_val != nullptr); const std::string cmdline_key("androidboot." + android_key); for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) { for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) { if (key == cmdline_key) { *out_val = value; return true; Loading @@ -76,6 +114,17 @@ bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::s return false; } // Tries to get the given boot config value from bootconfig. // Returns true if successfully found, false otherwise. bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val) { std::string bootconfig; if (!android::base::ReadFileToString("/proc/bootconfig", &bootconfig)) return false; if (!bootconfig.empty() && bootconfig.back() == '\n') { bootconfig.pop_back(); } return fs_mgr_get_boot_config_from_bootconfig(bootconfig, key, out_val); } // Tries to get the given boot config value from kernel cmdline. // Returns true if successfully found, false otherwise. bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) { Loading Loading @@ -110,6 +159,11 @@ bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { return true; } // next, check if we have the property in bootconfig if (fs_mgr_get_boot_config_from_bootconfig_source(key, out_val)) { return true; } // finally, fallback to kernel cmdline, properties may not be ready yet if (fs_mgr_get_boot_config_from_kernel_cmdline(key, out_val)) { return true; Loading
fs_mgr/fs_mgr_fstab.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -854,7 +854,7 @@ std::set<std::string> GetBootDevices() { if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) { std::set<std::string> boot_devices; const std::string cmdline_key = "androidboot.boot_device"; for (const auto& [key, value] : fs_mgr_parse_boot_config(cmdline)) { for (const auto& [key, value] : fs_mgr_parse_cmdline(cmdline)) { if (key == cmdline_key) { boot_devices.emplace(value); } Loading
fs_mgr/fs_mgr_priv_boot_config.h +6 −1 Original line number Diff line number Diff line Loading @@ -22,11 +22,16 @@ #include <utility> #include <vector> std::vector<std::pair<std::string, std::string>> fs_mgr_parse_boot_config(const std::string& cmdline); std::vector<std::pair<std::string, std::string>> fs_mgr_parse_cmdline(const std::string& cmdline); bool fs_mgr_get_boot_config_from_kernel(const std::string& cmdline, const std::string& key, std::string* out_val); bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val); bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val); std::vector<std::pair<std::string, std::string>> fs_mgr_parse_proc_bootconfig( const std::string& bootconfig); bool fs_mgr_get_boot_config_from_bootconfig(const std::string& bootconfig, const std::string& key, std::string* out_val); bool fs_mgr_get_boot_config_from_bootconfig_source(const std::string& key, std::string* out_val); #endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
fs_mgr/tests/fs_mgr_test.cpp +86 −2 Original line number Diff line number Diff line Loading @@ -119,10 +119,73 @@ const std::vector<std::pair<std::string, std::string>> result_space = { {"terminator", "truncated"}, }; const std::string bootconfig = "androidboot.bootdevice = \" \"1d84000.ufshc\"\n" "androidboot.baseband = \"sdy\"\n" "androidboot.keymaster = \"1\"\n" "androidboot.serialno = \"BLAHBLAHBLAH\"\n" "androidboot.slot_suffix = \"_a\"\n" "androidboot.hardware.platform = \"sdw813\"\n" "androidboot.hardware = \"foo\"\n" "androidboot.revision = \"EVT1.0\"\n" "androidboot.bootloader = \"burp-0.1-7521\"\n" "androidboot.hardware.sku = \"mary\"\n" "androidboot.hardware.radio.subtype = \"0\"\n" "androidboot.dtbo_idx = \"2\"\n" "androidboot.mode = \"normal\"\n" "androidboot.hardware.ddr = \"1GB,combuchi,LPDDR4X\"\n" "androidboot.ddr_info = \"combuchiandroidboot.ddr_size=2GB\"\n" "androidboot.hardware.ufs = \"2GB,combushi\"\n" "androidboot.boottime = \"0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123\"\n" "androidboot.ramdump = \"disabled\"\n" "androidboot.vbmeta.device = \"PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb\"\n" "androidboot.vbmeta.avb_version = \"1.1\"\n" "androidboot.vbmeta.device_state = \"unlocked\"\n" "androidboot.vbmeta.hash_alg = \"sha256\"\n" "androidboot.vbmeta.size = \"5248\"\n" "androidboot.vbmeta.digest = \"" "ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860\"\n" "androidboot.vbmeta.invalidate_on_error = \"yes\"\n" "androidboot.veritymode = \"enforcing\"\n" "androidboot.verifiedbootstate = \"orange\"\n" "androidboot.space = \"sha256 5248 androidboot.nospace = nope\"\n"; const std::vector<std::pair<std::string, std::string>> bootconfig_result_space = { {"androidboot.bootdevice", "1d84000.ufshc"}, {"androidboot.baseband", "sdy"}, {"androidboot.keymaster", "1"}, {"androidboot.serialno", "BLAHBLAHBLAH"}, {"androidboot.slot_suffix", "_a"}, {"androidboot.hardware.platform", "sdw813"}, {"androidboot.hardware", "foo"}, {"androidboot.revision", "EVT1.0"}, {"androidboot.bootloader", "burp-0.1-7521"}, {"androidboot.hardware.sku", "mary"}, {"androidboot.hardware.radio.subtype", "0"}, {"androidboot.dtbo_idx", "2"}, {"androidboot.mode", "normal"}, {"androidboot.hardware.ddr", "1GB,combuchi,LPDDR4X"}, {"androidboot.ddr_info", "combuchiandroidboot.ddr_size=2GB"}, {"androidboot.hardware.ufs", "2GB,combushi"}, {"androidboot.boottime", "0BLE:58,1BLL:22,1BLE:571,2BLL:105,ODT:0,AVB:123"}, {"androidboot.ramdump", "disabled"}, {"androidboot.vbmeta.device", "PARTUUID=aa08f1a4-c7c9-402e-9a66-9707cafa9ceb"}, {"androidboot.vbmeta.avb_version", "1.1"}, {"androidboot.vbmeta.device_state", "unlocked"}, {"androidboot.vbmeta.hash_alg", "sha256"}, {"androidboot.vbmeta.size", "5248"}, {"androidboot.vbmeta.digest", "ac13147e959861c20f2a6da97d25fe79e60e902c022a371c5c039d31e7c68860"}, {"androidboot.vbmeta.invalidate_on_error", "yes"}, {"androidboot.veritymode", "enforcing"}, {"androidboot.verifiedbootstate", "orange"}, {"androidboot.space", "sha256 5248 androidboot.nospace = nope"}, }; } // namespace TEST(fs_mgr, fs_mgr_parse_boot_config) { EXPECT_EQ(result_space, fs_mgr_parse_boot_config(cmdline)); TEST(fs_mgr, fs_mgr_parse_cmdline) { EXPECT_EQ(result_space, fs_mgr_parse_cmdline(cmdline)); } TEST(fs_mgr, fs_mgr_get_boot_config_from_kernel_cmdline) { Loading @@ -140,6 +203,27 @@ TEST(fs_mgr, fs_mgr_get_boot_config_from_kernel_cmdline) { EXPECT_TRUE(content.empty()) << content; } TEST(fs_mgr, fs_mgr_parse_bootconfig) { EXPECT_EQ(bootconfig_result_space, fs_mgr_parse_proc_bootconfig(bootconfig)); } TEST(fs_mgr, fs_mgr_get_boot_config_from_bootconfig) { std::string content; for (const auto& entry : bootconfig_result_space) { static constexpr char androidboot[] = "androidboot."; if (!android::base::StartsWith(entry.first, androidboot)) continue; auto key = entry.first.substr(strlen(androidboot)); EXPECT_TRUE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, key, &content)) << " for " << key; EXPECT_EQ(entry.second, content); } EXPECT_FALSE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, "vbmeta.avb_versio", &content)); EXPECT_TRUE(content.empty()) << content; EXPECT_FALSE(fs_mgr_get_boot_config_from_bootconfig(bootconfig, "nospace", &content)); EXPECT_TRUE(content.empty()) << content; } TEST(fs_mgr, fs_mgr_read_fstab_file_proc_mounts) { Fstab fstab; ASSERT_TRUE(ReadFstabFromFile("/proc/mounts", &fstab)); Loading
init/first_stage_init.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,8 @@ int FirstStageMain(int argc, char** argv) { CHECKCALL(chmod("/proc/cmdline", 0440)); std::string cmdline; android::base::ReadFileToString("/proc/cmdline", &cmdline); // Don't expose the raw bootconfig to unprivileged processes. chmod("/proc/bootconfig", 0440); gid_t groups[] = {AID_READPROC}; CHECKCALL(setgroups(arraysize(groups), groups)); CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL)); Loading