]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0143-x86-dumpstack-Add-get_stack_info-support-for-the-SYS.patch
add objtool build fix
[pve-kernel.git] / patches / kernel / 0143-x86-dumpstack-Add-get_stack_info-support-for-the-SYS.patch
1 From 45b01b77bd3529e761bca6de0f0ed79549377479 Mon Sep 17 00:00:00 2001
2 From: Andy Lutomirski <luto@kernel.org>
3 Date: Mon, 4 Dec 2017 15:07:13 +0100
4 Subject: [PATCH 143/233] x86/dumpstack: Add get_stack_info() support for the
5 SYSENTER stack
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 get_stack_info() doesn't currently know about the SYSENTER stack, so
13 unwinding will fail if we entered the kernel on the SYSENTER stack
14 and haven't fully switched off. Teach get_stack_info() about the
15 SYSENTER stack.
16
17 With future patches applied that run part of the entry code on the
18 SYSENTER stack and introduce an intentional BUG(), I would get:
19
20 PANIC: double fault, error_code: 0x0
21 ...
22 RIP: 0010:do_error_trap+0x33/0x1c0
23 ...
24 Call Trace:
25 Code: ...
26
27 With this patch, I get:
28
29 PANIC: double fault, error_code: 0x0
30 ...
31 Call Trace:
32 <SYSENTER>
33 ? async_page_fault+0x36/0x60
34 ? invalid_op+0x22/0x40
35 ? async_page_fault+0x36/0x60
36 ? sync_regs+0x3c/0x40
37 ? sync_regs+0x2e/0x40
38 ? error_entry+0x6c/0xd0
39 ? async_page_fault+0x36/0x60
40 </SYSENTER>
41 Code: ...
42
43 which is a lot more informative.
44
45 Signed-off-by: Andy Lutomirski <luto@kernel.org>
46 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
47 Reviewed-by: Borislav Petkov <bp@suse.de>
48 Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
49 Cc: Borislav Petkov <bp@alien8.de>
50 Cc: Borislav Petkov <bpetkov@suse.de>
51 Cc: Brian Gerst <brgerst@gmail.com>
52 Cc: Dave Hansen <dave.hansen@intel.com>
53 Cc: Dave Hansen <dave.hansen@linux.intel.com>
54 Cc: David Laight <David.Laight@aculab.com>
55 Cc: Denys Vlasenko <dvlasenk@redhat.com>
56 Cc: Eduardo Valentin <eduval@amazon.com>
57 Cc: Greg KH <gregkh@linuxfoundation.org>
58 Cc: H. Peter Anvin <hpa@zytor.com>
59 Cc: Josh Poimboeuf <jpoimboe@redhat.com>
60 Cc: Juergen Gross <jgross@suse.com>
61 Cc: Linus Torvalds <torvalds@linux-foundation.org>
62 Cc: Peter Zijlstra <peterz@infradead.org>
63 Cc: Rik van Riel <riel@redhat.com>
64 Cc: Will Deacon <will.deacon@arm.com>
65 Cc: aliguori@amazon.com
66 Cc: daniel.gruss@iaik.tugraz.at
67 Cc: hughd@google.com
68 Cc: keescook@google.com
69 Link: https://lkml.kernel.org/r/20171204150605.392711508@linutronix.de
70 Signed-off-by: Ingo Molnar <mingo@kernel.org>
71 (cherry picked from commit 33a2f1a6c4d7c0a02d1c006fb0379cc5ca3b96bb)
72 Signed-off-by: Andy Whitcroft <apw@canonical.com>
73 Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
74 (cherry picked from commit 72e90cc5463cf882c5f9508817029d85b317f2b5)
75 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
76 ---
77 arch/x86/include/asm/stacktrace.h | 3 +++
78 arch/x86/kernel/dumpstack.c | 19 +++++++++++++++++++
79 arch/x86/kernel/dumpstack_32.c | 6 ++++++
80 arch/x86/kernel/dumpstack_64.c | 6 ++++++
81 4 files changed, 34 insertions(+)
82
83 diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
84 index 2e41c50ddf47..95f999576131 100644
85 --- a/arch/x86/include/asm/stacktrace.h
86 +++ b/arch/x86/include/asm/stacktrace.h
87 @@ -15,6 +15,7 @@ enum stack_type {
88 STACK_TYPE_TASK,
89 STACK_TYPE_IRQ,
90 STACK_TYPE_SOFTIRQ,
91 + STACK_TYPE_SYSENTER,
92 STACK_TYPE_EXCEPTION,
93 STACK_TYPE_EXCEPTION_LAST = STACK_TYPE_EXCEPTION + N_EXCEPTION_STACKS-1,
94 };
95 @@ -27,6 +28,8 @@ struct stack_info {
96 bool in_task_stack(unsigned long *stack, struct task_struct *task,
97 struct stack_info *info);
98
99 +bool in_sysenter_stack(unsigned long *stack, struct stack_info *info);
100 +
101 int get_stack_info(unsigned long *stack, struct task_struct *task,
102 struct stack_info *info, unsigned long *visit_mask);
103
104 diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
105 index 695cdce5dfc8..c211cbdff709 100644
106 --- a/arch/x86/kernel/dumpstack.c
107 +++ b/arch/x86/kernel/dumpstack.c
108 @@ -43,6 +43,25 @@ bool in_task_stack(unsigned long *stack, struct task_struct *task,
109 return true;
110 }
111
112 +bool in_sysenter_stack(unsigned long *stack, struct stack_info *info)
113 +{
114 + struct tss_struct *tss = this_cpu_ptr(&cpu_tss);
115 +
116 + /* Treat the canary as part of the stack for unwinding purposes. */
117 + void *begin = &tss->SYSENTER_stack_canary;
118 + void *end = (void *)&tss->SYSENTER_stack + sizeof(tss->SYSENTER_stack);
119 +
120 + if ((void *)stack < begin || (void *)stack >= end)
121 + return false;
122 +
123 + info->type = STACK_TYPE_SYSENTER;
124 + info->begin = begin;
125 + info->end = end;
126 + info->next_sp = NULL;
127 +
128 + return true;
129 +}
130 +
131 static void printk_stack_address(unsigned long address, int reliable,
132 char *log_lvl)
133 {
134 diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
135 index e5f0b40e66d2..3160bf2d100e 100644
136 --- a/arch/x86/kernel/dumpstack_32.c
137 +++ b/arch/x86/kernel/dumpstack_32.c
138 @@ -25,6 +25,9 @@ const char *stack_type_name(enum stack_type type)
139 if (type == STACK_TYPE_SOFTIRQ)
140 return "SOFTIRQ";
141
142 + if (type == STACK_TYPE_SYSENTER)
143 + return "SYSENTER";
144 +
145 return NULL;
146 }
147
148 @@ -92,6 +95,9 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
149 if (task != current)
150 goto unknown;
151
152 + if (in_sysenter_stack(stack, info))
153 + goto recursion_check;
154 +
155 if (in_hardirq_stack(stack, info))
156 goto recursion_check;
157
158 diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
159 index 3e1471d57487..f5107b659f86 100644
160 --- a/arch/x86/kernel/dumpstack_64.c
161 +++ b/arch/x86/kernel/dumpstack_64.c
162 @@ -36,6 +36,9 @@ const char *stack_type_name(enum stack_type type)
163 if (type == STACK_TYPE_IRQ)
164 return "IRQ";
165
166 + if (type == STACK_TYPE_SYSENTER)
167 + return "SYSENTER";
168 +
169 if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST)
170 return exception_stack_names[type - STACK_TYPE_EXCEPTION];
171
172 @@ -114,6 +117,9 @@ int get_stack_info(unsigned long *stack, struct task_struct *task,
173 if (in_irq_stack(stack, info))
174 goto recursion_check;
175
176 + if (in_sysenter_stack(stack, info))
177 + goto recursion_check;
178 +
179 goto unknown;
180
181 recursion_check:
182 --
183 2.14.2
184