Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35de254d authored by Roland McGrath's avatar Roland McGrath Committed by Linus Torvalds
Browse files

tracehook: tracehook_consider_ignored_signal



This defines tracehook_consider_ignored_signal() has a fine-grained hook
for deciding to prevent the normal short-circuit of sending an ignored
signal, as ptrace does.  There is no change, only cleanup.

Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Reviewed-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c45aea27
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -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	/* <linux/tracehook.h> */
+16 −11
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/ptrace.h>
#include <linux/signal.h>
#include <linux/signalfd.h>
#include <linux/tracehook.h>
#include <linux/capability.h>
#include <linux/freezer.h>
#include <linux/pid_namespace.h>
@@ -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);