Skip to content

Commit 2deb4be

Browse files
amlutoIngo Molnar
authored andcommitted
x86/dumpstack: When OOPSing, rewind the stack before do_exit()
If we call do_exit() with a clean stack, we greatly reduce the risk of recursive oopses due to stack overflow in do_exit, and we allow do_exit to work even if we OOPS from an IST stack. The latter gives us a much better chance of surviving long enough after we detect a stack overflow to write out our logs. Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/32f73ceb372ec61889598da5e5b145889b9f2e19.1468527351.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 46aea38 commit 2deb4be

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

arch/x86/entry/entry_32.S

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,3 +1153,14 @@ ENTRY(async_page_fault)
11531153
jmp error_code
11541154
END(async_page_fault)
11551155
#endif
1156+
1157+
ENTRY(rewind_stack_do_exit)
1158+
/* Prevent any naive code from trying to unwind to our caller. */
1159+
xorl %ebp, %ebp
1160+
1161+
movl PER_CPU_VAR(cpu_current_top_of_stack), %esi
1162+
leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
1163+
1164+
call do_exit
1165+
1: jmp 1b
1166+
END(rewind_stack_do_exit)

arch/x86/entry/entry_64.S

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,3 +1423,14 @@ ENTRY(ignore_sysret)
14231423
mov $-ENOSYS, %eax
14241424
sysret
14251425
END(ignore_sysret)
1426+
1427+
ENTRY(rewind_stack_do_exit)
1428+
/* Prevent any naive code from trying to unwind to our caller. */
1429+
xorl %ebp, %ebp
1430+
1431+
movq PER_CPU_VAR(cpu_current_top_of_stack), %rax
1432+
leaq -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%rax), %rsp
1433+
1434+
call do_exit
1435+
1: jmp 1b
1436+
END(rewind_stack_do_exit)

arch/x86/kernel/dumpstack.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ unsigned long oops_begin(void)
234234
EXPORT_SYMBOL_GPL(oops_begin);
235235
NOKPROBE_SYMBOL(oops_begin);
236236

237+
void __noreturn rewind_stack_do_exit(int signr);
238+
237239
void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
238240
{
239241
if (regs && kexec_should_crash(current))
@@ -255,7 +257,13 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
255257
panic("Fatal exception in interrupt");
256258
if (panic_on_oops)
257259
panic("Fatal exception");
258-
do_exit(signr);
260+
261+
/*
262+
* We're not going to return, but we might be on an IST stack or
263+
* have very little stack space left. Rewind the stack and kill
264+
* the task.
265+
*/
266+
rewind_stack_do_exit(signr);
259267
}
260268
NOKPROBE_SYMBOL(oops_end);
261269

0 commit comments

Comments
 (0)