5066 lines · 131.5 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* *  linux/kernel/signal.c * *  Copyright (C) 1991, 1992  Linus Torvalds * *  1997-11-02  Modified for POSIX.1b signals by Richard Henderson * *  2003-06-02  Jim Houston - Concurrent Computer Corp. *		Changes to use preallocated sigqueue structures *		to allow signals to be sent reliably. */ #include <linux/slab.h>#include <linux/export.h>#include <linux/init.h>#include <linux/sched/mm.h>#include <linux/sched/user.h>#include <linux/sched/debug.h>#include <linux/sched/task.h>#include <linux/sched/task_stack.h>#include <linux/sched/cputime.h>#include <linux/file.h>#include <linux/fs.h>#include <linux/mm.h>#include <linux/proc_fs.h>#include <linux/tty.h>#include <linux/binfmts.h>#include <linux/coredump.h>#include <linux/security.h>#include <linux/syscalls.h>#include <linux/ptrace.h>#include <linux/signal.h>#include <linux/signalfd.h>#include <linux/ratelimit.h>#include <linux/task_work.h>#include <linux/capability.h>#include <linux/freezer.h>#include <linux/pid_namespace.h>#include <linux/nsproxy.h>#include <linux/user_namespace.h>#include <linux/uprobes.h>#include <linux/compat.h>#include <linux/cn_proc.h>#include <linux/compiler.h>#include <linux/posix-timers.h>#include <linux/cgroup.h>#include <linux/audit.h>#include <linux/sysctl.h>#include <uapi/linux/pidfd.h> #define CREATE_TRACE_POINTS#include <trace/events/signal.h> #include <asm/param.h>#include <linux/uaccess.h>#include <asm/unistd.h>#include <asm/siginfo.h>#include <asm/cacheflush.h>#include <asm/syscall.h>	/* for syscall_get_* */ #include "time/posix-timers.h" /* * SLAB caches for signal bits. */ static struct kmem_cache *sigqueue_cachep; int print_fatal_signals __read_mostly; static void __user *sig_handler(struct task_struct *t, int sig){	return t->sighand->action[sig - 1].sa.sa_handler;} static inline bool sig_handler_ignored(void __user *handler, int sig){	/* Is it explicitly or implicitly ignored? */	return handler == SIG_IGN ||	       (handler == SIG_DFL && sig_kernel_ignore(sig));} static bool sig_task_ignored(struct task_struct *t, int sig, bool force){	void __user *handler; 	handler = sig_handler(t, sig); 	/* SIGKILL and SIGSTOP may not be sent to the global init */	if (unlikely(is_global_init(t) && sig_kernel_only(sig)))		return true; 	if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) &&	    handler == SIG_DFL && !(force && sig_kernel_only(sig)))		return true; 	/* Only allow kernel generated signals to this kthread */	if (unlikely((t->flags & PF_KTHREAD) &&		     (handler == SIG_KTHREAD_KERNEL) && !force))		return true; 	return sig_handler_ignored(handler, sig);} static bool sig_ignored(struct task_struct *t, int sig, bool force){	/*	 * Blocked signals are never ignored, since the	 * signal handler may change by the time it is	 * unblocked.	 */	if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))		return false; 	/*	 * Tracers may want to know about even ignored signal unless it	 * is SIGKILL which can't be reported anyway but can be ignored	 * by SIGNAL_UNKILLABLE task.	 */	if (t->ptrace && sig != SIGKILL)		return false; 	return sig_task_ignored(t, sig, force);} /* * Re-calculate pending state from the set of locally pending * signals, globally pending signals, and blocked signals. */static inline bool has_pending_signals(sigset_t *signal, sigset_t *blocked){	unsigned long ready = 0;	for (long i = 0; i < _NSIG_WORDS; i++)		ready |= signal->sig[i] & ~blocked->sig[i];	return ready != 0;} #define PENDING(p,b) has_pending_signals(&(p)->signal, (b)) static bool recalc_sigpending_tsk(struct task_struct *t){	if ((t->jobctl & (JOBCTL_PENDING_MASK | JOBCTL_TRAP_FREEZE)) ||	    PENDING(&t->pending, &t->blocked) ||	    PENDING(&t->signal->shared_pending, &t->blocked) ||	    cgroup_task_frozen(t)) {		set_tsk_thread_flag(t, TIF_SIGPENDING);		return true;	} 	/*	 * We must never clear the flag in another thread, or in current	 * when it's possible the current syscall is returning -ERESTART*.	 * So we don't clear it here, and only callers who know they should do.	 */	return false;} void recalc_sigpending(void){	if (!recalc_sigpending_tsk(current) && !freezing(current)) {		if (unlikely(test_thread_flag(TIF_SIGPENDING)))			clear_thread_flag(TIF_SIGPENDING);	}}EXPORT_SYMBOL(recalc_sigpending); void calculate_sigpending(void){	/* Have any signals or users of TIF_SIGPENDING been delayed	 * until after fork?	 */	spin_lock_irq(&current->sighand->siglock);	set_tsk_thread_flag(current, TIF_SIGPENDING);	recalc_sigpending();	spin_unlock_irq(&current->sighand->siglock);} /* Given the mask, find the first available signal that should be serviced. */ #define SYNCHRONOUS_MASK \	(sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \	 sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS)) int next_signal(struct sigpending *pending, sigset_t *mask){	unsigned long i, *s, *m, x;	int sig = 0; 	s = pending->signal.sig;	m = mask->sig; 	/*	 * Handle the first word specially: it contains the	 * synchronous signals that need to be dequeued first.	 */	x = *s &~ *m;	if (x) {		if (x & SYNCHRONOUS_MASK)			x &= SYNCHRONOUS_MASK;		sig = ffz(~x) + 1;		return sig;	} 	switch (_NSIG_WORDS) {	default:		for (i = 1; i < _NSIG_WORDS; ++i) {			x = *++s &~ *++m;			if (!x)				continue;			sig = ffz(~x) + i*_NSIG_BPW + 1;			break;		}		break; 	case 2:		x = s[1] &~ m[1];		if (!x)			break;		sig = ffz(~x) + _NSIG_BPW + 1;		break; 	case 1:		/* Nothing to do */		break;	} 	return sig;} static inline void print_dropped_signal(int sig){	static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10); 	if (!print_fatal_signals)		return; 	if (!__ratelimit(&ratelimit_state))		return; 	pr_info("%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n",				current->comm, current->pid, sig);} /** * task_set_jobctl_pending - set jobctl pending bits * @task: target task * @mask: pending bits to set * * Clear @mask from @task->jobctl.  @mask must be subset of * %JOBCTL_PENDING_MASK | %JOBCTL_STOP_CONSUME | %JOBCTL_STOP_SIGMASK | * %JOBCTL_TRAPPING.  If stop signo is being set, the existing signo is * cleared.  If @task is already being killed or exiting, this function * becomes noop. * * CONTEXT: * Must be called with @task->sighand->siglock held. * * RETURNS: * %true if @mask is set, %false if made noop because @task was dying. */bool task_set_jobctl_pending(struct task_struct *task, unsigned long mask){	BUG_ON(mask & ~(JOBCTL_PENDING_MASK | JOBCTL_STOP_CONSUME |			JOBCTL_STOP_SIGMASK | JOBCTL_TRAPPING));	BUG_ON((mask & JOBCTL_TRAPPING) && !(mask & JOBCTL_PENDING_MASK)); 	if (unlikely(fatal_signal_pending(task) || (task->flags & PF_EXITING)))		return false; 	if (mask & JOBCTL_STOP_SIGMASK)		task->jobctl &= ~JOBCTL_STOP_SIGMASK; 	task->jobctl |= mask;	return true;} /** * task_clear_jobctl_trapping - clear jobctl trapping bit * @task: target task * * If JOBCTL_TRAPPING is set, a ptracer is waiting for us to enter TRACED. * Clear it and wake up the ptracer.  Note that we don't need any further * locking.  @task->siglock guarantees that @task->parent points to the * ptracer. * * CONTEXT: * Must be called with @task->sighand->siglock held. */void task_clear_jobctl_trapping(struct task_struct *task){	if (unlikely(task->jobctl & JOBCTL_TRAPPING)) {		task->jobctl &= ~JOBCTL_TRAPPING;		smp_mb();	/* advised by wake_up_bit() */		wake_up_bit(&task->jobctl, JOBCTL_TRAPPING_BIT);	}} /** * task_clear_jobctl_pending - clear jobctl pending bits * @task: target task * @mask: pending bits to clear * * Clear @mask from @task->jobctl.  @mask must be subset of * %JOBCTL_PENDING_MASK.  If %JOBCTL_STOP_PENDING is being cleared, other * STOP bits are cleared together. * * If clearing of @mask leaves no stop or trap pending, this function calls * task_clear_jobctl_trapping(). * * CONTEXT: * Must be called with @task->sighand->siglock held. */void task_clear_jobctl_pending(struct task_struct *task, unsigned long mask){	BUG_ON(mask & ~JOBCTL_PENDING_MASK); 	if (mask & JOBCTL_STOP_PENDING)		mask |= JOBCTL_STOP_CONSUME | JOBCTL_STOP_DEQUEUED; 	task->jobctl &= ~mask; 	if (!(task->jobctl & JOBCTL_PENDING_MASK))		task_clear_jobctl_trapping(task);} /** * task_participate_group_stop - participate in a group stop * @task: task participating in a group stop * * @task has %JOBCTL_STOP_PENDING set and is participating in a group stop. * Group stop states are cleared and the group stop count is consumed if * %JOBCTL_STOP_CONSUME was set.  If the consumption completes the group * stop, the appropriate `SIGNAL_*` flags are set. * * CONTEXT: * Must be called with @task->sighand->siglock held. * * RETURNS: * %true if group stop completion should be notified to the parent, %false * otherwise. */static bool task_participate_group_stop(struct task_struct *task){	struct signal_struct *sig = task->signal;	bool consume = task->jobctl & JOBCTL_STOP_CONSUME; 	WARN_ON_ONCE(!(task->jobctl & JOBCTL_STOP_PENDING)); 	task_clear_jobctl_pending(task, JOBCTL_STOP_PENDING); 	if (!consume)		return false; 	if (!WARN_ON_ONCE(sig->group_stop_count == 0))		sig->group_stop_count--; 	/*	 * Tell the caller to notify completion iff we are entering into a	 * fresh group stop.  Read comment in do_signal_stop() for details.	 */	if (!sig->group_stop_count && !(sig->flags & SIGNAL_STOP_STOPPED)) {		signal_set_stop_flags(sig, SIGNAL_STOP_STOPPED);		return true;	}	return false;} void task_join_group_stop(struct task_struct *task){	unsigned long mask = current->jobctl & JOBCTL_STOP_SIGMASK;	struct signal_struct *sig = current->signal; 	if (sig->group_stop_count) {		sig->group_stop_count++;		mask |= JOBCTL_STOP_CONSUME;	} else if (!(sig->flags & SIGNAL_STOP_STOPPED))		return; 	/* Have the new thread join an on-going signal group stop */	task_set_jobctl_pending(task, mask | JOBCTL_STOP_PENDING);} static struct ucounts *sig_get_ucounts(struct task_struct *t, int sig,				       int override_rlimit){	struct ucounts *ucounts;	long sigpending; 	/*	 * Protect access to @t credentials. This can go away when all	 * callers hold rcu read lock.	 *	 * NOTE! A pending signal will hold on to the user refcount,	 * and we get/put the refcount only when the sigpending count	 * changes from/to zero.	 */	rcu_read_lock();	ucounts = task_ucounts(t);	sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING,					    override_rlimit);	rcu_read_unlock();	if (!sigpending)		return NULL; 	if (unlikely(!override_rlimit && sigpending > task_rlimit(t, RLIMIT_SIGPENDING))) {		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);		print_dropped_signal(sig);		return NULL;	} 	return ucounts;} static void __sigqueue_init(struct sigqueue *q, struct ucounts *ucounts,			    const unsigned int sigqueue_flags){	INIT_LIST_HEAD(&q->list);	q->flags = sigqueue_flags;	q->ucounts = ucounts;} /* * allocate a new signal queue record * - this may be called without locks if and only if t == current, otherwise an *   appropriate lock must be held to stop the target task from exiting */static struct sigqueue *sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,				       int override_rlimit){	struct ucounts *ucounts = sig_get_ucounts(t, sig, override_rlimit);	struct sigqueue *q; 	if (!ucounts)		return NULL; 	q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);	if (!q) {		dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING);		return NULL;	} 	__sigqueue_init(q, ucounts, 0);	return q;} static void __sigqueue_free(struct sigqueue *q){	if (q->flags & SIGQUEUE_PREALLOC) {		posixtimer_sigqueue_putref(q);		return;	}	if (q->ucounts) {		dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING);		q->ucounts = NULL;	}	kmem_cache_free(sigqueue_cachep, q);} void flush_sigqueue(struct sigpending *queue){	struct sigqueue *q; 	sigemptyset(&queue->signal);	while (!list_empty(&queue->list)) {		q = list_entry(queue->list.next, struct sigqueue , list);		list_del_init(&q->list);		__sigqueue_free(q);	}} /* * Flush all pending signals for this kthread. */void flush_signals(struct task_struct *t){	unsigned long flags; 	spin_lock_irqsave(&t->sighand->siglock, flags);	clear_tsk_thread_flag(t, TIF_SIGPENDING);	flush_sigqueue(&t->pending);	flush_sigqueue(&t->signal->shared_pending);	spin_unlock_irqrestore(&t->sighand->siglock, flags);}EXPORT_SYMBOL(flush_signals); void ignore_signals(struct task_struct *t){	int i; 	for (i = 0; i < _NSIG; ++i)		t->sighand->action[i].sa.sa_handler = SIG_IGN; 	flush_signals(t);} /* * Flush all handlers for a task. */ 

Lines 1–500 of 5066.