Browse Source

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: Linus Torvalds <torvalds@osdl.org>
Linus Torvalds 18 years ago
parent
commit
808dbbb6bb
1 changed files with 7 additions and 3 deletions
  1. 7 3
      arch/i386/kernel/traps.c

+ 7 - 3
arch/i386/kernel/traps.c

@@ -129,15 +129,19 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
 
 #ifdef	CONFIG_FRAME_POINTER
 	while (valid_stack_ptr(tinfo, (void *)ebp)) {
+		unsigned long new_ebp;
 		addr = *(unsigned long *)(ebp + 4);
 		ops->address(data, addr);
 		/*
 		 * 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;
-		ebp = *(unsigned long *)ebp;
+		ebp = new_ebp;
 	}
 #else
 	while (valid_stack_ptr(tinfo, stack)) {