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
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
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>
18 arch/powerpc/kernel/traps.c | 18 ++++++++++--------
19 arch/ppc/kernel/traps.c | 18 ++++++++++--------
20 2 files changed, 20 insertions(+), 16 deletions(-)
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
26 void alignment_exception(struct pt_regs *regs)
29 + int sig, code, fixed = 0;
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
35 /* Operand address was bad */
36 if (fixed == -EFAULT) {
37 - if (user_mode(regs))
38 - _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
40 - /* Search exception table */
41 - bad_page_fault(regs, regs->dar, SIGSEGV);
49 - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
50 + if (user_mode(regs))
51 + _exception(sig, regs, code, regs->dar);
53 + bad_page_fault(regs, regs->dar, sig);
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
61 void alignment_exception(struct pt_regs *regs)
64 + int sig, code, fixed = 0;
66 fixed = fix_alignment(regs);
68 @@ -717,14 +717,16 @@ void alignment_exception(struct pt_regs
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);
76 - bad_page_fault(regs, regs->dar, SIGSEGV);
84 - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
85 + if (user_mode(regs))
86 + _exception(sig, regs, code, regs->dar);
88 + bad_page_fault(regs, regs->dar, sig);
91 void StackOverflow(struct pt_regs *regs)