aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/signal32.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-09-22 00:41:12 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-22 00:41:12 -0400
commit392c21802ee3aa85cee0e703105f797a8a7b9416 (patch)
treed0b40070dbd80817f069a5b033044e6370b55f26 /arch/sparc/kernel/signal32.c
parent05c5e7698bdc54b3079a3517d86077f49ebcc788 (diff)
sparc: Don't mask signal when we can't setup signal frame.
Don't invoke the signal handler tracehook in that situation either. Reported-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/signal32.c')
-rw-r--r--arch/sparc/kernel/signal32.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 76b67c4c6aa4..643a354795cc 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -511,8 +511,8 @@ out_irqs_on:
511 511
512} 512}
513 513
514static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, 514static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
515 int signo, sigset_t *oldset) 515 int signo, sigset_t *oldset)
516{ 516{
517 struct signal_frame32 __user *sf; 517 struct signal_frame32 __user *sf;
518 int sigframe_size; 518 int sigframe_size;
@@ -620,13 +620,16 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
620 620
621sigill: 621sigill:
622 do_exit(SIGILL); 622 do_exit(SIGILL);
623 return -EINVAL;
624
623sigsegv: 625sigsegv:
624 force_sigsegv(signo, current); 626 force_sigsegv(signo, current);
627 return -EFAULT;
625} 628}
626 629
627static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, 630static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
628 unsigned long signr, sigset_t *oldset, 631 unsigned long signr, sigset_t *oldset,
629 siginfo_t *info) 632 siginfo_t *info)
630{ 633{
631 struct rt_signal_frame32 __user *sf; 634 struct rt_signal_frame32 __user *sf;
632 int sigframe_size; 635 int sigframe_size;
@@ -738,22 +741,30 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
738 741
739 flush_signal_insns(address); 742 flush_signal_insns(address);
740 } 743 }
741 return; 744 return 0;
742 745
743sigill: 746sigill:
744 do_exit(SIGILL); 747 do_exit(SIGILL);
748 return -EINVAL;
749
745sigsegv: 750sigsegv:
746 force_sigsegv(signr, current); 751 force_sigsegv(signr, current);
752 return -EFAULT;
747} 753}
748 754
749static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, 755static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
750 siginfo_t *info, 756 siginfo_t *info,
751 sigset_t *oldset, struct pt_regs *regs) 757 sigset_t *oldset, struct pt_regs *regs)
752{ 758{
759 int err;
760
753 if (ka->sa.sa_flags & SA_SIGINFO) 761 if (ka->sa.sa_flags & SA_SIGINFO)
754 setup_rt_frame32(ka, regs, signr, oldset, info); 762 err = setup_rt_frame32(ka, regs, signr, oldset, info);
755 else 763 else
756 setup_frame32(ka, regs, signr, oldset); 764 err = setup_frame32(ka, regs, signr, oldset);
765
766 if (err)
767 return err;
757 768
758 spin_lock_irq(&current->sighand->siglock); 769 spin_lock_irq(&current->sighand->siglock);
759 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 770 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -761,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
761 sigaddset(&current->blocked,signr); 772 sigaddset(&current->blocked,signr);
762 recalc_sigpending(); 773 recalc_sigpending();
763 spin_unlock_irq(&current->sighand->siglock); 774 spin_unlock_irq(&current->sighand->siglock);
775
776 tracehook_signal_handler(signr, info, ka, regs, 0);
777
778 return 0;
764} 779}
765 780
766static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, 781static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
@@ -807,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
807 if (signr > 0) { 822 if (signr > 0) {
808 if (restart_syscall) 823 if (restart_syscall)
809 syscall_restart32(orig_i0, regs, &ka.sa); 824 syscall_restart32(orig_i0, regs, &ka.sa);
810 handle_signal32(signr, &ka, &info, oldset, regs); 825 if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) {
811 826 /* A signal was successfully delivered; the saved
812 /* A signal was successfully delivered; the saved 827 * sigmask will have been stored in the signal frame,
813 * sigmask will have been stored in the signal frame, 828 * and will be restored by sigreturn, so we can simply
814 * and will be restored by sigreturn, so we can simply 829 * clear the TS_RESTORE_SIGMASK flag.
815 * clear the TS_RESTORE_SIGMASK flag. 830 */
816 */ 831 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
817 current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 832 }
818
819 tracehook_signal_handler(signr, &info, &ka, regs, 0);
820 return; 833 return;
821 } 834 }
822 if (restart_syscall && 835 if (restart_syscall &&