]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
POWERPC: Make alignment exception always check exception table
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 20 Nov 2006 21:45:49 +0000 (22:45 +0100)
committerAdrian Bunk <bunk@stusta.de>
Mon, 20 Nov 2006 21:45:49 +0000 (22:45 +0100)
The alignment exception used to only check the exception table for
-EFAULT, not for other errors. That opens an oops window if we can
coerce the kernel into getting an alignment exception for other reasons
in what would normally be a user-protected accessor, which can be done
via some of the futex ops. This fixes it by always checking the
exception tables.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
arch/powerpc/kernel/traps.c
arch/ppc/kernel/traps.c

index 98660aedeeb77234865edaf7075fea0ca29da9df..c9506e226dd00d8ee1da898b563f6e0063e1350b 100644 (file)
@@ -837,7 +837,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
 
 void alignment_exception(struct pt_regs *regs)
 {
-       int fixed;
+       int sig, code, fixed;
 
        fixed = fix_alignment(regs);
 
@@ -849,14 +849,16 @@ void alignment_exception(struct pt_regs *regs)
 
        /* Operand address was bad */
        if (fixed == -EFAULT) {
-               if (user_mode(regs))
-                       _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-               else
-                       /* Search exception table */
-                       bad_page_fault(regs, regs->dar, SIGSEGV);
-               return;
+               sig = SIGSEGV;
+               code = SEGV_ACCERR;
+       } else {
+               sig = SIGBUS;
+               code = BUS_ADRALN;
        }
-       _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+       if (user_mode(regs))
+               _exception(sig, regs, code, regs->dar);
+       else
+               bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)
index 6d0a1838d94cc4badc79fd46552ef6f83be106cc..aa9dd0d07ec9251cffbc41befe3a1ca0ebdbe440 100644 (file)
@@ -711,7 +711,7 @@ void single_step_exception(struct pt_regs *regs)
 
 void alignment_exception(struct pt_regs *regs)
 {
-       int fixed;
+       int sig, code, fixed = 0;
 
        fixed = fix_alignment(regs);
        if (fixed == 1) {
@@ -720,14 +720,16 @@ void alignment_exception(struct pt_regs *regs)
                return;
        }
        if (fixed == -EFAULT) {
-               /* fixed == -EFAULT means the operand address was bad */
-               if (user_mode(regs))
-                       _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-               else
-                       bad_page_fault(regs, regs->dar, SIGSEGV);
-               return;
+               sig = SIGSEGV;
+               code = SEGV_ACCERR;
+       } else {
+               sig = SIGBUS;
+               code = BUS_ADRALN;
        }
-       _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+       if (user_mode(regs))
+               _exception(sig, regs, code, regs->dar);
+       else
+               bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)