diff options
author | Matthew Garrett <mjg59@srcf.ucam.org> | 2019-08-20 02:17:49 +0200 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2019-08-20 06:54:16 +0200 |
commit | 95f5e95f41dff31b2a4566c5a8975c08a49ae4e3 (patch) | |
tree | 1d11399a1d98cf0cf2b338f45567781559034e12 | |
parent | x86: Lock down IO port access when the kernel is locked down (diff) | |
download | linux-95f5e95f41dff31b2a4566c5a8975c08a49ae4e3.tar.xz linux-95f5e95f41dff31b2a4566c5a8975c08a49ae4e3.zip |
x86/msr: Restrict MSR access when the kernel is locked down
Writing to MSRs should not be allowed if the kernel is locked down, since
it could lead to execution of arbitrary code in kernel mode. Based on a
patch by Kees Cook.
Signed-off-by: Matthew Garrett <mjg59@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
cc: x86@kernel.org
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | arch/x86/kernel/msr.c | 8 | ||||
-rw-r--r-- | include/linux/security.h | 1 | ||||
-rw-r--r-- | security/lockdown/lockdown.c | 1 |
3 files changed, 10 insertions, 0 deletions
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 3db2252b958d..1547be359d7f 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -34,6 +34,7 @@ #include <linux/notifier.h> #include <linux/uaccess.h> #include <linux/gfp.h> +#include <linux/security.h> #include <asm/cpufeature.h> #include <asm/msr.h> @@ -79,6 +80,10 @@ static ssize_t msr_write(struct file *file, const char __user *buf, int err = 0; ssize_t bytes = 0; + err = security_locked_down(LOCKDOWN_MSR); + if (err) + return err; + if (count % 8) return -EINVAL; /* Invalid chunk size */ @@ -130,6 +135,9 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg) err = -EFAULT; break; } + err = security_locked_down(LOCKDOWN_MSR); + if (err) + break; err = wrmsr_safe_regs_on_cpu(cpu, regs); if (err) break; diff --git a/include/linux/security.h b/include/linux/security.h index cd93fa5d3c6d..010637a79eac 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -109,6 +109,7 @@ enum lockdown_reason { LOCKDOWN_HIBERNATION, LOCKDOWN_PCI_ACCESS, LOCKDOWN_IOPORT, + LOCKDOWN_MSR, LOCKDOWN_INTEGRITY_MAX, LOCKDOWN_CONFIDENTIALITY_MAX, }; diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index 8b7d65dbb086..b1c1c72440d5 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -24,6 +24,7 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = { [LOCKDOWN_HIBERNATION] = "hibernation", [LOCKDOWN_PCI_ACCESS] = "direct PCI access", [LOCKDOWN_IOPORT] = "raw io port access", + [LOCKDOWN_MSR] = "raw MSR access", [LOCKDOWN_INTEGRITY_MAX] = "integrity", [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality", }; |