]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.1/signal-fix-alternate-signal-stack-check.patch
drop queue-4.14/mips-make-sure-dt-memory-regions-are-valid.patch
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.1 / signal-fix-alternate-signal-stack-check.patch
CommitLineData
e46fb18b
GKH
1From 2a855dd01bc1539111adb7233f587c5c468732ac Mon Sep 17 00:00:00 2001
2From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
3Date: Sun, 25 Oct 2009 15:37:58 +0100
4Subject: signal: Fix alternate signal stack check
5
6From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
7
8commit 2a855dd01bc1539111adb7233f587c5c468732ac upstream.
9
10All architectures in the kernel increment/decrement the stack pointer
11before storing values on the stack.
12
13On architectures which have the stack grow down sas_ss_sp == sp is not
14on the alternate signal stack while sas_ss_sp + sas_ss_size == sp is
15on the alternate signal stack.
16
17On architectures which have the stack grow up sas_ss_sp == sp is on
18the alternate signal stack while sas_ss_sp + sas_ss_size == sp is not
19on the alternate signal stack.
20
21The current implementation fails for architectures which have the
22stack grow down on the corner case where sas_ss_sp == sp.This was
23reported as Debian bug #544905 on AMD64.
24Simplified test case: http://download.breakpoint.cc/tc-sig-stack.c
25
26The test case creates the following stack scenario:
27 0xn0300 stack top
28 0xn0200 alt stack pointer top (when switching to alt stack)
29 0xn01ff alt stack end
30 0xn0100 alt stack start == stack pointer
31
32If the signal is sent the stack pointer is pointing to the base
33address of the alt stack and the kernel erroneously decides that it
34has already switched to the alternate stack because of the current
35check for "sp - sas_ss_sp < sas_ss_size"
36
37On parisc (stack grows up) the scenario would be:
38 0xn0200 stack pointer
39 0xn01ff alt stack end
40 0xn0100 alt stack start = alt stack pointer base
41 (when switching to alt stack)
42 0xn0000 stack base
43
44This is handled correctly by the current implementation.
45
46[ tglx: Modified for archs which have the stack grow up (parisc) which
47 would fail with the correct implementation for stack grows
48 down. Added a check for sp >= current->sas_ss_sp which is
49 strictly not necessary but makes the code symetric for both
50 variants ]
51
52Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
53Cc: Oleg Nesterov <oleg@redhat.com>
54Cc: Roland McGrath <roland@redhat.com>
55Cc: Kyle McMartin <kyle@mcmartin.ca>
56LKML-Reference: <20091025143758.GA6653@Chamillionaire.breakpoint.cc>
57Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
58Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
59
60---
61 include/linux/sched.h | 13 ++++++++++---
62 1 file changed, 10 insertions(+), 3 deletions(-)
63
64--- a/include/linux/sched.h
65+++ b/include/linux/sched.h
66@@ -2086,11 +2086,18 @@ static inline int is_si_special(const st
67 return info <= SEND_SIG_FORCED;
68 }
69
70-/* True if we are on the alternate signal stack. */
71-
72+/*
73+ * True if we are on the alternate signal stack.
74+ */
75 static inline int on_sig_stack(unsigned long sp)
76 {
77- return (sp - current->sas_ss_sp < current->sas_ss_size);
78+#ifdef CONFIG_STACK_GROWSUP
79+ return sp >= current->sas_ss_sp &&
80+ sp - current->sas_ss_sp < current->sas_ss_size;
81+#else
82+ return sp > current->sas_ss_sp &&
83+ sp - current->sas_ss_sp <= current->sas_ss_size;
84+#endif
85 }
86
87 static inline int sas_ss_flags(unsigned long sp)