]>
Commit | Line | Data |
---|---|---|
321d628a FG |
1 | From bb0be747b5ee45f07f5514a214231c9061261b50 Mon Sep 17 00:00:00 2001 |
2 | From: Andy Lutomirski <luto@kernel.org> | |
3 | Date: Mon, 4 Dec 2017 15:07:08 +0100 | |
e4cdf2a5 | 4 | Subject: [PATCH 138/241] x86/unwinder/orc: Dont bail on stack overflow |
321d628a FG |
5 | MIME-Version: 1.0 |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | CVE-2017-5754 | |
10 | ||
11 | If the stack overflows into a guard page and the ORC unwinder should work | |
12 | well: by construction, there can't be any meaningful data in the guard page | |
13 | because no writes to the guard page will have succeeded. | |
14 | ||
15 | But there is a bug that prevents unwinding from working correctly: if the | |
16 | starting register state has RSP pointing into a stack guard page, the ORC | |
17 | unwinder bails out immediately. | |
18 | ||
19 | Instead of bailing out immediately check whether the next page up is a | |
20 | valid check page and if so analyze that. As a result the ORC unwinder will | |
21 | start the unwind. | |
22 | ||
23 | Tested by intentionally overflowing the task stack. The result is an | |
24 | accurate call trace instead of a trace consisting purely of '?' entries. | |
25 | ||
26 | There are a few other bugs that are triggered if the unwinder encounters a | |
27 | stack overflow after the first step, but they are outside the scope of this | |
28 | fix. | |
29 | ||
30 | Signed-off-by: Andy Lutomirski <luto@kernel.org> | |
31 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | |
32 | Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> | |
33 | Cc: Borislav Petkov <bp@alien8.de> | |
34 | Cc: Borislav Petkov <bpetkov@suse.de> | |
35 | Cc: Brian Gerst <brgerst@gmail.com> | |
36 | Cc: Dave Hansen <dave.hansen@intel.com> | |
37 | Cc: Dave Hansen <dave.hansen@linux.intel.com> | |
38 | Cc: David Laight <David.Laight@aculab.com> | |
39 | Cc: Denys Vlasenko <dvlasenk@redhat.com> | |
40 | Cc: Eduardo Valentin <eduval@amazon.com> | |
41 | Cc: Greg KH <gregkh@linuxfoundation.org> | |
42 | Cc: H. Peter Anvin <hpa@zytor.com> | |
43 | Cc: Josh Poimboeuf <jpoimboe@redhat.com> | |
44 | Cc: Juergen Gross <jgross@suse.com> | |
45 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
46 | Cc: Peter Zijlstra <peterz@infradead.org> | |
47 | Cc: Rik van Riel <riel@redhat.com> | |
48 | Cc: Will Deacon <will.deacon@arm.com> | |
49 | Cc: aliguori@amazon.com | |
50 | Cc: daniel.gruss@iaik.tugraz.at | |
51 | Cc: hughd@google.com | |
52 | Cc: keescook@google.com | |
53 | Link: https://lkml.kernel.org/r/20171204150604.991389777@linutronix.de | |
54 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
55 | (cherry picked from commit d3a09104018cf2ad5973dfa8a9c138ef9f5015a3) | |
56 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
57 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
58 | (cherry picked from commit e5c3115ac69cddd384d6f7abc4a0ef030b247498) | |
59 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
60 | --- | |
61 | arch/x86/kernel/unwind_orc.c | 14 ++++++++++++-- | |
62 | 1 file changed, 12 insertions(+), 2 deletions(-) | |
63 | ||
64 | diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c | |
65 | index 570b70d3f604..cea85bfe93f7 100644 | |
66 | --- a/arch/x86/kernel/unwind_orc.c | |
67 | +++ b/arch/x86/kernel/unwind_orc.c | |
68 | @@ -552,8 +552,18 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, | |
69 | } | |
70 | ||
71 | if (get_stack_info((unsigned long *)state->sp, state->task, | |
72 | - &state->stack_info, &state->stack_mask)) | |
73 | - return; | |
74 | + &state->stack_info, &state->stack_mask)) { | |
75 | + /* | |
76 | + * We weren't on a valid stack. It's possible that | |
77 | + * we overflowed a valid stack into a guard page. | |
78 | + * See if the next page up is valid so that we can | |
79 | + * generate some kind of backtrace if this happens. | |
80 | + */ | |
81 | + void *next_page = (void *)PAGE_ALIGN((unsigned long)state->sp); | |
82 | + if (get_stack_info(next_page, state->task, &state->stack_info, | |
83 | + &state->stack_mask)) | |
84 | + return; | |
85 | + } | |
86 | ||
87 | /* | |
88 | * The caller can provide the address of the first frame directly | |
89 | -- | |
90 | 2.14.2 | |
91 |