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
This commit is contained in:
parent
81cc9d986f
commit
f1200fb117
4 changed files with 84 additions and 52 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue