From cf66c9bd08e69447f6fc8030d183f0c1c0dcba0e Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 25 Jul 2008 19:45:51 -0700 Subject: [PATCH] --- yaml --- r: 106215 b: refs/heads/master c: 35de254dc60f91004b3b5ebb1fc7b2c3093d6032 h: refs/heads/master i: 106213: 723cada63f8d8ce8185fd628bbb5be49708a202f 106211: e579f675f7e7d02712b8f964d025a356c7c9f040 106207: a143731d63a8748c14efb36920437690f5ee3446 v: v3 --- [refs] | 2 +- trunk/include/linux/tracehook.h | 19 +++++++++++++++++++ trunk/kernel/signal.c | 27 ++++++++++++++++----------- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/[refs] b/[refs] index 6481e998409b..2fb252ca00c6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c45aea27617d6a1e0aacddc3b0233f704222fcbd +refs/heads/master: 35de254dc60f91004b3b5ebb1fc7b2c3093d6032 diff --git a/trunk/include/linux/tracehook.h b/trunk/include/linux/tracehook.h index 2d1426f8e33b..8cffd34f88d5 100644 --- a/trunk/include/linux/tracehook.h +++ b/trunk/include/linux/tracehook.h @@ -312,4 +312,23 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, ptrace_notify(SIGTRAP); } +/** + * tracehook_consider_ignored_signal - suppress short-circuit of ignored signal + * @task: task receiving the signal + * @sig: signal number being sent + * @handler: %SIG_IGN or %SIG_DFL + * + * Return zero iff tracing doesn't care to examine this ignored signal, + * so it can short-circuit normal delivery and never even get queued. + * Either @handler is %SIG_DFL and @sig's default is ignore, or it's %SIG_IGN. + * + * Called with @task->sighand->siglock held. + */ +static inline int tracehook_consider_ignored_signal(struct task_struct *task, + int sig, + void __user *handler) +{ + return (task_ptrace(task) & PT_PTRACED) != 0; +} + #endif /* */ diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 8715c18b27b9..9efd1cee6d0b 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -39,24 +40,21 @@ static struct kmem_cache *sigqueue_cachep; -static int __sig_ignored(struct task_struct *t, int sig) +static void __user *sig_handler(struct task_struct *t, int sig) { - void __user *handler; + return t->sighand->action[sig - 1].sa.sa_handler; +} +static int sig_handler_ignored(void __user *handler, int sig) +{ /* Is it explicitly or implicitly ignored? */ - - handler = t->sighand->action[sig - 1].sa.sa_handler; return handler == SIG_IGN || (handler == SIG_DFL && sig_kernel_ignore(sig)); } static int sig_ignored(struct task_struct *t, int sig) { - /* - * Tracers always want to know about signals.. - */ - if (t->ptrace & PT_PTRACED) - return 0; + void __user *handler; /* * Blocked signals are never ignored, since the @@ -66,7 +64,14 @@ static int sig_ignored(struct task_struct *t, int sig) if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig)) return 0; - return __sig_ignored(t, sig); + handler = sig_handler(t, sig); + if (!sig_handler_ignored(handler, sig)) + return 0; + + /* + * Tracers may want to know about even ignored signals. + */ + return !tracehook_consider_ignored_signal(t, sig, handler); } /* @@ -2298,7 +2303,7 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) * (for example, SIGCHLD), shall cause the pending signal to * be discarded, whether or not it is blocked" */ - if (__sig_ignored(t, sig)) { + if (sig_handler_ignored(sig_handler(t, sig), sig)) { sigemptyset(&mask); sigaddset(&mask, sig); rm_from_queue_full(&mask, &t->signal->shared_pending);