]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
module-util: use the blacklist from module_blacklist= in cmdline
authorMike Yuan <me@yhndnzj.com>
Fri, 11 Nov 2022 18:52:38 +0000 (02:52 +0800)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 14 Nov 2022 01:52:01 +0000 (10:52 +0900)
When a module is blacklisted using module_blacklist=
we shouldn't fail with 'Operation not permitted'.
Instead we check for it and skip it if this is the case.

src/shared/module-util.c

index 1526f59b0aa028fc1ea8b6e51d7e610a699dbc56..951701d497ef40320d634c238873bdc22f328563 100644 (file)
@@ -3,11 +3,47 @@
 #include <errno.h>
 
 #include "module-util.h"
+#include "proc-cmdline.h"
+#include "strv.h"
+
+static int denylist_modules(const char *p, char ***denylist) {
+        _cleanup_strv_free_ char **k = NULL;
+
+        assert(p);
+        assert(denylist);
+
+        k = strv_split(p, ",");
+        if (!k)
+                return -ENOMEM;
+
+        if (strv_extend_strv(denylist, k, true) < 0)
+                return -ENOMEM;
+
+        return 0;
+}
+
+static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
+        int r;
+
+        if (proc_cmdline_key_streq(key, "module_blacklist")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                r = denylist_modules(value, data);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
 
 int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose) {
         const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST;
         struct kmod_list *itr;
         _cleanup_(kmod_module_unref_listp) struct kmod_list *modlist = NULL;
+        _cleanup_strv_free_ char **denylist = NULL;
+        bool denylist_parsed = false;
         int r;
 
         /* verbose==true means we should log at non-debug level if we
@@ -50,10 +86,27 @@ int module_load_and_warn(struct kmod_ctx *ctx, const char *module, bool verbose)
                                          "Inserted module '%s'", kmod_module_get_name(mod));
                         else if (err == KMOD_PROBE_APPLY_BLACKLIST)
                                 log_full(verbose ? LOG_INFO : LOG_DEBUG,
-                                         "Module '%s' is deny-listed", kmod_module_get_name(mod));
+                                         "Module '%s' is deny-listed (by kmod)", kmod_module_get_name(mod));
                         else {
                                 assert(err < 0);
 
+                                if (err == -EPERM) {
+                                        if (!denylist_parsed) {
+                                                r = proc_cmdline_parse(parse_proc_cmdline_item, &denylist, 0);
+                                                if (r < 0)
+                                                        log_full_errno(!verbose ? LOG_DEBUG : LOG_WARNING,
+                                                                       r,
+                                                                       "Failed to parse kernel command line, ignoring: %m");
+
+                                                denylist_parsed = true;
+                                        }
+                                        if (strv_contains(denylist, kmod_module_get_name(mod))) {
+                                                log_full(verbose ? LOG_INFO : LOG_DEBUG,
+                                                         "Module '%s' is deny-listed (by kernel)", kmod_module_get_name(mod));
+                                                continue;
+                                        }
+                                }
+
                                 log_full_errno(!verbose ? LOG_DEBUG :
                                                err == -ENODEV ? LOG_NOTICE :
                                                err == -ENOENT ? LOG_WARNING :