Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e3beff2 authored by Devin Moore's avatar Devin Moore Committed by Automerger Merge Worker
Browse files

Merge "Support bootconfig in first stage init and fs_mgr" am: cb4ebecb

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1580792

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ib5cdbb7f02f963b8316439f3f9d6c0d656503155
parents 27e2d3d4 cb4ebecb
Loading
Loading
Loading
Loading
+56 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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) {
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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);
            }
+6 −1
Original line number Diff line number Diff line
@@ -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 */
+86 −2
Original line number Diff line number Diff line
@@ -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) {
@@ -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));
+2 −0
Original line number Diff line number Diff line
@@ -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