[lkml]   [2017]   [Dec]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH 4.14 075/159] x86/unwinder/orc: Dont bail on stack overflow
4.14-stable review patch.  If anyone has any objections, please let me know.


From: Andy Lutomirski <>

commit d3a09104018cf2ad5973dfa8a9c138ef9f5015a3 upstream.

If the stack overflows into a guard page and the ORC unwinder should work
well: by construction, there can't be any meaningful data in the guard page
because no writes to the guard page will have succeeded.

But there is a bug that prevents unwinding from working correctly: if the
starting register state has RSP pointing into a stack guard page, the ORC
unwinder bails out immediately.

Instead of bailing out immediately check whether the next page up is a
valid check page and if so analyze that. As a result the ORC unwinder will
start the unwind.

Tested by intentionally overflowing the task stack. The result is an
accurate call trace instead of a trace consisting purely of '?' entries.

There are a few other bugs that are triggered if the unwinder encounters a
stack overflow after the first step, but they are outside the scope of this

Signed-off-by: Andy Lutomirski <>
Signed-off-by: Thomas Gleixner <>
Cc: Boris Ostrovsky <>
Cc: Borislav Petkov <>
Cc: Borislav Petkov <>
Cc: Brian Gerst <>
Cc: Dave Hansen <>
Cc: Dave Hansen <>
Cc: David Laight <>
Cc: Denys Vlasenko <>
Cc: Eduardo Valentin <>
Cc: Greg KH <>
Cc: H. Peter Anvin <>
Cc: Josh Poimboeuf <>
Cc: Juergen Gross <>
Cc: Linus Torvalds <>
Cc: Peter Zijlstra <>
Cc: Rik van Riel <>
Cc: Will Deacon <>
Signed-off-by: Ingo Molnar <>
Signed-off-by: Greg Kroah-Hartman <>

arch/x86/kernel/unwind_orc.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/unwind_orc.c
+++ b/arch/x86/kernel/unwind_orc.c
@@ -553,8 +553,18 @@ void __unwind_start(struct unwind_state

if (get_stack_info((unsigned long *)state->sp, state->task,
- &state->stack_info, &state->stack_mask))
- return;
+ &state->stack_info, &state->stack_mask)) {
+ /*
+ * We weren't on a valid stack. It's possible that
+ * we overflowed a valid stack into a guard page.
+ * See if the next page up is valid so that we can
+ * generate some kind of backtrace if this happens.
+ */
+ void *next_page = (void *)PAGE_ALIGN((unsigned long)state->sp);
+ if (get_stack_info(next_page, state->task, &state->stack_info,
+ &state->stack_mask))
+ return;
+ }

* The caller can provide the address of the first frame directly

 \ /
  Last update: 2017-12-22 10:42    [W:0.492 / U:0.028 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site