commit 808dbbb6bb61173bf52946a28f99089d2efa4c55 tree 4d221ed1e66ea09d244b248bb27998ac2efda119 parent 1ff5683043196b9ad628a5de6bf8eeca52ee8bfd author Linus Torvalds <[EMAIL PROTECTED]> 1163790896 -0800 committer Linus Torvalds <[EMAIL PROTECTED]> 1163790896 -0800
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 <[EMAIL PROTECTED]> arch/i386/kernel/traps.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 00489b7..fe9c5e8 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -129,15 +129,19 @@ static inline unsigned long print_contex #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)) { - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html