]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/2.6.18.3/make-alignment-exception-always-check-exception-table.patch
5.0-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.18.3 / make-alignment-exception-always-check-exception-table.patch
1 From 4393c4f6788cee65095dd838cfeca6edefbfeb52 Mon Sep 17 00:00:00 2001
2 From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
3 Message-Id: <1162416427.25682.429.camel@localhost.localdomain>
4 Date: Wed, 1 Nov 2006 15:11:39 +1100
5 Subject: POWERPC: Make alignment exception always check exception table
6
7 The alignment exception used to only check the exception table for
8 -EFAULT, not for other errors. That opens an oops window if we can
9 coerce the kernel into getting an alignment exception for other reasons
10 in what would normally be a user-protected accessor, which can be done
11 via some of the futex ops. This fixes it by always checking the
12 exception tables.
13
14 Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
15 Signed-off-by: Paul Mackerras <paulus@samba.org>
16 Signed-off-by: Chris Wright <chrisw@sous-sol.org>
17 ---
18 arch/powerpc/kernel/traps.c | 18 ++++++++++--------
19 arch/ppc/kernel/traps.c | 18 ++++++++++--------
20 2 files changed, 20 insertions(+), 16 deletions(-)
21
22 --- linux-2.6.18.2.orig/arch/powerpc/kernel/traps.c
23 +++ linux-2.6.18.2/arch/powerpc/kernel/traps.c
24 @@ -818,7 +818,7 @@ void __kprobes program_check_exception(s
25
26 void alignment_exception(struct pt_regs *regs)
27 {
28 - int fixed = 0;
29 + int sig, code, fixed = 0;
30
31 /* we don't implement logging of alignment exceptions */
32 if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
33 @@ -832,14 +832,16 @@ void alignment_exception(struct pt_regs
34
35 /* Operand address was bad */
36 if (fixed == -EFAULT) {
37 - if (user_mode(regs))
38 - _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
39 - else
40 - /* Search exception table */
41 - bad_page_fault(regs, regs->dar, SIGSEGV);
42 - return;
43 + sig = SIGSEGV;
44 + code = SEGV_ACCERR;
45 + } else {
46 + sig = SIGBUS;
47 + code = BUS_ADRALN;
48 }
49 - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
50 + if (user_mode(regs))
51 + _exception(sig, regs, code, regs->dar);
52 + else
53 + bad_page_fault(regs, regs->dar, sig);
54 }
55
56 void StackOverflow(struct pt_regs *regs)
57 --- linux-2.6.18.2.orig/arch/ppc/kernel/traps.c
58 +++ linux-2.6.18.2/arch/ppc/kernel/traps.c
59 @@ -708,7 +708,7 @@ void single_step_exception(struct pt_reg
60
61 void alignment_exception(struct pt_regs *regs)
62 {
63 - int fixed;
64 + int sig, code, fixed = 0;
65
66 fixed = fix_alignment(regs);
67 if (fixed == 1) {
68 @@ -717,14 +717,16 @@ void alignment_exception(struct pt_regs
69 return;
70 }
71 if (fixed == -EFAULT) {
72 - /* fixed == -EFAULT means the operand address was bad */
73 - if (user_mode(regs))
74 - _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
75 - else
76 - bad_page_fault(regs, regs->dar, SIGSEGV);
77 - return;
78 + sig = SIGSEGV;
79 + code = SEGV_ACCERR;
80 + } else {
81 + sig = SIGBUS;
82 + code = BUS_ADRALN;
83 }
84 - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
85 + if (user_mode(regs))
86 + _exception(sig, regs, code, regs->dar);
87 + else
88 + bad_page_fault(regs, regs->dar, sig);
89 }
90
91 void StackOverflow(struct pt_regs *regs)