libmodprobe: add support for a blacklist
If the blacklist is enabled, blacklisted modules are treated as though they are not present. Change-Id: Ie8712f24298e78f92d5028b1ca3a8a3e07a9190a
This commit is contained in:
parent
13700a69d3
commit
e31f840a0a
5 changed files with 63 additions and 10 deletions
|
@ -16,6 +16,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
@ -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);
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
@ -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()));
|
||||
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, 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()));
|
||||
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;
|
||||
|
@ -153,4 +160,7 @@ TEST(libmodprobe, Test) {
|
|||
}
|
||||
|
||||
EXPECT_TRUE(modules_loaded == expected_after_remove);
|
||||
|
||||
m.EnableBlacklist(true);
|
||||
EXPECT_FALSE(m.LoadWithAliases("test4", true));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue