]>
Commit | Line | Data |
---|---|---|
59d5af67 | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
321d628a FG |
2 | From: Andy Lutomirski <luto@kernel.org> |
3 | Date: Mon, 4 Dec 2017 15:07:19 +0100 | |
59d5af67 FG |
4 | Subject: [PATCH] x86/entry: Move SYSENTER_stack to the beginning of struct |
5 | tss_struct | |
321d628a FG |
6 | MIME-Version: 1.0 |
7 | Content-Type: text/plain; charset=UTF-8 | |
8 | Content-Transfer-Encoding: 8bit | |
9 | ||
10 | CVE-2017-5754 | |
11 | ||
12 | SYSENTER_stack should have reliable overflow detection, which | |
13 | means that it needs to be at the bottom of a page, not the top. | |
14 | Move it to the beginning of struct tss_struct and page-align it. | |
15 | ||
16 | Also add an assertion to make sure that the fixed hardware TSS | |
17 | doesn't cross a page boundary. | |
18 | ||
19 | Signed-off-by: Andy Lutomirski <luto@kernel.org> | |
20 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | |
21 | Reviewed-by: Thomas Gleixner <tglx@linutronix.de> | |
22 | Reviewed-by: Borislav Petkov <bp@suse.de> | |
23 | Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> | |
24 | Cc: Borislav Petkov <bp@alien8.de> | |
25 | Cc: Borislav Petkov <bpetkov@suse.de> | |
26 | Cc: Brian Gerst <brgerst@gmail.com> | |
27 | Cc: Dave Hansen <dave.hansen@intel.com> | |
28 | Cc: Dave Hansen <dave.hansen@linux.intel.com> | |
29 | Cc: David Laight <David.Laight@aculab.com> | |
30 | Cc: Denys Vlasenko <dvlasenk@redhat.com> | |
31 | Cc: Eduardo Valentin <eduval@amazon.com> | |
32 | Cc: Greg KH <gregkh@linuxfoundation.org> | |
33 | Cc: H. Peter Anvin <hpa@zytor.com> | |
34 | Cc: Josh Poimboeuf <jpoimboe@redhat.com> | |
35 | Cc: Juergen Gross <jgross@suse.com> | |
36 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
37 | Cc: Peter Zijlstra <peterz@infradead.org> | |
38 | Cc: Rik van Riel <riel@redhat.com> | |
39 | Cc: Will Deacon <will.deacon@arm.com> | |
40 | Cc: aliguori@amazon.com | |
41 | Cc: daniel.gruss@iaik.tugraz.at | |
42 | Cc: hughd@google.com | |
43 | Cc: keescook@google.com | |
44 | Link: https://lkml.kernel.org/r/20171204150605.881827433@linutronix.de | |
45 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
46 | (cherry picked from commit 1a935bc3d4ea61556461a9e92a68ca3556232efd) | |
47 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
48 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
49 | (cherry picked from commit 57d6cfd9e7d015aabbed6d0b50e7d2525b3c86c2) | |
50 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
51 | --- | |
52 | arch/x86/include/asm/processor.h | 21 ++++++++++++--------- | |
53 | arch/x86/kernel/cpu/common.c | 21 +++++++++++++++++++++ | |
54 | 2 files changed, 33 insertions(+), 9 deletions(-) | |
55 | ||
56 | diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h | |
57 | index 78123abdb046..55885465c3a7 100644 | |
58 | --- a/arch/x86/include/asm/processor.h | |
59 | +++ b/arch/x86/include/asm/processor.h | |
60 | @@ -326,7 +326,16 @@ struct x86_hw_tss { | |
61 | ||
62 | struct tss_struct { | |
63 | /* | |
64 | - * The hardware state: | |
65 | + * Space for the temporary SYSENTER stack, used for SYSENTER | |
66 | + * and the entry trampoline as well. | |
67 | + */ | |
68 | + unsigned long SYSENTER_stack_canary; | |
69 | + unsigned long SYSENTER_stack[64]; | |
70 | + | |
71 | + /* | |
72 | + * The fixed hardware portion. This must not cross a page boundary | |
73 | + * at risk of violating the SDM's advice and potentially triggering | |
74 | + * errata. | |
75 | */ | |
76 | struct x86_hw_tss x86_tss; | |
77 | ||
78 | @@ -337,15 +346,9 @@ struct tss_struct { | |
79 | * be within the limit. | |
80 | */ | |
81 | unsigned long io_bitmap[IO_BITMAP_LONGS + 1]; | |
82 | +} __aligned(PAGE_SIZE); | |
83 | ||
84 | - /* | |
85 | - * Space for the temporary SYSENTER stack. | |
86 | - */ | |
87 | - unsigned long SYSENTER_stack_canary; | |
88 | - unsigned long SYSENTER_stack[64]; | |
89 | -} ____cacheline_aligned; | |
90 | - | |
91 | -DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss); | |
92 | +DECLARE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss); | |
93 | ||
94 | /* | |
95 | * sizeof(unsigned long) coming from an extra "long" at the end | |
96 | diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c | |
97 | index e526d82b546c..e61eff11f562 100644 | |
98 | --- a/arch/x86/kernel/cpu/common.c | |
99 | +++ b/arch/x86/kernel/cpu/common.c | |
100 | @@ -487,6 +487,27 @@ static inline void setup_cpu_entry_area(int cpu) | |
101 | #endif | |
102 | ||
103 | __set_fixmap(get_cpu_entry_area_index(cpu, gdt), get_cpu_gdt_paddr(cpu), gdt_prot); | |
104 | + | |
105 | + /* | |
106 | + * The Intel SDM says (Volume 3, 7.2.1): | |
107 | + * | |
108 | + * Avoid placing a page boundary in the part of the TSS that the | |
109 | + * processor reads during a task switch (the first 104 bytes). The | |
110 | + * processor may not correctly perform address translations if a | |
111 | + * boundary occurs in this area. During a task switch, the processor | |
112 | + * reads and writes into the first 104 bytes of each TSS (using | |
113 | + * contiguous physical addresses beginning with the physical address | |
114 | + * of the first byte of the TSS). So, after TSS access begins, if | |
115 | + * part of the 104 bytes is not physically contiguous, the processor | |
116 | + * will access incorrect information without generating a page-fault | |
117 | + * exception. | |
118 | + * | |
119 | + * There are also a lot of errata involving the TSS spanning a page | |
120 | + * boundary. Assert that we're not doing that. | |
121 | + */ | |
122 | + BUILD_BUG_ON((offsetof(struct tss_struct, x86_tss) ^ | |
123 | + offsetofend(struct tss_struct, x86_tss)) & PAGE_MASK); | |
124 | + | |
125 | } | |
126 | ||
127 | /* Load the original GDT from the per-cpu structure */ | |
128 | -- | |
129 | 2.14.2 | |
130 |