2018-01-06 17:13:39 +03:00
|
|
|
From 63463bcffe420067411ad3d4d01b79c872fffc3a Mon Sep 17 00:00:00 2001
|
|
|
|
From: Andy Lutomirski <luto@kernel.org>
|
|
|
|
Date: Tue, 11 Jul 2017 10:33:39 -0500
|
2018-01-06 17:14:30 +03:00
|
|
|
Subject: [PATCH 019/232] x86/entry/64: Initialize the top of the IRQ stack
|
2018-01-06 17:13:39 +03:00
|
|
|
before switching stacks
|
|
|
|
MIME-Version: 1.0
|
|
|
|
Content-Type: text/plain; charset=UTF-8
|
|
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
|
|
|
|
CVE-2017-5754
|
|
|
|
|
|
|
|
The OOPS unwinder wants the word at the top of the IRQ stack to
|
|
|
|
point back to the previous stack at all times when the IRQ stack
|
|
|
|
is in use. There's currently a one-instruction window in ENTER_IRQ_STACK
|
|
|
|
during which this isn't the case. Fix it by writing the old RSP to the
|
|
|
|
top of the IRQ stack before jumping.
|
|
|
|
|
|
|
|
This currently writes the pointer to the stack twice, which is a bit
|
|
|
|
ugly. We could get rid of this by replacing irq_stack_ptr with
|
|
|
|
irq_stack_ptr_minus_eight (better name welcome). OTOH, there may be
|
|
|
|
all kinds of odd microarchitectural considerations in play that
|
|
|
|
affect performance by a few cycles here.
|
|
|
|
|
|
|
|
Reported-by: Mike Galbraith <efault@gmx.de>
|
|
|
|
Reported-by: Josh Poimboeuf <jpoimboe@redhat.com>
|
|
|
|
Signed-off-by: Andy Lutomirski <luto@kernel.org>
|
|
|
|
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
|
|
|
|
Cc: Borislav Petkov <bp@alien8.de>
|
|
|
|
Cc: Brian Gerst <brgerst@gmail.com>
|
|
|
|
Cc: Denys Vlasenko <dvlasenk@redhat.com>
|
|
|
|
Cc: H. Peter Anvin <hpa@zytor.com>
|
|
|
|
Cc: Jiri Slaby <jslaby@suse.cz>
|
|
|
|
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
|
|
|
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
|
|
Cc: Thomas Gleixner <tglx@linutronix.de>
|
|
|
|
Cc: live-patching@vger.kernel.org
|
|
|
|
Link: http://lkml.kernel.org/r/aae7e79e49914808440ad5310ace138ced2179ca.1499786555.git.jpoimboe@redhat.com
|
|
|
|
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
|
|
(cherry picked from commit 2995590964da93e1fd9a91550f9c9d9fab28f160)
|
|
|
|
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
|
|
|
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
|
|
|
|
(cherry picked from commit a753ff654dfd07a7f8d6f39a27126589eac7e55f)
|
|
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
|
|
---
|
|
|
|
arch/x86/entry/entry_64.S | 24 +++++++++++++++++++++++-
|
|
|
|
1 file changed, 23 insertions(+), 1 deletion(-)
|
|
|
|
|
|
|
|
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
|
|
|
|
index 07b4056af8a8..184b70712545 100644
|
|
|
|
--- a/arch/x86/entry/entry_64.S
|
|
|
|
+++ b/arch/x86/entry/entry_64.S
|
|
|
|
@@ -469,6 +469,7 @@ END(irq_entries_start)
|
|
|
|
DEBUG_ENTRY_ASSERT_IRQS_OFF
|
|
|
|
movq %rsp, \old_rsp
|
|
|
|
incl PER_CPU_VAR(irq_count)
|
|
|
|
+ jnz .Lirq_stack_push_old_rsp_\@
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Right now, if we just incremented irq_count to zero, we've
|
|
|
|
@@ -478,9 +479,30 @@ END(irq_entries_start)
|
|
|
|
* it must be *extremely* careful to limit its stack usage. This
|
|
|
|
* could include kprobes and a hypothetical future IST-less #DB
|
|
|
|
* handler.
|
|
|
|
+ *
|
|
|
|
+ * The OOPS unwinder relies on the word at the top of the IRQ
|
|
|
|
+ * stack linking back to the previous RSP for the entire time we're
|
|
|
|
+ * on the IRQ stack. For this to work reliably, we need to write
|
|
|
|
+ * it before we actually move ourselves to the IRQ stack.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ movq \old_rsp, PER_CPU_VAR(irq_stack_union + IRQ_STACK_SIZE - 8)
|
|
|
|
+ movq PER_CPU_VAR(irq_stack_ptr), %rsp
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DEBUG_ENTRY
|
|
|
|
+ /*
|
|
|
|
+ * If the first movq above becomes wrong due to IRQ stack layout
|
|
|
|
+ * changes, the only way we'll notice is if we try to unwind right
|
|
|
|
+ * here. Assert that we set up the stack right to catch this type
|
|
|
|
+ * of bug quickly.
|
|
|
|
*/
|
|
|
|
+ cmpq -8(%rsp), \old_rsp
|
|
|
|
+ je .Lirq_stack_okay\@
|
|
|
|
+ ud2
|
|
|
|
+ .Lirq_stack_okay\@:
|
|
|
|
+#endif
|
|
|
|
|
|
|
|
- cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
|
|
|
|
+.Lirq_stack_push_old_rsp_\@:
|
|
|
|
pushq \old_rsp
|
|
|
|
.endm
|
|
|
|
|
|
|
|
--
|
|
|
|
2.14.2
|
|
|
|
|