]> Pileus Git - ~andy/linux/commitdiff
avr32: don't mask signals in the error path
authorMatt Fleming <matt.fleming@intel.com>
Fri, 11 May 2012 00:57:57 +0000 (10:57 +1000)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 22 May 2012 03:52:36 +0000 (23:52 -0400)
The current handle_signal() implementation is broken - it will mask
signals if we fail to setup the signal stack frame, which isn't the
desired behaviour, we should only be masking signals if we succeed in
setting up the stack frame.  It looks like this code was copied from the
old (broken) arm implementation but wasn't updated when the arm code was
fixed in commit a6c61e9dfdd0 ("[ARM] 3168/1: Update ARM signal delivery
and masking").

Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: Havard Skinnemoen <hskinnemoen@gmail.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/avr32/kernel/signal.c

index 64f886fac2efef6ea05bd1c0703cfdf4ccb8d7d4..9c075e105d603b710a677ae7c42175bda71745a5 100644 (file)
@@ -238,22 +238,21 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
         */
        ret |= !valid_user_regs(regs);
 
+       if (ret != 0) {
+               force_sigsegv(sig, current);
+               return;
+       }
+
        /*
-        * Block the signal if we were unsuccessful.
+        * Block the signal if we were successful.
         */
-       if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
-               spin_lock_irq(&current->sighand->siglock);
-               sigorsets(&current->blocked, &current->blocked,
-                         &ka->sa.sa_mask);
+       spin_lock_irq(&current->sighand->siglock);
+       sigorsets(&current->blocked, &current->blocked,
+                 &ka->sa.sa_mask);
+       if (!(ka->sa.sa_flags & SA_NODEFER))
                sigaddset(&current->blocked, sig);
-               recalc_sigpending();
-               spin_unlock_irq(&current->sighand->siglock);
-       }
-
-       if (ret == 0)
-               return;
-
-       force_sigsegv(sig, current);
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
 }
 
 /*