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

Commit 95c4242c authored by Jooyung Han's avatar Jooyung Han
Browse files

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
parent d6790c4b
Loading
Loading
Loading
Loading
+13 −2
Original line number Original line Diff line number Diff line
@@ -298,8 +298,7 @@ int main(int argc, char** argv) {
    ServiceList& sl = ServiceList::GetInstance();
    ServiceList& sl = ServiceList::GetInstance();
    Parser parser;
    Parser parser;
    parser.AddSectionParser("service",
    parser.AddSectionParser("service",
                            std::make_unique<ServiceParser>(&sl, GetSubcontext(),
                            std::make_unique<ServiceParser>(&sl, GetSubcontext(), std::nullopt));
                                                            *interface_inheritance_hierarchy_map));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, GetSubcontext()));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, GetSubcontext()));
    parser.AddSectionParser("import", std::make_unique<HostImportParser>());
    parser.AddSectionParser("import", std::make_unique<HostImportParser>());


@@ -317,11 +316,23 @@ int main(int argc, char** argv) {
            return EXIT_FAILURE;
            return EXIT_FAILURE;
        }
        }
    }
    }

    size_t failures = parser.parse_error_count() + am.CheckAllCommands() + sl.CheckAllCommands();
    size_t failures = parser.parse_error_count() + am.CheckAllCommands() + sl.CheckAllCommands();
    if (failures > 0) {
    if (failures > 0) {
        LOG(ERROR) << "Failed to parse init scripts with " << failures << " error(s).";
        LOG(ERROR) << "Failed to parse init scripts with " << failures << " error(s).";
        return EXIT_FAILURE;
        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;
    return EXIT_SUCCESS;
}
}


+21 −21
Original line number Original line Diff line number Diff line
@@ -39,27 +39,6 @@ std::string FQNamesToString(const std::set<FQName>& fqnames) {
    return android::base::Join(fqname_strings, " ");
    return android::base::Join(fqname_strings, " ");
}
}


}  // namespace

Result<void> CheckInterfaceInheritanceHierarchy(const std::set<std::string>& instances,
                                                const InterfaceInheritanceHierarchyMap& hierarchy) {
    std::set<FQName> 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<void> CheckInterfaceInheritanceHierarchy(const std::set<FQName>& interfaces,
Result<void> CheckInterfaceInheritanceHierarchy(const std::set<FQName>& interfaces,
                                                const InterfaceInheritanceHierarchyMap& hierarchy) {
                                                const InterfaceInheritanceHierarchyMap& hierarchy) {
    std::ostringstream error_stream;
    std::ostringstream error_stream;
@@ -90,6 +69,27 @@ Result<void> CheckInterfaceInheritanceHierarchy(const std::set<FQName>& interfac
    return {};
    return {};
}
}


}  // namespace

Result<void> CheckInterfaceInheritanceHierarchy(const std::set<std::string>& instances,
                                                const InterfaceInheritanceHierarchyMap& hierarchy) {
    std::set<FQName> 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<std::set<FQName>> known_interfaces;
std::optional<std::set<FQName>> known_interfaces;


void SetKnownInterfaces(const InterfaceInheritanceHierarchyMap& hierarchy) {
void SetKnownInterfaces(const InterfaceInheritanceHierarchyMap& hierarchy) {
+0 −2
Original line number Original line Diff line number Diff line
@@ -34,8 +34,6 @@ using InterfaceInheritanceHierarchyMap = std::map<android::FQName, std::set<andr
// interface set. Uses the provided hierarchy data.
// interface set. Uses the provided hierarchy data.
Result<void> CheckInterfaceInheritanceHierarchy(const std::set<std::string>& instances,
Result<void> CheckInterfaceInheritanceHierarchy(const std::set<std::string>& instances,
                                                const InterfaceInheritanceHierarchyMap& hierarchy);
                                                const InterfaceInheritanceHierarchyMap& hierarchy);
Result<void> CheckInterfaceInheritanceHierarchy(const std::set<android::FQName>& interfaces,
                                                const InterfaceInheritanceHierarchyMap& hierarchy);


// Saves the set of known interfaces using the provided HIDL interface
// Saves the set of known interfaces using the provided HIDL interface
// inheritance hierarchy.
// inheritance hierarchy.