From 80c1dfa91c44665f2cecc1666050b2e8e04cef68 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 11 May 2012 10:58:05 +1000 Subject: score: don't mask signals if we fail to setup signal stack If setup_rt_frame() returns -EFAULT then we must not block any signals in the current process. Acked-by: Oleg Nesterov Cc: Chen Liqin Cc: Lennox Wu Signed-off-by: Matt Fleming Signed-off-by: Andrew Morton Signed-off-by: Al Viro --- arch/score/kernel/signal.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/score') diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index aa57440e497..bf9e33e0533 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -272,12 +272,14 @@ static int handle_signal(unsigned long sig, siginfo_t *info, */ ret = setup_rt_frame(ka, regs, sig, oldset, info); - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } return ret; } -- cgit v1.2.3-70-g09d2 From 4c3181bd3bde449d79b04e127b41ef02cade8005 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 11 May 2012 10:58:05 +1000 Subject: score: use set_current_blocked() and block_sigmask() As described in e6fa16ab ("signal: sigprocmask() should do retarget_shared_pending()") the modification of current->blocked is incorrect as we need to check whether the signal we're about to block is pending in the shared queue. Also, use the new helper function introduced in commit 5e6292c0f28f ("signal: add block_sigmask() for adding sigmask to current->blocked") which centralises the code for updating current->blocked after successfully delivering a signal and reduces the amount of duplicate code across architectures. In the past some architectures got this code wrong, so using this helper function should stop that from happening again. Acked-by: Oleg Nesterov Cc: Chen Liqin Cc: Lennox Wu Signed-off-by: Matt Fleming Signed-off-by: Andrew Morton Signed-off-by: Al Viro --- arch/score/kernel/signal.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'arch/score') diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index bf9e33e0533..5a5bd176333 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -159,10 +159,7 @@ score_rt_sigreturn(struct pt_regs *regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext); if (sig < 0) @@ -272,14 +269,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info, */ ret = setup_rt_frame(ka, regs, sig, oldset, info); - if (ret == 0) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } + if (ret == 0) + block_sigmask(ka, sig); return ret; } -- cgit v1.2.3-70-g09d2 From f2ccfb3e565f51f1063d68f119d5b42a7f5fd984 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Apr 2012 03:33:45 -0400 Subject: score: ->restart_block.fn needs to be reset on rt_sigreturn Signed-off-by: Al Viro --- arch/score/kernel/signal.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/score') diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index 5a5bd176333..c3fded7357f 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -152,6 +152,9 @@ score_rt_sigreturn(struct pt_regs *regs) stack_t st; int sig; + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + frame = (struct rt_sigframe __user *) regs->regs[0]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; -- cgit v1.2.3-70-g09d2 From cf4a0ce45c06f79f800f6d8747618901e3a6a8ad Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 21 Apr 2012 21:39:54 -0400 Subject: score: don't open-code force_sigsegv() Signed-off-by: Al Viro --- arch/score/kernel/signal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/score') diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index c3fded7357f..a087ad85175 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -236,9 +236,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, return 0; give_sigsegv: - if (signr == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); + force_sigsegv(signr, current); return -EFAULT; } -- cgit v1.2.3-70-g09d2 From 1d5d4dbe810befe63e79b2d6cdcad2066e3b1fc4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 24 Apr 2012 01:55:30 -0400 Subject: score: add handling of NOTIFY_RESUME to do_notify_resume() It's already called if TIF_NOTIFY_RESUME is set, so we only need to add the actual work. Note that checking for RESTORE_SIGMASK was not needed - set_restore_sigmask() also sets SIGPENDING, so we never RESTORE_SIGMASK without SIGPENDING. Signed-off-by: Al Viro --- arch/score/kernel/signal.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/score') diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index a087ad85175..d4a49011c48 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -350,6 +351,12 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) { /* deal with pending signal delivery */ - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); + if (thread_info_flags & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + if (current->replacement_session_keyring) + key_replace_session_keyring(); + } } -- cgit v1.2.3-70-g09d2