[PATCH] powerpc: Make alignment exception always check exception table (#2)
flat view
STALE7297d
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2006-11-01 03:43:54
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> --- Paul: this version also fixes arch/ppc This is 2.6.19 material and should probably go into stable as well. (Greg: take it if paulus acks it and it applies :) Index: linux-work/arch/powerpc/kernel/traps.c ===================================================================
--- linux-work.orig/arch/powerpc/kernel/traps.c 2006-10-23 14:41:37.000000000 +1000
+++ linux-work/arch/powerpc/kernel/traps.c 2006-10-30 13:59:41.000000000 +1100@@ -843,7 +843,7 @@ void __kprobes program_check_exception(s void alignment_exception(struct pt_regs *regs) { - int fixed = 0; + int sig, fixed = 0; /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
@@ -856,15 +856,11 @@ void alignment_exception(struct pt_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; - } - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); + sig = fixed == -EFAULT ? SIGSEGV : SIGBUS; + if (user_mode(regs)) + _exception(sig, regs, SEGV_ACCERR, regs->dar); + else + bad_page_fault(regs, regs->dar, sig); } void StackOverflow(struct pt_regs *regs)
Index: linux-work/arch/ppc/kernel/traps.c ===================================================================
--- linux-work.orig/arch/ppc/kernel/traps.c 2006-10-06 13:47:55.000000000 +1000
+++ linux-work/arch/ppc/kernel/traps.c 2006-11-01 14:39:44.000000000 +1100@@ -708,7 +708,7 @@ void single_step_exception(struct pt_reg void alignment_exception(struct pt_regs *regs) { - int fixed; + int sig, fixed = 0; fixed = fix_alignment(regs); if (fixed == 1) {
@@ -716,15 +716,11 @@ void alignment_exception(struct pt_regs emulate_single_step(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; - } - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); + sig = fixed == -EFAULT ? SIGSEGV : SIGBUS; + if (user_mode(regs)) + _exception(sig, regs, SEGV_ACCERR, regs->dar); + else + bad_page_fault(regs, regs->dar, sig); } void StackOverflow(struct pt_regs *regs)