diff options
| -rw-r--r-- | kernel/signal.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 7fe874d12fae..bfdb5686fa3e 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -791,22 +791,31 @@ out: | |||
| 791 | /* | 791 | /* |
| 792 | * Force a signal that the process can't ignore: if necessary | 792 | * Force a signal that the process can't ignore: if necessary |
| 793 | * we unblock the signal and change any SIG_IGN to SIG_DFL. | 793 | * we unblock the signal and change any SIG_IGN to SIG_DFL. |
| 794 | * | ||
| 795 | * Note: If we unblock the signal, we always reset it to SIG_DFL, | ||
| 796 | * since we do not want to have a signal handler that was blocked | ||
| 797 | * be invoked when user space had explicitly blocked it. | ||
| 798 | * | ||
| 799 | * We don't want to have recursive SIGSEGV's etc, for example. | ||
| 794 | */ | 800 | */ |
| 795 | |||
| 796 | int | 801 | int |
| 797 | force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | 802 | force_sig_info(int sig, struct siginfo *info, struct task_struct *t) |
| 798 | { | 803 | { |
| 799 | unsigned long int flags; | 804 | unsigned long int flags; |
| 800 | int ret; | 805 | int ret, blocked, ignored; |
| 806 | struct k_sigaction *action; | ||
| 801 | 807 | ||
| 802 | spin_lock_irqsave(&t->sighand->siglock, flags); | 808 | spin_lock_irqsave(&t->sighand->siglock, flags); |
| 803 | if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) { | 809 | action = &t->sighand->action[sig-1]; |
| 804 | t->sighand->action[sig-1].sa.sa_handler = SIG_DFL; | 810 | ignored = action->sa.sa_handler == SIG_IGN; |
| 805 | } | 811 | blocked = sigismember(&t->blocked, sig); |
| 806 | if (sigismember(&t->blocked, sig)) { | 812 | if (blocked || ignored) { |
| 807 | sigdelset(&t->blocked, sig); | 813 | action->sa.sa_handler = SIG_DFL; |
| 814 | if (blocked) { | ||
| 815 | sigdelset(&t->blocked, sig); | ||
| 816 | recalc_sigpending_tsk(t); | ||
| 817 | } | ||
| 808 | } | 818 | } |
| 809 | recalc_sigpending_tsk(t); | ||
| 810 | ret = specific_send_sig_info(sig, info, t); | 819 | ret = specific_send_sig_info(sig, info, t); |
| 811 | spin_unlock_irqrestore(&t->sighand->siglock, flags); | 820 | spin_unlock_irqrestore(&t->sighand->siglock, flags); |
| 812 | 821 | ||
