From 4a36f4a8b16c7fd345f6aec973d926d4e429328a Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 5 Mar 2014 14:40:14 +0100 Subject: [PATCH 3/6] libkmod: Implement filtering of unsupported modules (off by default) References: fate#316971 Patch-mainline: never --- libkmod/libkmod-config.c | 12 ++++++++++-- libkmod/libkmod-internal.h | 1 + libkmod/libkmod-module.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/libkmod/libkmod-config.c b/libkmod/libkmod-config.c index 1b24536..07d6a9e 100644 --- a/libkmod/libkmod-config.c +++ b/libkmod/libkmod-config.c @@ -651,8 +651,16 @@ static int kmod_config_parse(struct kmod_config *config, int fd, ERR(ctx, "%s: command %s is deprecated and not parsed anymore\n", filename, cmd); } else if (streq(cmd, "allow_unsupported_modules")) { - /* dummy option for now */ - ; + char *param = strtok_r(NULL, "\t ", &saveptr); + + if (param == NULL) + goto syntax_error; + if (streq(param, "yes") || streq(param, "1")) + config->block_unsupported = 0; + else if (streq(param, "no") || streq(param, "0")) + config->block_unsupported = 1; + else + goto syntax_error; } else { syntax_error: ERR(ctx, "%s line %u: ignoring bad line starting with '%s'\n", diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h index a65ddd1..2ad74c7 100644 --- a/libkmod/libkmod-internal.h +++ b/libkmod/libkmod-internal.h @@ -119,6 +119,7 @@ struct kmod_config { struct kmod_list *softdeps; struct kmod_list *paths; + int block_unsupported; }; int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **config, const char * const *config_paths) __attribute__((nonnull(1, 2,3))); diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index bffe715..9a3a35a 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -798,6 +798,24 @@ KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod, extern long init_module(const void *mem, unsigned long len, const char *args); +static int check_module_supported(struct kmod_module *mod) +{ + char **strings; + int i, count; + struct kmod_elf *elf; + + elf = kmod_file_get_elf(mod->file); + count = kmod_elf_get_strings(elf, ".modinfo", &strings); + if (count < 0) + return count; + for (i = 0; i < count; i++) + if (streq(strings[i], "supported=yes") || + streq(strings[i], "supported=external")) { + return 1; + } + return 0; +} + /** * kmod_module_insert_module: * @mod: kmod module @@ -823,6 +841,7 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod, struct kmod_elf *elf; const char *path; const char *args = options ? options : ""; + const struct kmod_config *config = kmod_get_config(mod->ctx); if (mod == NULL) return -ENOENT; @@ -841,6 +860,18 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod, } } + if (config->block_unsupported) { + err = check_module_supported(mod); + if (err < 0) + return err; + else if (err == 0) { + ERR(mod->ctx, "module '%s' is unsupported\n", mod->name); + ERR(mod->ctx, "Use --allow-unsupported or set allow_unsupported_modules 1 in\n"); + ERR(mod->ctx, "/etc/modprobe.d/10-unsupported-modules.conf\n"); + return -EPERM; + } + } + if (kmod_file_get_direct(mod->file)) { unsigned int kernel_flags = 0; -- 2.20.1