Loading init/Android.bp +4 −3 Original line number Diff line number Diff line Loading @@ -242,11 +242,12 @@ cc_binary { ], whole_static_libs: ["libcap"], shared_libs: [ "libprotobuf-cpp-lite", "libcutils", "libhidl-gen-utils", "libprocessgroup", "libjsoncpp", "liblog", "libcutils", "libprocessgroup", "libprotobuf-cpp-lite", ], srcs: [ "action.cpp", Loading init/host_init_verifier.cpp +31 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> #include <fstream> #include <iostream> #include <iterator> #include <string> Loading @@ -29,6 +30,7 @@ #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> #include <json/json.h> #include "action.h" #include "action_manager.h" Loading Loading @@ -129,21 +131,33 @@ passwd* getpwnam(const char* login) { // NOLINT: implementing bad function. return nullptr; } static std::optional<std::set<std::string>> ReadKnownInterfaces( const std::string& known_interfaces_file) { if (known_interfaces_file.empty()) { LOG(WARNING) << "Missing a known interfaces file."; static std::optional<android::init::InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy(const std::string& interface_inheritance_hierarchy_file) { if (interface_inheritance_hierarchy_file.empty()) { LOG(WARNING) << "Missing an interface inheritance hierarchy file."; return {}; } std::string known_interfaces; if (!ReadFileToString(known_interfaces_file, &known_interfaces)) { LOG(ERROR) << "Failed to read known interfaces file '" << known_interfaces_file << "'"; Json::Value root; Json::Reader reader; std::ifstream stream(interface_inheritance_hierarchy_file); if (!reader.parse(stream, root)) { LOG(ERROR) << "Failed to read interface inheritance hierarchy file: " << interface_inheritance_hierarchy_file << "\n" << reader.getFormattedErrorMessages(); return {}; } auto interfaces = Split(known_interfaces, " "); return std::set<std::string>(interfaces.begin(), interfaces.end()); android::init::InterfaceInheritanceHierarchyMap result; for (const Json::Value& entry : root) { std::set<std::string> inherited_interfaces; for (const Json::Value& intf : entry["inheritedInterfaces"]) { inherited_interfaces.insert(intf.asString()); } result[entry["interface"].asString()] = inherited_interfaces; } return result; } namespace android { Loading @@ -169,7 +183,7 @@ int main(int argc, char** argv) { android::base::InitLogging(argv, &android::base::StdioLogger); android::base::SetMinimumLogSeverity(android::base::ERROR); std::string known_interfaces_file; std::string interface_inheritance_hierarchy_file; while (true) { static const struct option long_options[] = { Loading @@ -177,7 +191,7 @@ int main(int argc, char** argv) { {nullptr, 0, nullptr, 0}, }; int arg = getopt_long(argc, argv, "p:k:", long_options, nullptr); int arg = getopt_long(argc, argv, "p:i:", long_options, nullptr); if (arg == -1) { break; Loading @@ -190,8 +204,8 @@ int main(int argc, char** argv) { case 'p': passwd_files.emplace_back(optarg); break; case 'k': known_interfaces_file = optarg; case 'i': interface_inheritance_hierarchy_file = optarg; break; default: std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl; Loading @@ -213,8 +227,10 @@ int main(int argc, char** argv) { ServiceList& sl = ServiceList::GetInstance(); Parser parser; parser.AddSectionParser( "service", std::make_unique<ServiceParser>(&sl, nullptr, ReadKnownInterfaces(known_interfaces_file))); "service", std::make_unique<ServiceParser>( &sl, nullptr, ReadInterfaceInheritanceHierarchy(interface_inheritance_hierarchy_file))); parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr)); parser.AddSectionParser("import", std::make_unique<HostImportParser>()); Loading init/service_parser.cpp +34 −6 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ #include <linux/input.h> #include <algorithm> #include <sstream> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> Loading Loading @@ -152,12 +155,6 @@ Result<void> ServiceParser::ParseInterface(std::vector<std::string>&& args) { return Error() << "Interface name must not be a value name '" << interface_name << "'"; } if (known_interfaces_ && known_interfaces_->count(interface_name) == 0) { return Error() << "Interface is not in the known set of hidl_interfaces: '" << interface_name << "'. Please ensure the interface is built " << "by a hidl_interface target."; } const std::string fullname = interface_name + "/" + instance_name; for (const auto& svc : *service_list_) { Loading Loading @@ -540,6 +537,37 @@ Result<void> ServiceParser::EndSection() { return {}; } if (interface_inheritance_hierarchy_) { std::set<std::string> interface_names; for (const std::string& intf : service_->interfaces()) { interface_names.insert(Split(intf, "/")[0]); } std::ostringstream error_stream; for (const std::string& intf : interface_names) { if (interface_inheritance_hierarchy_->count(intf) == 0) { error_stream << "\nInterface is not in the known set of hidl_interfaces: '" << intf << "'. Please ensure the interface is spelled correctly and built " << "by a hidl_interface target."; continue; } const std::set<std::string>& required_interfaces = (*interface_inheritance_hierarchy_)[intf]; std::set<std::string> diff; std::set_difference(required_interfaces.begin(), required_interfaces.end(), interface_names.begin(), interface_names.end(), std::inserter(diff, diff.begin())); if (!diff.empty()) { error_stream << "\nInterface '" << intf << "' requires its full inheritance " << "hierarchy to be listed in this init_rc file. Missing " << "interfaces: [" << base::Join(diff, " ") << "]"; } } const std::string& errors = error_stream.str(); if (!errors.empty()) { return Error() << errors; } } Service* old_service = service_list_->FindService(service_->name()); if (old_service) { if (!service_->is_override()) { Loading init/service_parser.h +7 −4 Original line number Diff line number Diff line Loading @@ -26,13 +26,16 @@ namespace android { namespace init { using InterfaceInheritanceHierarchyMap = std::map<std::string, std::set<std::string>>; class ServiceParser : public SectionParser { public: ServiceParser(ServiceList* service_list, std::vector<Subcontext>* subcontexts, const std::optional<std::set<std::string>>& known_interfaces) ServiceParser( ServiceList* service_list, std::vector<Subcontext>* subcontexts, const std::optional<InterfaceInheritanceHierarchyMap>& interface_inheritance_hierarchy) : service_list_(service_list), subcontexts_(subcontexts), known_interfaces_(known_interfaces), interface_inheritance_hierarchy_(interface_inheritance_hierarchy), service_(nullptr) {} Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename, int line) override; Loading Loading @@ -85,7 +88,7 @@ class ServiceParser : public SectionParser { ServiceList* service_list_; std::vector<Subcontext>* subcontexts_; std::optional<std::set<std::string>> known_interfaces_; std::optional<InterfaceInheritanceHierarchyMap> interface_inheritance_hierarchy_; std::unique_ptr<Service> service_; std::string filename_; }; Loading Loading
init/Android.bp +4 −3 Original line number Diff line number Diff line Loading @@ -242,11 +242,12 @@ cc_binary { ], whole_static_libs: ["libcap"], shared_libs: [ "libprotobuf-cpp-lite", "libcutils", "libhidl-gen-utils", "libprocessgroup", "libjsoncpp", "liblog", "libcutils", "libprocessgroup", "libprotobuf-cpp-lite", ], srcs: [ "action.cpp", Loading
init/host_init_verifier.cpp +31 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdlib.h> #include <fstream> #include <iostream> #include <iterator> #include <string> Loading @@ -29,6 +30,7 @@ #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> #include <json/json.h> #include "action.h" #include "action_manager.h" Loading Loading @@ -129,21 +131,33 @@ passwd* getpwnam(const char* login) { // NOLINT: implementing bad function. return nullptr; } static std::optional<std::set<std::string>> ReadKnownInterfaces( const std::string& known_interfaces_file) { if (known_interfaces_file.empty()) { LOG(WARNING) << "Missing a known interfaces file."; static std::optional<android::init::InterfaceInheritanceHierarchyMap> ReadInterfaceInheritanceHierarchy(const std::string& interface_inheritance_hierarchy_file) { if (interface_inheritance_hierarchy_file.empty()) { LOG(WARNING) << "Missing an interface inheritance hierarchy file."; return {}; } std::string known_interfaces; if (!ReadFileToString(known_interfaces_file, &known_interfaces)) { LOG(ERROR) << "Failed to read known interfaces file '" << known_interfaces_file << "'"; Json::Value root; Json::Reader reader; std::ifstream stream(interface_inheritance_hierarchy_file); if (!reader.parse(stream, root)) { LOG(ERROR) << "Failed to read interface inheritance hierarchy file: " << interface_inheritance_hierarchy_file << "\n" << reader.getFormattedErrorMessages(); return {}; } auto interfaces = Split(known_interfaces, " "); return std::set<std::string>(interfaces.begin(), interfaces.end()); android::init::InterfaceInheritanceHierarchyMap result; for (const Json::Value& entry : root) { std::set<std::string> inherited_interfaces; for (const Json::Value& intf : entry["inheritedInterfaces"]) { inherited_interfaces.insert(intf.asString()); } result[entry["interface"].asString()] = inherited_interfaces; } return result; } namespace android { Loading @@ -169,7 +183,7 @@ int main(int argc, char** argv) { android::base::InitLogging(argv, &android::base::StdioLogger); android::base::SetMinimumLogSeverity(android::base::ERROR); std::string known_interfaces_file; std::string interface_inheritance_hierarchy_file; while (true) { static const struct option long_options[] = { Loading @@ -177,7 +191,7 @@ int main(int argc, char** argv) { {nullptr, 0, nullptr, 0}, }; int arg = getopt_long(argc, argv, "p:k:", long_options, nullptr); int arg = getopt_long(argc, argv, "p:i:", long_options, nullptr); if (arg == -1) { break; Loading @@ -190,8 +204,8 @@ int main(int argc, char** argv) { case 'p': passwd_files.emplace_back(optarg); break; case 'k': known_interfaces_file = optarg; case 'i': interface_inheritance_hierarchy_file = optarg; break; default: std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl; Loading @@ -213,8 +227,10 @@ int main(int argc, char** argv) { ServiceList& sl = ServiceList::GetInstance(); Parser parser; parser.AddSectionParser( "service", std::make_unique<ServiceParser>(&sl, nullptr, ReadKnownInterfaces(known_interfaces_file))); "service", std::make_unique<ServiceParser>( &sl, nullptr, ReadInterfaceInheritanceHierarchy(interface_inheritance_hierarchy_file))); parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr)); parser.AddSectionParser("import", std::make_unique<HostImportParser>()); Loading
init/service_parser.cpp +34 −6 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ #include <linux/input.h> #include <algorithm> #include <sstream> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> Loading Loading @@ -152,12 +155,6 @@ Result<void> ServiceParser::ParseInterface(std::vector<std::string>&& args) { return Error() << "Interface name must not be a value name '" << interface_name << "'"; } if (known_interfaces_ && known_interfaces_->count(interface_name) == 0) { return Error() << "Interface is not in the known set of hidl_interfaces: '" << interface_name << "'. Please ensure the interface is built " << "by a hidl_interface target."; } const std::string fullname = interface_name + "/" + instance_name; for (const auto& svc : *service_list_) { Loading Loading @@ -540,6 +537,37 @@ Result<void> ServiceParser::EndSection() { return {}; } if (interface_inheritance_hierarchy_) { std::set<std::string> interface_names; for (const std::string& intf : service_->interfaces()) { interface_names.insert(Split(intf, "/")[0]); } std::ostringstream error_stream; for (const std::string& intf : interface_names) { if (interface_inheritance_hierarchy_->count(intf) == 0) { error_stream << "\nInterface is not in the known set of hidl_interfaces: '" << intf << "'. Please ensure the interface is spelled correctly and built " << "by a hidl_interface target."; continue; } const std::set<std::string>& required_interfaces = (*interface_inheritance_hierarchy_)[intf]; std::set<std::string> diff; std::set_difference(required_interfaces.begin(), required_interfaces.end(), interface_names.begin(), interface_names.end(), std::inserter(diff, diff.begin())); if (!diff.empty()) { error_stream << "\nInterface '" << intf << "' requires its full inheritance " << "hierarchy to be listed in this init_rc file. Missing " << "interfaces: [" << base::Join(diff, " ") << "]"; } } const std::string& errors = error_stream.str(); if (!errors.empty()) { return Error() << errors; } } Service* old_service = service_list_->FindService(service_->name()); if (old_service) { if (!service_->is_override()) { Loading
init/service_parser.h +7 −4 Original line number Diff line number Diff line Loading @@ -26,13 +26,16 @@ namespace android { namespace init { using InterfaceInheritanceHierarchyMap = std::map<std::string, std::set<std::string>>; class ServiceParser : public SectionParser { public: ServiceParser(ServiceList* service_list, std::vector<Subcontext>* subcontexts, const std::optional<std::set<std::string>>& known_interfaces) ServiceParser( ServiceList* service_list, std::vector<Subcontext>* subcontexts, const std::optional<InterfaceInheritanceHierarchyMap>& interface_inheritance_hierarchy) : service_list_(service_list), subcontexts_(subcontexts), known_interfaces_(known_interfaces), interface_inheritance_hierarchy_(interface_inheritance_hierarchy), service_(nullptr) {} Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename, int line) override; Loading Loading @@ -85,7 +88,7 @@ class ServiceParser : public SectionParser { ServiceList* service_list_; std::vector<Subcontext>* subcontexts_; std::optional<std::set<std::string>> known_interfaces_; std::optional<InterfaceInheritanceHierarchyMap> interface_inheritance_hierarchy_; std::unique_ptr<Service> service_; std::string filename_; }; Loading