Loading libmodprobe/include/modprobe/modprobe.h +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <set> #include <string> #include <unordered_map> #include <vector> Loading @@ -28,6 +29,7 @@ class Modprobe { bool LoadWithAliases(const std::string& module_name, bool strict, const std::string& parameters = ""); bool Remove(const std::string& module_name); void EnableBlacklist(bool enable); private: std::string MakeCanonical(const std::string& module_path); Loading @@ -42,6 +44,7 @@ class Modprobe { bool ParseSoftdepCallback(const std::vector<std::string>& args); bool ParseLoadCallback(const std::vector<std::string>& args); bool ParseOptionsCallback(const std::vector<std::string>& args); bool ParseBlacklistCallback(const std::vector<std::string>& args); void ParseCfg(const std::string& cfg, std::function<bool(const std::vector<std::string>&)> f); std::vector<std::pair<std::string, std::string>> module_aliases_; Loading @@ -50,4 +53,6 @@ class Modprobe { std::vector<std::pair<std::string, std::string>> module_post_softdep_; std::vector<std::string> module_load_; std::unordered_map<std::string, std::string> module_options_; std::set<std::string> module_blacklist_; bool blacklist_enabled = false; }; libmodprobe/libmodprobe.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,31 @@ bool Modprobe::ParseOptionsCallback(const std::vector<std::string>& args) { return true; } bool Modprobe::ParseBlacklistCallback(const std::vector<std::string>& args) { auto it = args.begin(); const std::string& type = *it++; if (type != "blacklist") { LOG(ERROR) << "non-blacklist line encountered in modules.blacklist"; return false; } if (args.size() != 2) { LOG(ERROR) << "lines in modules.blacklist must have exactly 2 entries, not " << args.size(); return false; } const std::string& module = *it++; const std::string& canonical_name = MakeCanonical(module); if (canonical_name.empty()) { return false; } this->module_blacklist_.emplace(canonical_name); return true; } void Modprobe::ParseCfg(const std::string& cfg, std::function<bool(const std::vector<std::string>&)> f) { std::string cfg_contents; Loading Loading @@ -231,9 +256,16 @@ Modprobe::Modprobe(const std::vector<std::string>& base_paths) { auto options_callback = std::bind(&Modprobe::ParseOptionsCallback, this, _1); ParseCfg(base_path + "/modules.options", options_callback); auto blacklist_callback = std::bind(&Modprobe::ParseBlacklistCallback, this, _1); ParseCfg(base_path + "/modules.blacklist", blacklist_callback); } } void Modprobe::EnableBlacklist(bool enable) { blacklist_enabled = enable; } std::vector<std::string> Modprobe::GetDependencies(const std::string& module) { auto it = module_deps_.find(module); if (it == module_deps_.end()) { Loading libmodprobe/libmodprobe_ext.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,9 @@ bool Modprobe::Rmmod(const std::string& module_name) { bool Modprobe::ModuleExists(const std::string& module_name) { struct stat fileStat; if (blacklist_enabled && module_blacklist_.count(module_name)) { return false; } auto deps = GetDependencies(module_name); if (deps.empty()) { // missing deps can happen in the case of an alias Loading libmodprobe/libmodprobe_ext_test.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,9 @@ bool Modprobe::Rmmod(const std::string& module_name) { bool Modprobe::ModuleExists(const std::string& module_name) { auto deps = GetDependencies(module_name); if (blacklist_enabled && module_blacklist_.count(module_name)) { return false; } if (deps.empty()) { // missing deps can happen in the case of an alias return false; Loading libmodprobe/libmodprobe_test.cpp +21 −11 Original line number Diff line number Diff line Loading @@ -99,6 +99,10 @@ TEST(libmodprobe, Test) { "options test9.ko param_x=1 param_y=2 param_z=3\n" "options test100.ko param_1=1\n"; const std::string modules_blacklist = "blacklist test9.ko\n" "blacklist test3.ko\n"; const std::string modules_load = "test4.ko\n" "test1.ko\n" Loading @@ -109,17 +113,20 @@ TEST(libmodprobe, Test) { "test11.ko\n"; TemporaryDir dir; ASSERT_TRUE(android::base::WriteStringToFile( modules_alias, std::string(dir.path) + "/modules.alias", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_dep, std::string(dir.path) + "/modules.dep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_softdep, std::string(dir.path) + "/modules.softdep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_options, std::string(dir.path) + "/modules.options", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_load, std::string(dir.path) + "/modules.load", 0600, getuid(), getgid())); auto dir_path = std::string(dir.path); ASSERT_TRUE(android::base::WriteStringToFile(modules_alias, dir_path + "/modules.alias", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_dep, dir_path + "/modules.dep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_softdep, dir_path + "/modules.softdep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_options, dir_path + "/modules.options", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_load, dir_path + "/modules.load", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_blacklist, dir_path + "/modules.blacklist", 0600, getuid(), getgid())); for (auto i = test_modules.begin(); i != test_modules.end(); ++i) { *i = dir.path + *i; Loading Loading @@ -153,4 +160,7 @@ TEST(libmodprobe, Test) { } EXPECT_TRUE(modules_loaded == expected_after_remove); m.EnableBlacklist(true); EXPECT_FALSE(m.LoadWithAliases("test4", true)); } Loading
libmodprobe/include/modprobe/modprobe.h +5 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <set> #include <string> #include <unordered_map> #include <vector> Loading @@ -28,6 +29,7 @@ class Modprobe { bool LoadWithAliases(const std::string& module_name, bool strict, const std::string& parameters = ""); bool Remove(const std::string& module_name); void EnableBlacklist(bool enable); private: std::string MakeCanonical(const std::string& module_path); Loading @@ -42,6 +44,7 @@ class Modprobe { bool ParseSoftdepCallback(const std::vector<std::string>& args); bool ParseLoadCallback(const std::vector<std::string>& args); bool ParseOptionsCallback(const std::vector<std::string>& args); bool ParseBlacklistCallback(const std::vector<std::string>& args); void ParseCfg(const std::string& cfg, std::function<bool(const std::vector<std::string>&)> f); std::vector<std::pair<std::string, std::string>> module_aliases_; Loading @@ -50,4 +53,6 @@ class Modprobe { std::vector<std::pair<std::string, std::string>> module_post_softdep_; std::vector<std::string> module_load_; std::unordered_map<std::string, std::string> module_options_; std::set<std::string> module_blacklist_; bool blacklist_enabled = false; };
libmodprobe/libmodprobe.cpp +32 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,31 @@ bool Modprobe::ParseOptionsCallback(const std::vector<std::string>& args) { return true; } bool Modprobe::ParseBlacklistCallback(const std::vector<std::string>& args) { auto it = args.begin(); const std::string& type = *it++; if (type != "blacklist") { LOG(ERROR) << "non-blacklist line encountered in modules.blacklist"; return false; } if (args.size() != 2) { LOG(ERROR) << "lines in modules.blacklist must have exactly 2 entries, not " << args.size(); return false; } const std::string& module = *it++; const std::string& canonical_name = MakeCanonical(module); if (canonical_name.empty()) { return false; } this->module_blacklist_.emplace(canonical_name); return true; } void Modprobe::ParseCfg(const std::string& cfg, std::function<bool(const std::vector<std::string>&)> f) { std::string cfg_contents; Loading Loading @@ -231,9 +256,16 @@ Modprobe::Modprobe(const std::vector<std::string>& base_paths) { auto options_callback = std::bind(&Modprobe::ParseOptionsCallback, this, _1); ParseCfg(base_path + "/modules.options", options_callback); auto blacklist_callback = std::bind(&Modprobe::ParseBlacklistCallback, this, _1); ParseCfg(base_path + "/modules.blacklist", blacklist_callback); } } void Modprobe::EnableBlacklist(bool enable) { blacklist_enabled = enable; } std::vector<std::string> Modprobe::GetDependencies(const std::string& module) { auto it = module_deps_.find(module); if (it == module_deps_.end()) { Loading
libmodprobe/libmodprobe_ext.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,9 @@ bool Modprobe::Rmmod(const std::string& module_name) { bool Modprobe::ModuleExists(const std::string& module_name) { struct stat fileStat; if (blacklist_enabled && module_blacklist_.count(module_name)) { return false; } auto deps = GetDependencies(module_name); if (deps.empty()) { // missing deps can happen in the case of an alias Loading
libmodprobe/libmodprobe_ext_test.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,9 @@ bool Modprobe::Rmmod(const std::string& module_name) { bool Modprobe::ModuleExists(const std::string& module_name) { auto deps = GetDependencies(module_name); if (blacklist_enabled && module_blacklist_.count(module_name)) { return false; } if (deps.empty()) { // missing deps can happen in the case of an alias return false; Loading
libmodprobe/libmodprobe_test.cpp +21 −11 Original line number Diff line number Diff line Loading @@ -99,6 +99,10 @@ TEST(libmodprobe, Test) { "options test9.ko param_x=1 param_y=2 param_z=3\n" "options test100.ko param_1=1\n"; const std::string modules_blacklist = "blacklist test9.ko\n" "blacklist test3.ko\n"; const std::string modules_load = "test4.ko\n" "test1.ko\n" Loading @@ -109,17 +113,20 @@ TEST(libmodprobe, Test) { "test11.ko\n"; TemporaryDir dir; ASSERT_TRUE(android::base::WriteStringToFile( modules_alias, std::string(dir.path) + "/modules.alias", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_dep, std::string(dir.path) + "/modules.dep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_softdep, std::string(dir.path) + "/modules.softdep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_options, std::string(dir.path) + "/modules.options", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile( modules_load, std::string(dir.path) + "/modules.load", 0600, getuid(), getgid())); auto dir_path = std::string(dir.path); ASSERT_TRUE(android::base::WriteStringToFile(modules_alias, dir_path + "/modules.alias", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_dep, dir_path + "/modules.dep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_softdep, dir_path + "/modules.softdep", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_options, dir_path + "/modules.options", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_load, dir_path + "/modules.load", 0600, getuid(), getgid())); ASSERT_TRUE(android::base::WriteStringToFile(modules_blacklist, dir_path + "/modules.blacklist", 0600, getuid(), getgid())); for (auto i = test_modules.begin(); i != test_modules.end(); ++i) { *i = dir.path + *i; Loading Loading @@ -153,4 +160,7 @@ TEST(libmodprobe, Test) { } EXPECT_TRUE(modules_loaded == expected_after_remove); m.EnableBlacklist(true); EXPECT_FALSE(m.LoadWithAliases("test4", true)); }