a0f7ab8a6a
cherry-pick from upstream 4.14
102 lines
3.3 KiB
Diff
102 lines
3.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Andy Lutomirski <luto@kernel.org>
|
|
Date: Thu, 2 Nov 2017 00:59:13 -0700
|
|
Subject: [PATCH] x86/entry/64: Stop initializing TSS.sp0 at boot
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
CVE-2017-5754
|
|
|
|
In my quest to get rid of thread_struct::sp0, I want to clean up or
|
|
remove all of its readers. Two of them are in cpu_init() (32-bit and
|
|
64-bit), and they aren't needed. This is because we never enter
|
|
userspace at all on the threads that CPUs are initialized in.
|
|
|
|
Poison the initial TSS.sp0 and stop initializing it on CPU init.
|
|
|
|
The comment text mostly comes from Dave Hansen. Thanks!
|
|
|
|
Signed-off-by: Andy Lutomirski <luto@kernel.org>
|
|
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/ee4a00540ad28c6cff475fbcc7769a4460acc861.1509609304.git.luto@kernel.org
|
|
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
(cherry picked from commit 20bb83443ea79087b5e5f8dab4e9d80bb9bf7acb)
|
|
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
|
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
|
|
(cherry picked from commit 8c6b12e88bd87433087ea1f1cd5a9a4975e4623c)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
arch/x86/kernel/cpu/common.c | 13 ++++++++++---
|
|
arch/x86/kernel/process.c | 8 +++++++-
|
|
2 files changed, 17 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
|
|
index 6562acbfc4e0..121fe3570d6f 100644
|
|
--- a/arch/x86/kernel/cpu/common.c
|
|
+++ b/arch/x86/kernel/cpu/common.c
|
|
@@ -1570,9 +1570,13 @@ void cpu_init(void)
|
|
BUG_ON(me->mm);
|
|
enter_lazy_tlb(&init_mm, me);
|
|
|
|
- load_sp0(current->thread.sp0);
|
|
+ /*
|
|
+ * Initialize the TSS. Don't bother initializing sp0, as the initial
|
|
+ * task never enters user mode.
|
|
+ */
|
|
set_tss_desc(cpu, t);
|
|
load_TR_desc();
|
|
+
|
|
load_mm_ldt(&init_mm);
|
|
|
|
clear_all_debug_regs();
|
|
@@ -1594,7 +1598,6 @@ void cpu_init(void)
|
|
int cpu = smp_processor_id();
|
|
struct task_struct *curr = current;
|
|
struct tss_struct *t = &per_cpu(cpu_tss, cpu);
|
|
- struct thread_struct *thread = &curr->thread;
|
|
|
|
wait_for_master_cpu(cpu);
|
|
|
|
@@ -1624,9 +1627,13 @@ void cpu_init(void)
|
|
BUG_ON(curr->mm);
|
|
enter_lazy_tlb(&init_mm, curr);
|
|
|
|
- load_sp0(thread->sp0);
|
|
+ /*
|
|
+ * Initialize the TSS. Don't bother initializing sp0, as the initial
|
|
+ * task never enters user mode.
|
|
+ */
|
|
set_tss_desc(cpu, t);
|
|
load_TR_desc();
|
|
+
|
|
load_mm_ldt(&init_mm);
|
|
|
|
t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
|
|
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
|
|
index 3ca198080ea9..ccf3a4f4ef68 100644
|
|
--- a/arch/x86/kernel/process.c
|
|
+++ b/arch/x86/kernel/process.c
|
|
@@ -48,7 +48,13 @@
|
|
*/
|
|
__visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = {
|
|
.x86_tss = {
|
|
- .sp0 = TOP_OF_INIT_STACK,
|
|
+ /*
|
|
+ * .sp0 is only used when entering ring 0 from a lower
|
|
+ * privilege level. Since the init task never runs anything
|
|
+ * but ring 0 code, there is no need for a valid value here.
|
|
+ * Poison it.
|
|
+ */
|
|
+ .sp0 = (1UL << (BITS_PER_LONG-1)) + 1,
|
|
#ifdef CONFIG_X86_32
|
|
.ss0 = __KERNEL_DS,
|
|
.ss1 = __KERNEL_CS,
|
|
--
|
|
2.14.2
|
|
|