aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-08-19 20:17:55 -0400
committerJames Morris <jmorris@namei.org>2019-08-20 00:54:16 -0400
commit20657f66ef52e5005369e4ef539d4cbf01eab10d (patch)
treef5f50d1c2f61821f69e41f1237cdafb446af8e5b
parent794edf30ee6cd088d5f4079b1d4a4cfe5371203e (diff)
lockdown: 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 <gnomes@lxorguk.ukuu.org.uk> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Matthew Garrett <mjg59@google.com> Reviewed-by: Kees Cook <keescook@chromium.org> Cc: Jessica Yu <jeyu@kernel.org> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--include/linux/security.h1
-rw-r--r--kernel/params.c21
-rw-r--r--security/lockdown/lockdown.c1
3 files changed, 18 insertions, 5 deletions
diff --git a/include/linux/security.h b/include/linux/security.h
index b4a85badb03a..1a3404f9c060 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -113,6 +113,7 @@ enum lockdown_reason {
113 LOCKDOWN_ACPI_TABLES, 113 LOCKDOWN_ACPI_TABLES,
114 LOCKDOWN_PCMCIA_CIS, 114 LOCKDOWN_PCMCIA_CIS,
115 LOCKDOWN_TIOCSSERIAL, 115 LOCKDOWN_TIOCSSERIAL,
116 LOCKDOWN_MODULE_PARAMETERS,
116 LOCKDOWN_INTEGRITY_MAX, 117 LOCKDOWN_INTEGRITY_MAX,
117 LOCKDOWN_CONFIDENTIALITY_MAX, 118 LOCKDOWN_CONFIDENTIALITY_MAX,
118}; 119};
diff --git a/kernel/params.c b/kernel/params.c
index cf448785d058..8e56f8b12d8f 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -12,6 +12,7 @@
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/ctype.h> 14#include <linux/ctype.h>
15#include <linux/security.h>
15 16
16#ifdef CONFIG_SYSFS 17#ifdef CONFIG_SYSFS
17/* Protects all built-in parameters, modules use their own param_lock */ 18/* Protects all built-in parameters, modules use their own param_lock */
@@ -96,13 +97,19 @@ bool parameq(const char *a, const char *b)
96 return parameqn(a, b, strlen(a)+1); 97 return parameqn(a, b, strlen(a)+1);
97} 98}
98 99
99static void param_check_unsafe(const struct kernel_param *kp) 100static bool param_check_unsafe(const struct kernel_param *kp)
100{ 101{
102 if (kp->flags & KERNEL_PARAM_FL_HWPARAM &&
103 security_locked_down(LOCKDOWN_MODULE_PARAMETERS))
104 return false;
105
101 if (kp->flags & KERNEL_PARAM_FL_UNSAFE) { 106 if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
102 pr_notice("Setting dangerous option %s - tainting kernel\n", 107 pr_notice("Setting dangerous option %s - tainting kernel\n",
103 kp->name); 108 kp->name);
104 add_taint(TAINT_USER, LOCKDEP_STILL_OK); 109 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
105 } 110 }
111
112 return true;
106} 113}
107 114
108static int parse_one(char *param, 115static int parse_one(char *param,
@@ -132,8 +139,10 @@ static int parse_one(char *param,
132 pr_debug("handling %s with %p\n", param, 139 pr_debug("handling %s with %p\n", param,
133 params[i].ops->set); 140 params[i].ops->set);
134 kernel_param_lock(params[i].mod); 141 kernel_param_lock(params[i].mod);
135 param_check_unsafe(&params[i]); 142 if (param_check_unsafe(&params[i]))
136 err = params[i].ops->set(val, &params[i]); 143 err = params[i].ops->set(val, &params[i]);
144 else
145 err = -EPERM;
137 kernel_param_unlock(params[i].mod); 146 kernel_param_unlock(params[i].mod);
138 return err; 147 return err;
139 } 148 }
@@ -553,8 +562,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
553 return -EPERM; 562 return -EPERM;
554 563
555 kernel_param_lock(mk->mod); 564 kernel_param_lock(mk->mod);
556 param_check_unsafe(attribute->param); 565 if (param_check_unsafe(attribute->param))
557 err = attribute->param->ops->set(buf, attribute->param); 566 err = attribute->param->ops->set(buf, attribute->param);
567 else
568 err = -EPERM;
558 kernel_param_unlock(mk->mod); 569 kernel_param_unlock(mk->mod);
559 if (!err) 570 if (!err)
560 return len; 571 return len;
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index 771c77f9c04a..0fa434294667 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -28,6 +28,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
28 [LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables", 28 [LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables",
29 [LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage", 29 [LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage",
30 [LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO", 30 [LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO",
31 [LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters",
31 [LOCKDOWN_INTEGRITY_MAX] = "integrity", 32 [LOCKDOWN_INTEGRITY_MAX] = "integrity",
32 [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality", 33 [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
33}; 34};