From: Thomas Gleixner <tglx@linutronix.de>
To: speck@linutronix.de
Subject: [patch V5 07/14] MDS basics 7
Date: Wed, 27 Feb 2019 16:09:46 +0100 [thread overview]
Message-ID: <20190227152037.639184760@linutronix.de> (raw)
In-Reply-To: 20190227150939.605235753@linutronix.de
Subject: [patch V5 07/14] x86/speculation/mds: Clear CPU buffers on exit to user
From: Thomas Gleixner <tglx@linutronix.de>
Add a static key which controls the invocation of the CPU buffer clear
mechanism on exit to user space and add the call into
prepare_exit_to_usermode() and do_nmi() right before actually returning.
Add documentation which kernel to user space transition this covers and
explain why some corner cases are not mitigated.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
V4 --> v5: Use an inline helper instead of open coding it.
Rework the documentation paragraph about exceptions.
V3 --> V4: Add #DS mitigation and document that the #MC corner case
is really not interesting.
V3: Add NMI conditional on user regs and update documentation accordingly.
Use the static branch scheme suggested by Peter. Fix typos ...
---
Documentation/x86/mds.rst | 52 +++++++++++++++++++++++++++++++++++
arch/x86/entry/common.c | 3 ++
arch/x86/include/asm/nospec-branch.h | 13 ++++++++
arch/x86/kernel/cpu/bugs.c | 3 ++
arch/x86/kernel/nmi.c | 4 ++
arch/x86/kernel/traps.c | 7 ++++
6 files changed, 82 insertions(+)
--- a/Documentation/x86/mds.rst
+++ b/Documentation/x86/mds.rst
@@ -97,3 +97,55 @@ According to current knowledge additiona
itself are not required because the necessary gadgets to expose the leaked
data cannot be controlled in a way which allows exploitation from malicious
user space or VM guests.
+
+Mitigation points
+-----------------
+
+1. Return to user space
+^^^^^^^^^^^^^^^^^^^^^^^
+
+ When transitioning from kernel to user space the CPU buffers are flushed
+ on affected CPUs when the mitigation is not disabled on the kernel
+ command line. The migitation is enabled through the static key
+ mds_user_clear.
+
+ The mitigation is invoked in prepare_exit_to_usermode() which covers
+ most of the kernel to user space transitions. There are a few exceptions
+ which are not invoking prepare_exit_to_usermode() on return to user
+ space. These exceptions use the paranoid exit code.
+
+ - Non Maskable Interrupt (NMI):
+
+ Access to sensible data like keys, credentials in the NMI context is
+ mostly theoretical: The CPU can do prefetching or execute a
+ misspeculated code path and thereby fetching data which might end up
+ leaking through a buffer.
+
+ But for mounting other attacks the kernel stack address of the task is
+ already valuable information. So in full mitigation mode, the NMI is
+ mitigated on the return from do_nmi() to provide almost complete
+ coverage.
+
+ - Double fault (#DF):
+
+ A double fault is usually fatal, but the ESPFIX workaround, which can
+ be triggered from user space through modify_ldt(2) is a recoverable
+ double fault. #DF uses the paranoid exit path, so explicit mitigation
+ in the double fault handler is required.
+
+ - Machine Check Exception (#MC):
+
+ Another corner case is a #MC which hits between the CPU buffer clear
+ invocation and the actual return to user. As this still is in kernel
+ space it takes the paranoid exit path which does not clear the CPU
+ buffers. So the #MC handler repopulates the buffers to some
+ extent. Machine checks are not reliably controllable and the window is
+ extremly small so mitigation would just tick a checkbox that this
+ theoretical corner case is covered. To keep the amount of special
+ cases small, ignore #MC.
+
+ - Debug Exception (#DB):
+
+ This takes the paranoid exit path only when the INT1 breakpoint is in
+ kernel space. #DB on a user space address takes the regular exit path,
+ so no extra mitigation required.
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -31,6 +31,7 @@
#include <asm/vdso.h>
#include <linux/uaccess.h>
#include <asm/cpufeature.h>
+#include <asm/nospec-branch.h>
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
@@ -212,6 +213,8 @@ static void exit_to_usermode_loop(struct
#endif
user_enter_irqoff();
+
+ mds_user_clear_cpu_buffers();
}
#define SYSCALL_EXIT_WORK_FLAGS \
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -318,6 +318,8 @@ DECLARE_STATIC_KEY_FALSE(switch_to_cond_
DECLARE_STATIC_KEY_FALSE(switch_mm_cond_ibpb);
DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb);
+DECLARE_STATIC_KEY_FALSE(mds_user_clear);
+
#include <asm/segment.h>
/**
@@ -343,6 +345,17 @@ static inline void mds_clear_cpu_buffers
asm volatile("verw %[ds]" : : [ds] "m" (ds) : "cc");
}
+/**
+ * mds_user_clear_cpu_buffers - Mitigation for MDS vulnerability
+ *
+ * Clear CPU buffers if the corresponding static key is enabled
+ */
+static inline void mds_user_clear_cpu_buffers(void)
+{
+ if (static_branch_likely(&mds_user_clear))
+ mds_clear_cpu_buffers();
+}
+
#endif /* __ASSEMBLY__ */
/*
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -63,6 +63,9 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_cond_i
/* Control unconditional IBPB in switch_mm() */
DEFINE_STATIC_KEY_FALSE(switch_mm_always_ibpb);
+/* Control MDS CPU buffer clear before returning to user space */
+DEFINE_STATIC_KEY_FALSE(mds_user_clear);
+
void __init check_bugs(void)
{
identify_boot_cpu();
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -34,6 +34,7 @@
#include <asm/x86_init.h>
#include <asm/reboot.h>
#include <asm/cache.h>
+#include <asm/nospec-branch.h>
#define CREATE_TRACE_POINTS
#include <trace/events/nmi.h>
@@ -533,6 +534,9 @@ do_nmi(struct pt_regs *regs, long error_
write_cr2(this_cpu_read(nmi_cr2));
if (this_cpu_dec_return(nmi_state))
goto nmi_restart;
+
+ if (user_mode(regs))
+ mds_user_clear_cpu_buffers();
}
NOKPROBE_SYMBOL(do_nmi);
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -366,6 +366,13 @@ dotraplinkage void do_double_fault(struc
regs->ip = (unsigned long)general_protection;
regs->sp = (unsigned long)&gpregs->orig_ax;
+ /*
+ * This situation can be triggered by userspace via
+ * modify_ldt(2) and the return does not take the regular
+ * user space exit, so a CPU buffer clear is required when
+ * MDS mitigation is enabled.
+ */
+ mds_user_clear_cpu_buffers();
return;
}
#endif
next prev parent reply other threads:[~2019-02-27 15:37 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-27 15:09 [patch V5 00/14] MDS basics 0 Thomas Gleixner
2019-02-27 15:09 ` [patch V5 01/14] MDS basics 1 Thomas Gleixner
2019-02-28 13:08 ` Thomas Gleixner
2019-02-27 15:09 ` [patch V5 02/14] MDS basics 2 Thomas Gleixner
2019-02-28 13:55 ` [MODERATED] " Josh Poimboeuf
2019-02-28 14:09 ` Thomas Gleixner
2019-02-28 20:23 ` [MODERATED] " Josh Poimboeuf
2019-03-01 16:04 ` Thomas Gleixner
2019-02-27 15:09 ` [patch V5 03/14] MDS basics 3 Thomas Gleixner
2019-02-27 16:34 ` [MODERATED] " Greg KH
2019-02-27 15:09 ` [patch V5 04/14] MDS basics 4 Thomas Gleixner
2019-02-27 15:09 ` [patch V5 05/14] MDS basics 5 Thomas Gleixner
2019-02-27 15:09 ` [patch V5 06/14] MDS basics 6 Thomas Gleixner
2019-02-27 15:09 ` Thomas Gleixner [this message]
2019-02-27 17:07 ` [MODERATED] Re: [patch V5 07/14] MDS basics 7 Greg KH
2019-02-27 15:09 ` [patch V5 08/14] MDS basics 8 Thomas Gleixner
2019-02-28 8:11 ` [MODERATED] " Greg KH
2019-02-27 15:09 ` [patch V5 09/14] MDS basics 9 Thomas Gleixner
2019-03-01 14:04 ` [MODERATED] " Josh Poimboeuf
2019-03-01 16:03 ` Thomas Gleixner
2019-03-01 16:40 ` [MODERATED] " Josh Poimboeuf
2019-03-01 18:39 ` Josh Poimboeuf
2019-03-01 19:15 ` Thomas Gleixner
2019-03-01 22:38 ` [MODERATED] " Andrea Arcangeli
2019-03-01 22:58 ` Thomas Gleixner
2019-03-02 19:22 ` [MODERATED] Re: [SPAM] " Dave Hansen
2019-03-02 20:39 ` Thomas Gleixner
2019-02-27 15:09 ` [patch V5 10/14] MDS basics 10 Thomas Gleixner
2019-02-27 15:09 ` [patch V5 11/14] MDS basics 11 Thomas Gleixner
2019-02-27 15:09 ` [patch V5 12/14] MDS basics 12 Thomas Gleixner
2019-03-01 22:00 ` [MODERATED] " mark gross
2019-02-27 15:09 ` [patch V5 13/14] MDS basics 13 Thomas Gleixner
2019-03-01 22:04 ` [MODERATED] " mark gross
2019-02-27 15:09 ` [patch V5 14/14] MDS basics 14 Thomas Gleixner
2019-02-27 17:49 ` Thomas Gleixner
2019-02-27 16:26 ` [MODERATED] Re: [patch V5 00/14] MDS basics 0 Linus Torvalds
2019-02-27 17:51 ` Thomas Gleixner
2019-02-27 18:13 ` Thomas Gleixner
2019-02-27 19:50 ` [MODERATED] " Linus Torvalds
2019-02-27 20:05 ` Thomas Gleixner
2019-02-27 21:04 ` Thomas Gleixner
2019-02-28 1:04 ` [MODERATED] " Josh Poimboeuf
2019-02-27 23:06 ` mark gross
2019-02-28 6:58 ` Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190227152037.639184760@linutronix.de \
--to=tglx@linutronix.de \
--cc=speck@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).