x86: Panic on detection of stack overflow
authorMitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
Tue, 29 Nov 2011 06:08:36 +0000 (15:08 +0900)
committerIngo Molnar <mingo@elte.hu>
Mon, 5 Dec 2011 10:37:47 +0000 (11:37 +0100)
Currently, messages are just output on the detection of stack
overflow, which is not sufficient for systems that need a
high reliability. This is because in general the overflow may
corrupt data, and the additional corruption may occur due to
reading them unless systems stop.

This patch adds the sysctl parameter
kernel.panic_on_stackoverflow and causes a panic when detecting
the overflows of kernel, IRQ and exception stacks except user
stack according to the parameter. It is disabled by default.

Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
Cc: yrl.pp-manager.tt@hitachi.com
Cc: Randy Dunlap <rdunlap@xenotime.net>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Link: http://lkml.kernel.org/r/20111129060836.11076.12323.stgit@ltc219.sdl.hitachi.co.jp
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Documentation/sysctl/kernel.txt
arch/x86/kernel/irq_32.c
arch/x86/kernel/irq_64.c
include/linux/kernel.h
kernel/sysctl.c

index 1f2463671a1a4d59d0981f0b877c2a1246da82db..6d8cd8b2c30d9d6104d05654e22fd85ed1e7032d 100644 (file)
@@ -49,6 +49,7 @@ show up in /proc/sys/kernel:
 - panic
 - panic_on_oops
 - panic_on_unrecovered_nmi
+- panic_on_stackoverflow
 - pid_max
 - powersave-nap               [ PPC only ]
 - printk
@@ -393,6 +394,19 @@ Controls the kernel's behaviour when an oops or BUG is encountered.
 
 ==============================================================
 
+panic_on_stackoverflow:
+
+Controls the kernel's behavior when detecting the overflows of
+kernel, IRQ and exception stacks except a user stack.
+This file shows up if CONFIG_DEBUG_STACKOVERFLOW is enabled.
+
+0: try to continue operation.
+
+1: panic immediately.
+
+==============================================================
+
+
 pid_max:
 
 PID allocation wrap value.  When the kernel's next PID value
index 72090705a656a65c5167392b7c815577e6798356..e16e99ebd7ad3b158d90c6cd9951d0bb3feee659 100644 (file)
@@ -43,6 +43,8 @@ static void print_stack_overflow(void)
 {
        printk(KERN_WARNING "low stack detected by irq handler\n");
        dump_stack();
+       if (sysctl_panic_on_stackoverflow)
+               panic("low stack detected by irq handler - check messages\n");
 }
 
 #else
index 928a7e909619c6966965ef2c0eedfb96b4b98c51..42552b0dce6a95ad51c83faaf8ccfe0b7962bd89 100644 (file)
@@ -26,6 +26,8 @@ EXPORT_PER_CPU_SYMBOL(irq_stat);
 DEFINE_PER_CPU(struct pt_regs *, irq_regs);
 EXPORT_PER_CPU_SYMBOL(irq_regs);
 
+int sysctl_panic_on_stackoverflow;
+
 /*
  * Probabilistic stack overflow check:
  *
@@ -65,6 +67,9 @@ static inline void stack_overflow_check(struct pt_regs *regs)
                current->comm, curbase, regs->sp,
                irq_stack_top, irq_stack_bottom,
                estack_top, estack_bottom);
+
+       if (sysctl_panic_on_stackoverflow)
+               panic("low stack detected by irq handler - check messages\n");
 #endif
 }
 
index e8b1597b5cf2592b85157674b1d1fcbd555d309a..ff83683c0b9d446a43b01411e434ef4e462c28a3 100644 (file)
@@ -341,6 +341,7 @@ extern int panic_timeout;
 extern int panic_on_oops;
 extern int panic_on_unrecovered_nmi;
 extern int panic_on_io_nmi;
+extern int sysctl_panic_on_stackoverflow;
 extern const char *print_tainted(void);
 extern void add_taint(unsigned flag);
 extern int test_taint(unsigned flag);
index ae27196438541384fbfdc1a5c405681169ac8921..f487f257e05e4f1dc8836ded96ca36556b048706 100644 (file)
@@ -803,6 +803,15 @@ static struct ctl_table kern_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+       {
+               .procname       = "panic_on_stackoverflow",
+               .data           = &sysctl_panic_on_stackoverflow,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
+#endif
        {
                .procname       = "bootloader_type",
                .data           = &bootloader_type,