Commit 808dbbb6 authored by Linus Torvalds's avatar Linus Torvalds

x86: be more careful when walking back the frame pointer chain

When showing the stack backtrace, make sure that we never accept not
only an unchanging frame pointer, but also a frame pointer that moves
back down the stack frame.  It must always grow up (toward older stack
frames).

I doubt this has triggered, but a subtly corrupt stack with extremely
unlucky contents could cause us to loop forever on a bogus endless frame
pointer chain.

This review was triggered by much worse problems happening in some of
the other stack unwinding code.
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1ff56830
...@@ -129,15 +129,19 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, ...@@ -129,15 +129,19 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
#ifdef CONFIG_FRAME_POINTER #ifdef CONFIG_FRAME_POINTER
while (valid_stack_ptr(tinfo, (void *)ebp)) { while (valid_stack_ptr(tinfo, (void *)ebp)) {
unsigned long new_ebp;
addr = *(unsigned long *)(ebp + 4); addr = *(unsigned long *)(ebp + 4);
ops->address(data, addr); ops->address(data, addr);
/* /*
* break out of recursive entries (such as * break out of recursive entries (such as
* end_of_stack_stop_unwind_function): * end_of_stack_stop_unwind_function). Also,
* we can never allow a frame pointer to
* move downwards!
*/ */
if (ebp == *(unsigned long *)ebp) new_ebp = *(unsigned long *)ebp;
if (new_ebp <= ebp)
break; break;
ebp = *(unsigned long *)ebp; ebp = new_ebp;
} }
#else #else
while (valid_stack_ptr(tinfo, stack)) { while (valid_stack_ptr(tinfo, stack)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment