From 95c4242cf6eb67b0ae36aeb3e15325919765e3df Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Wed, 21 Aug 2024 13:57:44 +0900 Subject: [PATCH] host_init_verifier: check interface names directly Previously, ServiceParser did the check, but only when it's invoked by host_init_verifier. Host_init_verifier can do it directly, which removes unnecessary runtime dependencies from init. Bug: 326827772 Test: host_init_verifier detects wrong HIDL interface names. Change-Id: I4c8bb0e89a5def7341c48c52af730795a6ee13c0 --- init/host_init_verifier.cpp | 15 +++++++++++-- init/interface_utils.cpp | 42 ++++++++++++++++++------------------- init/interface_utils.h | 2 -- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp index f746ab954..52be0a167 100644 --- a/init/host_init_verifier.cpp +++ b/init/host_init_verifier.cpp @@ -298,8 +298,7 @@ int main(int argc, char** argv) { ServiceList& sl = ServiceList::GetInstance(); Parser parser; parser.AddSectionParser("service", - std::make_unique(&sl, GetSubcontext(), - *interface_inheritance_hierarchy_map)); + std::make_unique(&sl, GetSubcontext(), std::nullopt)); parser.AddSectionParser("on", std::make_unique(&am, GetSubcontext())); parser.AddSectionParser("import", std::make_unique()); @@ -317,11 +316,23 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } } + size_t failures = parser.parse_error_count() + am.CheckAllCommands() + sl.CheckAllCommands(); if (failures > 0) { LOG(ERROR) << "Failed to parse init scripts with " << failures << " error(s)."; return EXIT_FAILURE; } + + for (const auto& service : sl) { + if (const auto& result = CheckInterfaceInheritanceHierarchy( + service->interfaces(), *interface_inheritance_hierarchy_map); + !result.ok()) { + LOG(ERROR) << service->filename() << ": invalid interface in service '" + << service->name() << "': " << result.error(); + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; } diff --git a/init/interface_utils.cpp b/init/interface_utils.cpp index 1b76bba5f..84407aa70 100644 --- a/init/interface_utils.cpp +++ b/init/interface_utils.cpp @@ -39,27 +39,6 @@ std::string FQNamesToString(const std::set& fqnames) { return android::base::Join(fqname_strings, " "); } -} // namespace - -Result CheckInterfaceInheritanceHierarchy(const std::set& instances, - const InterfaceInheritanceHierarchyMap& hierarchy) { - std::set interface_fqnames; - for (const std::string& instance : instances) { - // There is insufficient build-time information on AIDL interfaces to check them here - // TODO(b/139307527): Rework how services store interfaces to avoid excess string parsing - if (base::Split(instance, "/")[0] == "aidl") { - continue; - } - - FqInstance fqinstance; - if (!fqinstance.setTo(instance)) { - return Error() << "Unable to parse interface instance '" << instance << "'"; - } - interface_fqnames.insert(fqinstance.getFqName()); - } - return CheckInterfaceInheritanceHierarchy(interface_fqnames, hierarchy); -} - Result CheckInterfaceInheritanceHierarchy(const std::set& interfaces, const InterfaceInheritanceHierarchyMap& hierarchy) { std::ostringstream error_stream; @@ -90,6 +69,27 @@ Result CheckInterfaceInheritanceHierarchy(const std::set& interfac return {}; } +} // namespace + +Result CheckInterfaceInheritanceHierarchy(const std::set& instances, + const InterfaceInheritanceHierarchyMap& hierarchy) { + std::set interface_fqnames; + for (const std::string& instance : instances) { + // There is insufficient build-time information on AIDL interfaces to check them here + // TODO(b/139307527): Rework how services store interfaces to avoid excess string parsing + if (base::Split(instance, "/")[0] == "aidl") { + continue; + } + + FqInstance fqinstance; + if (!fqinstance.setTo(instance)) { + return Error() << "Unable to parse interface instance '" << instance << "'"; + } + interface_fqnames.insert(fqinstance.getFqName()); + } + return CheckInterfaceInheritanceHierarchy(interface_fqnames, hierarchy); +} + std::optional> known_interfaces; void SetKnownInterfaces(const InterfaceInheritanceHierarchyMap& hierarchy) { diff --git a/init/interface_utils.h b/init/interface_utils.h index 4ca377f64..214fedae1 100644 --- a/init/interface_utils.h +++ b/init/interface_utils.h @@ -34,8 +34,6 @@ using InterfaceInheritanceHierarchyMap = std::map CheckInterfaceInheritanceHierarchy(const std::set& instances, const InterfaceInheritanceHierarchyMap& hierarchy); -Result CheckInterfaceInheritanceHierarchy(const std::set& interfaces, - const InterfaceInheritanceHierarchyMap& hierarchy); // Saves the set of known interfaces using the provided HIDL interface // inheritance hierarchy.