From: David Howells Date: Wed, 8 Nov 2017 15:11:36 +0000 Subject: [22/29] Lock down module params that specify hardware parameters (eg. ioport) Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=d20a28efda02a7ce70b943c15246ea2f07e780f4 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 --- kernel/params.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) Index: linux/kernel/params.c =================================================================== --- linux.orig/kernel/params.c +++ linux/kernel/params.c @@ -108,13 +108,19 @@ bool parameq(const char *a, const char * 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_notice("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("Command line-specified device addresses, irqs and dma channels")) + return false; + return true; } static int parse_one(char *param, @@ -144,8 +150,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 +561,12 @@ static ssize_t param_attr_show(struct mo 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 +579,10 @@ static ssize_t param_attr_store(struct m 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;