From: David Howells Date: Wed, 5 Apr 2017 12:50:07 +0000 (+0100) Subject: Lock down module params that specify hardware parameters (eg. ioport) X-Git-Tag: archive/raspbian/4.15.4-1+rpi1~37 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a65c6de71abed7c86ca34f9d3231e78a0dbe3fe2;p=linux.git Lock down module params that specify hardware parameters (eg. ioport) Provided an annotation for module parameters that specify hardware parameters (such as io ports, iomem addresses, irqs, dma channels, fixed dma buffers and other types). Suggested-by: Alan Cox Signed-off-by: David Howells Gbp-Pq: Topic features/all/lockdown Gbp-Pq: Name 0061-Lock-down-module-params-that-specify-hardware-parame.patch --- diff --git a/kernel/params.c b/kernel/params.c index cc9108c2a1f..3e96549bd18 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -108,13 +108,20 @@ bool parameq(const char *a, const char *b) return parameqn(a, b, strlen(a)+1); } -static void param_check_unsafe(const struct kernel_param *kp) +static bool param_check_unsafe(const struct kernel_param *kp, + const char *doing) { if (kp->flags & KERNEL_PARAM_FL_UNSAFE) { pr_warn("Setting dangerous option %s - tainting kernel\n", kp->name); add_taint(TAINT_USER, LOCKDEP_STILL_OK); } + + if (kp->flags & KERNEL_PARAM_FL_HWPARAM && kernel_is_locked_down()) { + pr_err("Command line-specified device addresses, irqs and dma channels are not permitted when the kernel is locked down (%s.%s)\n", doing, kp->name); + return false; + } + return true; } static int parse_one(char *param, @@ -144,8 +151,10 @@ static int parse_one(char *param, pr_debug("handling %s with %p\n", param, params[i].ops->set); kernel_param_lock(params[i].mod); - param_check_unsafe(¶ms[i]); - err = params[i].ops->set(val, ¶ms[i]); + if (param_check_unsafe(¶ms[i], doing)) + err = params[i].ops->set(val, ¶ms[i]); + else + err = -EPERM; kernel_param_unlock(params[i].mod); return err; } @@ -553,6 +562,12 @@ static ssize_t param_attr_show(struct module_attribute *mattr, return count; } +#ifdef CONFIG_MODULES +#define mod_name(mod) (mod)->name +#else +#define mod_name(mod) "unknown" +#endif + /* sysfs always hands a nul-terminated string in buf. We rely on that. */ static ssize_t param_attr_store(struct module_attribute *mattr, struct module_kobject *mk, @@ -565,8 +580,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr, return -EPERM; kernel_param_lock(mk->mod); - param_check_unsafe(attribute->param); - err = attribute->param->ops->set(buf, attribute->param); + if (param_check_unsafe(attribute->param, mod_name(mk->mod))) + err = attribute->param->ops->set(buf, attribute->param); + else + err = -EPERM; kernel_param_unlock(mk->mod); if (!err) return len;