a0f7ab8a6a
cherry-pick from upstream 4.14
118 lines
3.7 KiB
Diff
118 lines
3.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Andy Lutomirski <luto@kernel.org>
|
|
Date: Thu, 2 Nov 2017 00:59:17 -0700
|
|
Subject: [PATCH] x86/traps: Use a new on_thread_stack() helper to clean up an
|
|
assertion
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
CVE-2017-5754
|
|
|
|
Let's keep the stack-related logic together rather than open-coding
|
|
a comparison in an assertion in the traps code.
|
|
|
|
Signed-off-by: Andy Lutomirski <luto@kernel.org>
|
|
Reviewed-by: Borislav Petkov <bp@suse.de>
|
|
Cc: Borislav Petkov <bpetkov@suse.de>
|
|
Cc: Brian Gerst <brgerst@gmail.com>
|
|
Cc: Dave Hansen <dave.hansen@intel.com>
|
|
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
Cc: Thomas Gleixner <tglx@linutronix.de>
|
|
Link: http://lkml.kernel.org/r/856b15bee1f55017b8f79d3758b0d51c48a08cf8.1509609304.git.luto@kernel.org
|
|
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
(backported from commit 3383642c2f9d4f5b4fa37436db4a109a1a10018c)
|
|
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
|
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
|
|
(cherry picked from commit 243de7bd3434c50fb07dd0fc84c462236cfcba3e)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
arch/x86/include/asm/processor.h | 8 ++++++++
|
|
arch/x86/include/asm/thread_info.h | 22 +++++++++++-----------
|
|
arch/x86/kernel/traps.c | 3 +--
|
|
3 files changed, 20 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
|
|
index cec9a329c0f1..79739e5f939a 100644
|
|
--- a/arch/x86/include/asm/processor.h
|
|
+++ b/arch/x86/include/asm/processor.h
|
|
@@ -159,6 +159,8 @@ enum cpuid_regs_idx {
|
|
extern struct cpuinfo_x86 boot_cpu_data;
|
|
extern struct cpuinfo_x86 new_cpu_data;
|
|
|
|
+#include <linux/thread_info.h>
|
|
+
|
|
extern struct tss_struct doublefault_tss;
|
|
extern __u32 cpu_caps_cleared[NCAPINTS];
|
|
extern __u32 cpu_caps_set[NCAPINTS];
|
|
@@ -534,6 +536,12 @@ static inline unsigned long current_top_of_stack(void)
|
|
#endif
|
|
}
|
|
|
|
+static inline bool on_thread_stack(void)
|
|
+{
|
|
+ return (unsigned long)(current_top_of_stack() -
|
|
+ current_stack_pointer()) < THREAD_SIZE;
|
|
+}
|
|
+
|
|
#ifdef CONFIG_PARAVIRT
|
|
#include <asm/paravirt.h>
|
|
#else
|
|
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
|
|
index e00e1bd6e7b3..ec8ef3bbb7dc 100644
|
|
--- a/arch/x86/include/asm/thread_info.h
|
|
+++ b/arch/x86/include/asm/thread_info.h
|
|
@@ -48,6 +48,17 @@
|
|
* - this struct shares the supervisor stack pages
|
|
*/
|
|
#ifndef __ASSEMBLY__
|
|
+static inline unsigned long current_stack_pointer(void)
|
|
+{
|
|
+ unsigned long sp;
|
|
+#ifdef CONFIG_X86_64
|
|
+ asm("mov %%rsp,%0" : "=g" (sp));
|
|
+#else
|
|
+ asm("mov %%esp,%0" : "=g" (sp));
|
|
+#endif
|
|
+ return sp;
|
|
+}
|
|
+
|
|
struct task_struct;
|
|
#include <asm/cpufeature.h>
|
|
#include <linux/atomic.h>
|
|
@@ -155,17 +166,6 @@ struct thread_info {
|
|
*/
|
|
#ifndef __ASSEMBLY__
|
|
|
|
-static inline unsigned long current_stack_pointer(void)
|
|
-{
|
|
- unsigned long sp;
|
|
-#ifdef CONFIG_X86_64
|
|
- asm("mov %%rsp,%0" : "=g" (sp));
|
|
-#else
|
|
- asm("mov %%esp,%0" : "=g" (sp));
|
|
-#endif
|
|
- return sp;
|
|
-}
|
|
-
|
|
/*
|
|
* Walks up the stack frames to make sure that the specified object is
|
|
* entirely contained by a single stack frame.
|
|
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
|
|
index b2157d4a5338..3a46cab2696e 100644
|
|
--- a/arch/x86/kernel/traps.c
|
|
+++ b/arch/x86/kernel/traps.c
|
|
@@ -153,8 +153,7 @@ void ist_begin_non_atomic(struct pt_regs *regs)
|
|
* will catch asm bugs and any attempt to use ist_preempt_enable
|
|
* from double_fault.
|
|
*/
|
|
- BUG_ON((unsigned long)(current_top_of_stack() -
|
|
- current_stack_pointer()) >= THREAD_SIZE);
|
|
+ BUG_ON(!on_thread_stack());
|
|
|
|
preempt_enable_no_resched();
|
|
}
|
|
--
|
|
2.14.2
|
|
|