diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/signal.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 4a45bac2c632..24ee53b7f60c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -39,11 +39,19 @@ | |||
39 | 39 | ||
40 | static struct kmem_cache *sigqueue_cachep; | 40 | static struct kmem_cache *sigqueue_cachep; |
41 | 41 | ||
42 | static int __sig_ignored(struct task_struct *t, int sig) | ||
43 | { | ||
44 | void __user *handler; | ||
45 | |||
46 | /* Is it explicitly or implicitly ignored? */ | ||
47 | |||
48 | handler = t->sighand->action[sig - 1].sa.sa_handler; | ||
49 | return handler == SIG_IGN || | ||
50 | (handler == SIG_DFL && sig_kernel_ignore(sig)); | ||
51 | } | ||
42 | 52 | ||
43 | static int sig_ignored(struct task_struct *t, int sig) | 53 | static int sig_ignored(struct task_struct *t, int sig) |
44 | { | 54 | { |
45 | void __user * handler; | ||
46 | |||
47 | /* | 55 | /* |
48 | * Tracers always want to know about signals.. | 56 | * Tracers always want to know about signals.. |
49 | */ | 57 | */ |
@@ -58,10 +66,7 @@ static int sig_ignored(struct task_struct *t, int sig) | |||
58 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) | 66 | if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) |
59 | return 0; | 67 | return 0; |
60 | 68 | ||
61 | /* Is it explicitly or implicitly ignored? */ | 69 | return __sig_ignored(t, sig); |
62 | handler = t->sighand->action[sig-1].sa.sa_handler; | ||
63 | return handler == SIG_IGN || | ||
64 | (handler == SIG_DFL && sig_kernel_ignore(sig)); | ||
65 | } | 70 | } |
66 | 71 | ||
67 | /* | 72 | /* |
@@ -2331,13 +2336,14 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo) | |||
2331 | 2336 | ||
2332 | int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) | 2337 | int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) |
2333 | { | 2338 | { |
2339 | struct task_struct *t = current; | ||
2334 | struct k_sigaction *k; | 2340 | struct k_sigaction *k; |
2335 | sigset_t mask; | 2341 | sigset_t mask; |
2336 | 2342 | ||
2337 | if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig))) | 2343 | if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig))) |
2338 | return -EINVAL; | 2344 | return -EINVAL; |
2339 | 2345 | ||
2340 | k = ¤t->sighand->action[sig-1]; | 2346 | k = &t->sighand->action[sig-1]; |
2341 | 2347 | ||
2342 | spin_lock_irq(¤t->sighand->siglock); | 2348 | spin_lock_irq(¤t->sighand->siglock); |
2343 | if (oact) | 2349 | if (oact) |
@@ -2358,9 +2364,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) | |||
2358 | * (for example, SIGCHLD), shall cause the pending signal to | 2364 | * (for example, SIGCHLD), shall cause the pending signal to |
2359 | * be discarded, whether or not it is blocked" | 2365 | * be discarded, whether or not it is blocked" |
2360 | */ | 2366 | */ |
2361 | if (act->sa.sa_handler == SIG_IGN || | 2367 | if (__sig_ignored(t, sig)) { |
2362 | (act->sa.sa_handler == SIG_DFL && sig_kernel_ignore(sig))) { | ||
2363 | struct task_struct *t = current; | ||
2364 | sigemptyset(&mask); | 2368 | sigemptyset(&mask); |
2365 | sigaddset(&mask, sig); | 2369 | sigaddset(&mask, sig); |
2366 | rm_from_queue_full(&mask, &t->signal->shared_pending); | 2370 | rm_from_queue_full(&mask, &t->signal->shared_pending); |