From: Greg Kroah-Hartman Date: Thu, 10 Dec 2009 19:05:40 +0000 (-0800) Subject: start .27 queue X-Git-Tag: v2.6.31.8~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b22d7a3fc2297f81d4b4be50583ad47577868569;p=thirdparty%2Fkernel%2Fstable-queue.git start .27 queue --- diff --git a/queue-2.6.27/series b/queue-2.6.27/series new file mode 100644 index 00000000000..0b37ab67df4 --- /dev/null +++ b/queue-2.6.27/series @@ -0,0 +1 @@ +signal-fix-alternate-signal-stack-check.patch diff --git a/queue-2.6.27/signal-fix-alternate-signal-stack-check.patch b/queue-2.6.27/signal-fix-alternate-signal-stack-check.patch new file mode 100644 index 00000000000..03764fd2103 --- /dev/null +++ b/queue-2.6.27/signal-fix-alternate-signal-stack-check.patch @@ -0,0 +1,87 @@ +From 2a855dd01bc1539111adb7233f587c5c468732ac Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Sun, 25 Oct 2009 15:37:58 +0100 +Subject: signal: Fix alternate signal stack check + +From: Sebastian Andrzej Siewior + +commit 2a855dd01bc1539111adb7233f587c5c468732ac upstream. + +All architectures in the kernel increment/decrement the stack pointer +before storing values on the stack. + +On architectures which have the stack grow down sas_ss_sp == sp is not +on the alternate signal stack while sas_ss_sp + sas_ss_size == sp is +on the alternate signal stack. + +On architectures which have the stack grow up sas_ss_sp == sp is on +the alternate signal stack while sas_ss_sp + sas_ss_size == sp is not +on the alternate signal stack. + +The current implementation fails for architectures which have the +stack grow down on the corner case where sas_ss_sp == sp.This was +reported as Debian bug #544905 on AMD64. +Simplified test case: http://download.breakpoint.cc/tc-sig-stack.c + +The test case creates the following stack scenario: + 0xn0300 stack top + 0xn0200 alt stack pointer top (when switching to alt stack) + 0xn01ff alt stack end + 0xn0100 alt stack start == stack pointer + +If the signal is sent the stack pointer is pointing to the base +address of the alt stack and the kernel erroneously decides that it +has already switched to the alternate stack because of the current +check for "sp - sas_ss_sp < sas_ss_size" + +On parisc (stack grows up) the scenario would be: + 0xn0200 stack pointer + 0xn01ff alt stack end + 0xn0100 alt stack start = alt stack pointer base + (when switching to alt stack) + 0xn0000 stack base + +This is handled correctly by the current implementation. + +[ tglx: Modified for archs which have the stack grow up (parisc) which + would fail with the correct implementation for stack grows + down. Added a check for sp >= current->sas_ss_sp which is + strictly not necessary but makes the code symetric for both + variants ] + +Signed-off-by: Sebastian Andrzej Siewior +Cc: Oleg Nesterov +Cc: Roland McGrath +Cc: Kyle McMartin +LKML-Reference: <20091025143758.GA6653@Chamillionaire.breakpoint.cc> +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/sched.h | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1803,11 +1803,18 @@ static inline int is_si_special(const st + return info <= SEND_SIG_FORCED; + } + +-/* True if we are on the alternate signal stack. */ +- ++/* ++ * True if we are on the alternate signal stack. ++ */ + static inline int on_sig_stack(unsigned long sp) + { +- return (sp - current->sas_ss_sp < current->sas_ss_size); ++#ifdef CONFIG_STACK_GROWSUP ++ return sp >= current->sas_ss_sp && ++ sp - current->sas_ss_sp < current->sas_ss_size; ++#else ++ return sp > current->sas_ss_sp && ++ sp - current->sas_ss_sp <= current->sas_ss_size; ++#endif + } + + static inline int sas_ss_flags(unsigned long sp)