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

Commit f1200fb1 authored by Daniel Norman's avatar Daniel Norman
Browse files

Adds an init host lib for use in host_apex_verifier.

Includes extracting the APEX-specific SDK version naming scheme filter
logic so it can be reused when host_apex_verifier looks at rc files
inside the APEX.

Bug: 222121216
Test: Use in host_apex_verifier
Change-Id: I0396a455f30d2de71525ccd3fa69c75576054048
parent 81cc9d98
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -532,8 +532,8 @@ genrule {
    cmd: "$(location host_builtin_map.py) --builtins $(location builtins.cpp) --check_builtins $(location check_builtins.cpp) > $(out)",
}

cc_binary {
    name: "host_init_verifier",
cc_defaults {
    name: "init_host_defaults",
    host_supported: true,
    cflags: [
        "-Wall",
@@ -556,7 +556,6 @@ cc_binary {
        "libprocessgroup",
        "libprotobuf-cpp-lite",
    ],
    srcs: init_common_sources + init_host_sources,
    proto: {
        type: "lite",
    },
@@ -574,6 +573,26 @@ cc_binary {
    },
}

cc_binary {
    name: "host_init_verifier",
    defaults: ["init_host_defaults"],
    srcs: init_common_sources + init_host_sources,
}

cc_library_host_static {
    name: "libinit_host",
    defaults: ["init_host_defaults"],
    srcs: init_common_sources,
    export_include_dirs: ["."],
    proto: {
        export_proto_headers: true,
    },
    visibility: [
        // host_apex_verifier performs a subset of init.rc validation
        "//system/apex/tools",
    ],
}

sh_binary {
    name: "extra_free_kbytes.sh",
    src: "extra_free_kbytes.sh",
+2 −49
Original line number Diff line number Diff line
@@ -1306,58 +1306,11 @@ static Result<void> parse_apex_configs() {
    }
    globfree(&glob_result);

    // Compare all files /apex/path.#rc and /apex/path.rc with the same "/apex/path" prefix,
    // choosing the one with the highest # that doesn't exceed the system's SDK.
    // (.rc == .0rc for ranking purposes)
    //
    int active_sdk = android::base::GetIntProperty("ro.build.version.sdk", INT_MAX);

    std::map<std::string, std::pair<std::string, int>> script_map;

    for (const auto& c : configs) {
        int sdk = 0;
        const std::vector<std::string> parts = android::base::Split(c, ".");
        std::string base;
        if (parts.size() < 2) {
            continue;
        }

        // parts[size()-1], aka the suffix, should be "rc" or "#rc"
        // any other pattern gets discarded

        const auto& suffix = parts[parts.size() - 1];
        if (suffix == "rc") {
            sdk = 0;
        } else {
            char trailer[9] = {0};
            int r = sscanf(suffix.c_str(), "%d%8s", &sdk, trailer);
            if (r != 2) {
                continue;
            }
            if (strlen(trailer) > 2 || strcmp(trailer, "rc") != 0) {
                continue;
            }
        }

        if (sdk < 0 || sdk > active_sdk) {
            continue;
        }

        base = parts[0];
        for (unsigned int i = 1; i < parts.size() - 1; i++) {
            base = base + "." + parts[i];
        }

        // is this preferred over what we already have
        auto it = script_map.find(base);
        if (it == script_map.end() || it->second.second < sdk) {
            script_map[base] = std::make_pair(c, sdk);
        }
    }

    bool success = true;
    for (const auto& m : script_map) {
        success &= parser.ParseConfigFile(m.second.first);
    for (const auto& c : parser.FilterVersionedConfigs(configs, active_sdk)) {
        success &= parser.ParseConfigFile(c);
    }
    ServiceList::GetInstance().MarkServicesUpdate();
    if (success) {
+54 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@

#include <dirent.h>

#include <map>

#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -154,6 +156,58 @@ bool Parser::ParseConfigFile(const std::string& path) {
    return true;
}

std::vector<std::string> Parser::FilterVersionedConfigs(const std::vector<std::string>& configs,
                                                        int active_sdk) {
    std::vector<std::string> filtered_configs;

    std::map<std::string, std::pair<std::string, int>> script_map;
    for (const auto& c : configs) {
        int sdk = 0;
        const std::vector<std::string> parts = android::base::Split(c, ".");
        std::string base;
        if (parts.size() < 2) {
            continue;
        }

        // parts[size()-1], aka the suffix, should be "rc" or "#rc"
        // any other pattern gets discarded

        const auto& suffix = parts[parts.size() - 1];
        if (suffix == "rc") {
            sdk = 0;
        } else {
            char trailer[9] = {0};
            int r = sscanf(suffix.c_str(), "%d%8s", &sdk, trailer);
            if (r != 2) {
                continue;
            }
            if (strlen(trailer) > 2 || strcmp(trailer, "rc") != 0) {
                continue;
            }
        }

        if (sdk < 0 || sdk > active_sdk) {
            continue;
        }

        base = parts[0];
        for (unsigned int i = 1; i < parts.size() - 1; i++) {
            base = base + "." + parts[i];
        }

        // is this preferred over what we already have
        auto it = script_map.find(base);
        if (it == script_map.end() || it->second.second < sdk) {
            script_map[base] = std::make_pair(c, sdk);
        }
    }

    for (const auto& m : script_map) {
        filtered_configs.push_back(m.second.first);
    }
    return filtered_configs;
}

bool Parser::ParseConfigDir(const std::string& path) {
    LOG(INFO) << "Parsing directory " << path << "...";
    std::unique_ptr<DIR, decltype(&closedir)> config_dir(opendir(path.c_str()), closedir);
+6 −0
Original line number Diff line number Diff line
@@ -76,6 +76,12 @@ class Parser {
    void AddSectionParser(const std::string& name, std::unique_ptr<SectionParser> parser);
    void AddSingleLineParser(const std::string& prefix, LineCallback callback);

    // Compare all files */path.#rc and */path.rc with the same path prefix.
    // Keep the one with the highest # that doesn't exceed the system's SDK.
    // (.rc == .0rc for ranking purposes)
    std::vector<std::string> FilterVersionedConfigs(const std::vector<std::string>& configs,
                                                    int active_sdk);

    // Host init verifier check file permissions.
    bool ParseConfigFileInsecure(const std::string& path);