xref: /openbmc/linux/include/linux/signal.h (revision e71ba124)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef _LINUX_SIGNAL_H
31da177e4SLinus Torvalds #define _LINUX_SIGNAL_H
41da177e4SLinus Torvalds 
51c3bea0eSOleg Nesterov #include <linux/bug.h>
6e6d930b4SIngo Molnar #include <linux/signal_types.h>
77994200cSChristoph Hellwig #include <linux/string.h>
81da177e4SLinus Torvalds 
91477fcc2SStephen Rothwell struct task_struct;
101477fcc2SStephen Rothwell 
11d33ed52dSDave Young /* for sysctl */
12d33ed52dSDave Young extern int print_fatal_signals;
131da177e4SLinus Torvalds 
copy_siginfo(kernel_siginfo_t * to,const kernel_siginfo_t * from)14ae7795bcSEric W. Biederman static inline void copy_siginfo(kernel_siginfo_t *to,
15ae7795bcSEric W. Biederman 				const kernel_siginfo_t *from)
16ca9eb49aSJames Hogan {
17ca9eb49aSJames Hogan 	memcpy(to, from, sizeof(*to));
18ca9eb49aSJames Hogan }
19ca9eb49aSJames Hogan 
clear_siginfo(kernel_siginfo_t * info)20ae7795bcSEric W. Biederman static inline void clear_siginfo(kernel_siginfo_t *info)
218c5dbf2aSEric W. Biederman {
228c5dbf2aSEric W. Biederman 	memset(info, 0, sizeof(*info));
238c5dbf2aSEric W. Biederman }
248c5dbf2aSEric W. Biederman 
254ce5f9c9SEric W. Biederman #define SI_EXPANSION_SIZE (sizeof(struct siginfo) - sizeof(struct kernel_siginfo))
264ce5f9c9SEric W. Biederman 
copy_siginfo_to_external(siginfo_t * to,const kernel_siginfo_t * from)27fa4751f4SEric W. Biederman static inline void copy_siginfo_to_external(siginfo_t *to,
28fa4751f4SEric W. Biederman 					    const kernel_siginfo_t *from)
29fa4751f4SEric W. Biederman {
30fa4751f4SEric W. Biederman 	memcpy(to, from, sizeof(*from));
31fa4751f4SEric W. Biederman 	memset(((char *)to) + sizeof(struct kernel_siginfo), 0,
32fa4751f4SEric W. Biederman 		SI_EXPANSION_SIZE);
33fa4751f4SEric W. Biederman }
34fa4751f4SEric W. Biederman 
35ae7795bcSEric W. Biederman int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from);
36ae7795bcSEric W. Biederman int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from);
37b9253a43SChristoph Hellwig 
38cc731525SEric W. Biederman enum siginfo_layout {
39cc731525SEric W. Biederman 	SIL_KILL,
40cc731525SEric W. Biederman 	SIL_TIMER,
41cc731525SEric W. Biederman 	SIL_POLL,
42cc731525SEric W. Biederman 	SIL_FAULT,
439abcabe3SEric W. Biederman 	SIL_FAULT_TRAPNO,
4431931c93SEric W. Biederman 	SIL_FAULT_MCEERR,
4531931c93SEric W. Biederman 	SIL_FAULT_BNDERR,
4631931c93SEric W. Biederman 	SIL_FAULT_PKUERR,
47f4ac7302SEric W. Biederman 	SIL_FAULT_PERF_EVENT,
48cc731525SEric W. Biederman 	SIL_CHLD,
49cc731525SEric W. Biederman 	SIL_RT,
50cc731525SEric W. Biederman 	SIL_SYS,
51cc731525SEric W. Biederman };
52cc731525SEric W. Biederman 
53a3670058SEric W. Biederman enum siginfo_layout siginfo_layout(unsigned sig, int si_code);
54cc731525SEric W. Biederman 
551da177e4SLinus Torvalds /*
561da177e4SLinus Torvalds  * Define some primitives to manipulate sigset_t.
571da177e4SLinus Torvalds  */
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds #ifndef __HAVE_ARCH_SIG_BITOPS
601da177e4SLinus Torvalds #include <linux/bitops.h>
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds /* We don't use <linux/bitops.h> for these because there is no need to
631da177e4SLinus Torvalds    be atomic.  */
sigaddset(sigset_t * set,int _sig)641da177e4SLinus Torvalds static inline void sigaddset(sigset_t *set, int _sig)
651da177e4SLinus Torvalds {
661da177e4SLinus Torvalds 	unsigned long sig = _sig - 1;
671da177e4SLinus Torvalds 	if (_NSIG_WORDS == 1)
681da177e4SLinus Torvalds 		set->sig[0] |= 1UL << sig;
691da177e4SLinus Torvalds 	else
701da177e4SLinus Torvalds 		set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW);
711da177e4SLinus Torvalds }
721da177e4SLinus Torvalds 
sigdelset(sigset_t * set,int _sig)731da177e4SLinus Torvalds static inline void sigdelset(sigset_t *set, int _sig)
741da177e4SLinus Torvalds {
751da177e4SLinus Torvalds 	unsigned long sig = _sig - 1;
761da177e4SLinus Torvalds 	if (_NSIG_WORDS == 1)
771da177e4SLinus Torvalds 		set->sig[0] &= ~(1UL << sig);
781da177e4SLinus Torvalds 	else
791da177e4SLinus Torvalds 		set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW));
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
sigismember(sigset_t * set,int _sig)821da177e4SLinus Torvalds static inline int sigismember(sigset_t *set, int _sig)
831da177e4SLinus Torvalds {
841da177e4SLinus Torvalds 	unsigned long sig = _sig - 1;
851da177e4SLinus Torvalds 	if (_NSIG_WORDS == 1)
861da177e4SLinus Torvalds 		return 1 & (set->sig[0] >> sig);
871da177e4SLinus Torvalds 	else
881da177e4SLinus Torvalds 		return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
891da177e4SLinus Torvalds }
901da177e4SLinus Torvalds 
911da177e4SLinus Torvalds #endif /* __HAVE_ARCH_SIG_BITOPS */
921da177e4SLinus Torvalds 
sigisemptyset(sigset_t * set)9371fabd5eSGeorge Anzinger static inline int sigisemptyset(sigset_t *set)
9471fabd5eSGeorge Anzinger {
9571fabd5eSGeorge Anzinger 	switch (_NSIG_WORDS) {
9671fabd5eSGeorge Anzinger 	case 4:
9771fabd5eSGeorge Anzinger 		return (set->sig[3] | set->sig[2] |
9871fabd5eSGeorge Anzinger 			set->sig[1] | set->sig[0]) == 0;
9971fabd5eSGeorge Anzinger 	case 2:
10071fabd5eSGeorge Anzinger 		return (set->sig[1] | set->sig[0]) == 0;
10171fabd5eSGeorge Anzinger 	case 1:
10271fabd5eSGeorge Anzinger 		return set->sig[0] == 0;
10371fabd5eSGeorge Anzinger 	default:
1041c3bea0eSOleg Nesterov 		BUILD_BUG();
10571fabd5eSGeorge Anzinger 		return 0;
10671fabd5eSGeorge Anzinger 	}
10771fabd5eSGeorge Anzinger }
10871fabd5eSGeorge Anzinger 
sigequalsets(const sigset_t * set1,const sigset_t * set2)109c7be96afSWaiman Long static inline int sigequalsets(const sigset_t *set1, const sigset_t *set2)
110c7be96afSWaiman Long {
111c7be96afSWaiman Long 	switch (_NSIG_WORDS) {
112c7be96afSWaiman Long 	case 4:
113c7be96afSWaiman Long 		return	(set1->sig[3] == set2->sig[3]) &&
114c7be96afSWaiman Long 			(set1->sig[2] == set2->sig[2]) &&
115c7be96afSWaiman Long 			(set1->sig[1] == set2->sig[1]) &&
116c7be96afSWaiman Long 			(set1->sig[0] == set2->sig[0]);
117c7be96afSWaiman Long 	case 2:
118c7be96afSWaiman Long 		return	(set1->sig[1] == set2->sig[1]) &&
119c7be96afSWaiman Long 			(set1->sig[0] == set2->sig[0]);
120c7be96afSWaiman Long 	case 1:
121c7be96afSWaiman Long 		return	set1->sig[0] == set2->sig[0];
122c7be96afSWaiman Long 	}
123c7be96afSWaiman Long 	return 0;
124c7be96afSWaiman Long }
125c7be96afSWaiman Long 
1261da177e4SLinus Torvalds #define sigmask(sig)	(1UL << ((sig) - 1))
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds #ifndef __HAVE_ARCH_SIG_SETOPS
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds #define _SIG_SET_BINOP(name, op)					\
1311da177e4SLinus Torvalds static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
1321da177e4SLinus Torvalds {									\
1331da177e4SLinus Torvalds 	unsigned long a0, a1, a2, a3, b0, b1, b2, b3;			\
1341da177e4SLinus Torvalds 									\
1351da177e4SLinus Torvalds 	switch (_NSIG_WORDS) {						\
1361da177e4SLinus Torvalds 	case 4:								\
1371da177e4SLinus Torvalds 		a3 = a->sig[3]; a2 = a->sig[2];				\
1381da177e4SLinus Torvalds 		b3 = b->sig[3]; b2 = b->sig[2];				\
1391da177e4SLinus Torvalds 		r->sig[3] = op(a3, b3);					\
1401da177e4SLinus Torvalds 		r->sig[2] = op(a2, b2);					\
141df561f66SGustavo A. R. Silva 		fallthrough;						\
1421da177e4SLinus Torvalds 	case 2:								\
1431da177e4SLinus Torvalds 		a1 = a->sig[1]; b1 = b->sig[1];				\
1441da177e4SLinus Torvalds 		r->sig[1] = op(a1, b1);					\
145df561f66SGustavo A. R. Silva 		fallthrough;						\
1461da177e4SLinus Torvalds 	case 1:								\
1471da177e4SLinus Torvalds 		a0 = a->sig[0]; b0 = b->sig[0];				\
1481da177e4SLinus Torvalds 		r->sig[0] = op(a0, b0);					\
1491da177e4SLinus Torvalds 		break;							\
1501da177e4SLinus Torvalds 	default:							\
1511c3bea0eSOleg Nesterov 		BUILD_BUG();						\
1521da177e4SLinus Torvalds 	}								\
1531da177e4SLinus Torvalds }
1541da177e4SLinus Torvalds 
1551da177e4SLinus Torvalds #define _sig_or(x,y)	((x) | (y))
_SIG_SET_BINOP(sigorsets,_sig_or)1561da177e4SLinus Torvalds _SIG_SET_BINOP(sigorsets, _sig_or)
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds #define _sig_and(x,y)	((x) & (y))
1591da177e4SLinus Torvalds _SIG_SET_BINOP(sigandsets, _sig_and)
1601da177e4SLinus Torvalds 
161702a5073SOleg Nesterov #define _sig_andn(x,y)	((x) & ~(y))
162702a5073SOleg Nesterov _SIG_SET_BINOP(sigandnsets, _sig_andn)
1631da177e4SLinus Torvalds 
1641da177e4SLinus Torvalds #undef _SIG_SET_BINOP
1651da177e4SLinus Torvalds #undef _sig_or
1661da177e4SLinus Torvalds #undef _sig_and
167702a5073SOleg Nesterov #undef _sig_andn
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds #define _SIG_SET_OP(name, op)						\
1701da177e4SLinus Torvalds static inline void name(sigset_t *set)					\
1711da177e4SLinus Torvalds {									\
1721da177e4SLinus Torvalds 	switch (_NSIG_WORDS) {						\
1731da177e4SLinus Torvalds 	case 4:	set->sig[3] = op(set->sig[3]);				\
1741da177e4SLinus Torvalds 		set->sig[2] = op(set->sig[2]);				\
175df561f66SGustavo A. R. Silva 		fallthrough;						\
1761da177e4SLinus Torvalds 	case 2:	set->sig[1] = op(set->sig[1]);				\
177df561f66SGustavo A. R. Silva 		fallthrough;						\
1781da177e4SLinus Torvalds 	case 1:	set->sig[0] = op(set->sig[0]);				\
1791da177e4SLinus Torvalds 		    break;						\
1801da177e4SLinus Torvalds 	default:							\
1811c3bea0eSOleg Nesterov 		BUILD_BUG();						\
1821da177e4SLinus Torvalds 	}								\
1831da177e4SLinus Torvalds }
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds #define _sig_not(x)	(~(x))
1861da177e4SLinus Torvalds _SIG_SET_OP(signotset, _sig_not)
1871da177e4SLinus Torvalds 
1881da177e4SLinus Torvalds #undef _SIG_SET_OP
1891da177e4SLinus Torvalds #undef _sig_not
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds static inline void sigemptyset(sigset_t *set)
1921da177e4SLinus Torvalds {
1931da177e4SLinus Torvalds 	switch (_NSIG_WORDS) {
1941da177e4SLinus Torvalds 	default:
1951da177e4SLinus Torvalds 		memset(set, 0, sizeof(sigset_t));
1961da177e4SLinus Torvalds 		break;
1971da177e4SLinus Torvalds 	case 2: set->sig[1] = 0;
198df561f66SGustavo A. R. Silva 		fallthrough;
1991da177e4SLinus Torvalds 	case 1:	set->sig[0] = 0;
2001da177e4SLinus Torvalds 		break;
2011da177e4SLinus Torvalds 	}
2021da177e4SLinus Torvalds }
2031da177e4SLinus Torvalds 
sigfillset(sigset_t * set)2041da177e4SLinus Torvalds static inline void sigfillset(sigset_t *set)
2051da177e4SLinus Torvalds {
2061da177e4SLinus Torvalds 	switch (_NSIG_WORDS) {
2071da177e4SLinus Torvalds 	default:
2081da177e4SLinus Torvalds 		memset(set, -1, sizeof(sigset_t));
2091da177e4SLinus Torvalds 		break;
2101da177e4SLinus Torvalds 	case 2: set->sig[1] = -1;
211df561f66SGustavo A. R. Silva 		fallthrough;
2121da177e4SLinus Torvalds 	case 1:	set->sig[0] = -1;
2131da177e4SLinus Torvalds 		break;
2141da177e4SLinus Torvalds 	}
2151da177e4SLinus Torvalds }
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds /* Some extensions for manipulating the low 32 signals in particular.  */
2181da177e4SLinus Torvalds 
sigaddsetmask(sigset_t * set,unsigned long mask)2191da177e4SLinus Torvalds static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
2201da177e4SLinus Torvalds {
2211da177e4SLinus Torvalds 	set->sig[0] |= mask;
2221da177e4SLinus Torvalds }
2231da177e4SLinus Torvalds 
sigdelsetmask(sigset_t * set,unsigned long mask)2241da177e4SLinus Torvalds static inline void sigdelsetmask(sigset_t *set, unsigned long mask)
2251da177e4SLinus Torvalds {
2261da177e4SLinus Torvalds 	set->sig[0] &= ~mask;
2271da177e4SLinus Torvalds }
2281da177e4SLinus Torvalds 
sigtestsetmask(sigset_t * set,unsigned long mask)2291da177e4SLinus Torvalds static inline int sigtestsetmask(sigset_t *set, unsigned long mask)
2301da177e4SLinus Torvalds {
2311da177e4SLinus Torvalds 	return (set->sig[0] & mask) != 0;
2321da177e4SLinus Torvalds }
2331da177e4SLinus Torvalds 
siginitset(sigset_t * set,unsigned long mask)2341da177e4SLinus Torvalds static inline void siginitset(sigset_t *set, unsigned long mask)
2351da177e4SLinus Torvalds {
2361da177e4SLinus Torvalds 	set->sig[0] = mask;
2371da177e4SLinus Torvalds 	switch (_NSIG_WORDS) {
2381da177e4SLinus Torvalds 	default:
2391da177e4SLinus Torvalds 		memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1));
2401da177e4SLinus Torvalds 		break;
2411da177e4SLinus Torvalds 	case 2: set->sig[1] = 0;
2424169e889SGustavo A. R. Silva 		break;
2431da177e4SLinus Torvalds 	case 1: ;
2441da177e4SLinus Torvalds 	}
2451da177e4SLinus Torvalds }
2461da177e4SLinus Torvalds 
siginitsetinv(sigset_t * set,unsigned long mask)2471da177e4SLinus Torvalds static inline void siginitsetinv(sigset_t *set, unsigned long mask)
2481da177e4SLinus Torvalds {
2491da177e4SLinus Torvalds 	set->sig[0] = ~mask;
2501da177e4SLinus Torvalds 	switch (_NSIG_WORDS) {
2511da177e4SLinus Torvalds 	default:
2521da177e4SLinus Torvalds 		memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1));
2531da177e4SLinus Torvalds 		break;
2541da177e4SLinus Torvalds 	case 2: set->sig[1] = -1;
2554169e889SGustavo A. R. Silva 		break;
2561da177e4SLinus Torvalds 	case 1: ;
2571da177e4SLinus Torvalds 	}
2581da177e4SLinus Torvalds }
2591da177e4SLinus Torvalds 
2601da177e4SLinus Torvalds #endif /* __HAVE_ARCH_SIG_SETOPS */
2611da177e4SLinus Torvalds 
init_sigpending(struct sigpending * sig)2621da177e4SLinus Torvalds static inline void init_sigpending(struct sigpending *sig)
2631da177e4SLinus Torvalds {
2641da177e4SLinus Torvalds 	sigemptyset(&sig->signal);
2651da177e4SLinus Torvalds 	INIT_LIST_HEAD(&sig->list);
2661da177e4SLinus Torvalds }
2671da177e4SLinus Torvalds 
2686a14c5c9SOleg Nesterov extern void flush_sigqueue(struct sigpending *queue);
2696a14c5c9SOleg Nesterov 
270e5bdd883SJesper Juhl /* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */
valid_signal(unsigned long sig)271e5bdd883SJesper Juhl static inline int valid_signal(unsigned long sig)
272e5bdd883SJesper Juhl {
273e5bdd883SJesper Juhl 	return sig <= _NSIG ? 1 : 0;
274e5bdd883SJesper Juhl }
275e5bdd883SJesper Juhl 
276b2b07e4fSOleg Nesterov struct timespec;
277b2b07e4fSOleg Nesterov struct pt_regs;
27801024980SEric W. Biederman enum pid_type;
279b2b07e4fSOleg Nesterov 
280fba2afaaSDavide Libenzi extern int next_signal(struct sigpending *pending, sigset_t *mask);
281ae7795bcSEric W. Biederman extern int do_send_sig_info(int sig, struct kernel_siginfo *info,
28240b3b025SEric W. Biederman 				struct task_struct *p, enum pid_type type);
283ae7795bcSEric W. Biederman extern int group_send_sig_info(int sig, struct kernel_siginfo *info,
28401024980SEric W. Biederman 			       struct task_struct *p, enum pid_type type);
285*157cc181SEric W. Biederman extern int send_signal_locked(int sig, struct kernel_siginfo *info,
286*157cc181SEric W. Biederman 			      struct task_struct *p, enum pid_type type);
2871da177e4SLinus Torvalds extern int sigprocmask(int, sigset_t *, sigset_t *);
28877097ae5SAl Viro extern void set_current_blocked(sigset_t *);
28977097ae5SAl Viro extern void __set_current_blocked(const sigset_t *);
290abd4f750SMasoud Asgharifard Sharbiani extern int show_unhandled_signals;
2911da177e4SLinus Torvalds 
29220ab7218SChristian Brauner extern bool get_signal(struct ksignal *ksig);
2932ce5da17SAl Viro extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
294d12619b5SOleg Nesterov extern void exit_signals(struct task_struct *tsk);
295b4e74264SOleg Nesterov extern void kernel_sigaction(int, __sighandler_t);
296b4e74264SOleg Nesterov 
29733da8e7cSEric W. Biederman #define SIG_KTHREAD ((__force __sighandler_t)2)
29833da8e7cSEric W. Biederman #define SIG_KTHREAD_KERNEL ((__force __sighandler_t)3)
29933da8e7cSEric W. Biederman 
allow_signal(int sig)300b4e74264SOleg Nesterov static inline void allow_signal(int sig)
301b4e74264SOleg Nesterov {
302b4e74264SOleg Nesterov 	/*
303b4e74264SOleg Nesterov 	 * Kernel threads handle their own signals. Let the signal code
304b4e74264SOleg Nesterov 	 * know it'll be handled, so that they don't get converted to
305b4e74264SOleg Nesterov 	 * SIGKILL or just silently dropped.
306b4e74264SOleg Nesterov 	 */
30733da8e7cSEric W. Biederman 	kernel_sigaction(sig, SIG_KTHREAD);
30833da8e7cSEric W. Biederman }
30933da8e7cSEric W. Biederman 
allow_kernel_signal(int sig)31033da8e7cSEric W. Biederman static inline void allow_kernel_signal(int sig)
31133da8e7cSEric W. Biederman {
31233da8e7cSEric W. Biederman 	/*
31333da8e7cSEric W. Biederman 	 * Kernel threads handle their own signals. Let the signal code
31433da8e7cSEric W. Biederman 	 * know signals sent by the kernel will be handled, so that they
31533da8e7cSEric W. Biederman 	 * don't get silently dropped.
31633da8e7cSEric W. Biederman 	 */
31733da8e7cSEric W. Biederman 	kernel_sigaction(sig, SIG_KTHREAD_KERNEL);
318b4e74264SOleg Nesterov }
319b4e74264SOleg Nesterov 
disallow_signal(int sig)320b4e74264SOleg Nesterov static inline void disallow_signal(int sig)
321b4e74264SOleg Nesterov {
322b4e74264SOleg Nesterov 	kernel_sigaction(sig, SIG_IGN);
323b4e74264SOleg Nesterov }
3241da177e4SLinus Torvalds 
325298ec1e2SChristoph Lameter extern struct kmem_cache *sighand_cachep;
326298ec1e2SChristoph Lameter 
32767a48a24SChristian Brauner extern bool unhandled_signal(struct task_struct *tsk, int sig);
328abd4f750SMasoud Asgharifard Sharbiani 
32955c0d1f8SRoland McGrath /*
33055c0d1f8SRoland McGrath  * In POSIX a signal is sent either to a specific thread (Linux task)
33155c0d1f8SRoland McGrath  * or to the process as a whole (Linux thread group).  How the signal
33255c0d1f8SRoland McGrath  * is sent determines whether it's to one thread or the whole group,
33355c0d1f8SRoland McGrath  * which determines which signal mask(s) are involved in blocking it
33455c0d1f8SRoland McGrath  * from being delivered until later.  When the signal is delivered,
33555c0d1f8SRoland McGrath  * either it's caught or ignored by a user handler or it has a default
33655c0d1f8SRoland McGrath  * effect that applies to the whole thread group (POSIX process).
33755c0d1f8SRoland McGrath  *
33855c0d1f8SRoland McGrath  * The possible effects an unblocked signal set to SIG_DFL can have are:
33955c0d1f8SRoland McGrath  *   ignore	- Nothing Happens
34055c0d1f8SRoland McGrath  *   terminate	- kill the process, i.e. all threads in the group,
34155c0d1f8SRoland McGrath  * 		  similar to exit_group.  The group leader (only) reports
34255c0d1f8SRoland McGrath  *		  WIFSIGNALED status to its parent.
34355c0d1f8SRoland McGrath  *   coredump	- write a core dump file describing all threads using
34455c0d1f8SRoland McGrath  *		  the same mm and then kill all those threads
34555c0d1f8SRoland McGrath  *   stop 	- stop all the threads in the group, i.e. TASK_STOPPED state
34655c0d1f8SRoland McGrath  *
34755c0d1f8SRoland McGrath  * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
34855c0d1f8SRoland McGrath  * Other signals when not blocked and set to SIG_DFL behaves as follows.
34955c0d1f8SRoland McGrath  * The job control signals also have other special effects.
35055c0d1f8SRoland McGrath  *
35155c0d1f8SRoland McGrath  *	+--------------------+------------------+
35255c0d1f8SRoland McGrath  *	|  POSIX signal      |  default action  |
35355c0d1f8SRoland McGrath  *	+--------------------+------------------+
35455c0d1f8SRoland McGrath  *	|  SIGHUP            |  terminate	|
35555c0d1f8SRoland McGrath  *	|  SIGINT            |	terminate	|
35655c0d1f8SRoland McGrath  *	|  SIGQUIT           |	coredump 	|
35755c0d1f8SRoland McGrath  *	|  SIGILL            |	coredump 	|
35855c0d1f8SRoland McGrath  *	|  SIGTRAP           |	coredump 	|
35955c0d1f8SRoland McGrath  *	|  SIGABRT/SIGIOT    |	coredump 	|
36055c0d1f8SRoland McGrath  *	|  SIGBUS            |	coredump 	|
36155c0d1f8SRoland McGrath  *	|  SIGFPE            |	coredump 	|
36255c0d1f8SRoland McGrath  *	|  SIGKILL           |	terminate(+)	|
36355c0d1f8SRoland McGrath  *	|  SIGUSR1           |	terminate	|
36455c0d1f8SRoland McGrath  *	|  SIGSEGV           |	coredump 	|
36555c0d1f8SRoland McGrath  *	|  SIGUSR2           |	terminate	|
36655c0d1f8SRoland McGrath  *	|  SIGPIPE           |	terminate	|
36755c0d1f8SRoland McGrath  *	|  SIGALRM           |	terminate	|
36855c0d1f8SRoland McGrath  *	|  SIGTERM           |	terminate	|
36955c0d1f8SRoland McGrath  *	|  SIGCHLD           |	ignore   	|
37055c0d1f8SRoland McGrath  *	|  SIGCONT           |	ignore(*)	|
37155c0d1f8SRoland McGrath  *	|  SIGSTOP           |	stop(*)(+)  	|
37255c0d1f8SRoland McGrath  *	|  SIGTSTP           |	stop(*)  	|
37355c0d1f8SRoland McGrath  *	|  SIGTTIN           |	stop(*)  	|
37455c0d1f8SRoland McGrath  *	|  SIGTTOU           |	stop(*)  	|
37555c0d1f8SRoland McGrath  *	|  SIGURG            |	ignore   	|
37655c0d1f8SRoland McGrath  *	|  SIGXCPU           |	coredump 	|
37755c0d1f8SRoland McGrath  *	|  SIGXFSZ           |	coredump 	|
37855c0d1f8SRoland McGrath  *	|  SIGVTALRM         |	terminate	|
37955c0d1f8SRoland McGrath  *	|  SIGPROF           |	terminate	|
38055c0d1f8SRoland McGrath  *	|  SIGPOLL/SIGIO     |	terminate	|
38155c0d1f8SRoland McGrath  *	|  SIGSYS/SIGUNUSED  |	coredump 	|
38255c0d1f8SRoland McGrath  *	|  SIGSTKFLT         |	terminate	|
38355c0d1f8SRoland McGrath  *	|  SIGWINCH          |	ignore   	|
38455c0d1f8SRoland McGrath  *	|  SIGPWR            |	terminate	|
38555c0d1f8SRoland McGrath  *	|  SIGRTMIN-SIGRTMAX |	terminate       |
38655c0d1f8SRoland McGrath  *	+--------------------+------------------+
38755c0d1f8SRoland McGrath  *	|  non-POSIX signal  |  default action  |
38855c0d1f8SRoland McGrath  *	+--------------------+------------------+
38955c0d1f8SRoland McGrath  *	|  SIGEMT            |  coredump	|
39055c0d1f8SRoland McGrath  *	+--------------------+------------------+
39155c0d1f8SRoland McGrath  *
39255c0d1f8SRoland McGrath  * (+) For SIGKILL and SIGSTOP the action is "always", not just "default".
39355c0d1f8SRoland McGrath  * (*) Special job control effects:
39455c0d1f8SRoland McGrath  * When SIGCONT is sent, it resumes the process (all threads in the group)
39555c0d1f8SRoland McGrath  * from TASK_STOPPED state and also clears any pending/queued stop signals
39655c0d1f8SRoland McGrath  * (any of those marked with "stop(*)").  This happens regardless of blocking,
39755c0d1f8SRoland McGrath  * catching, or ignoring SIGCONT.  When any stop signal is sent, it clears
39855c0d1f8SRoland McGrath  * any pending/queued SIGCONT signals; this happens regardless of blocking,
39955c0d1f8SRoland McGrath  * catching, or ignored the stop signal, though (except for SIGSTOP) the
40055c0d1f8SRoland McGrath  * default action of stopping the process may happen later or never.
40155c0d1f8SRoland McGrath  */
40255c0d1f8SRoland McGrath 
40355c0d1f8SRoland McGrath #ifdef SIGEMT
40455c0d1f8SRoland McGrath #define SIGEMT_MASK	rt_sigmask(SIGEMT)
40555c0d1f8SRoland McGrath #else
40655c0d1f8SRoland McGrath #define SIGEMT_MASK	0
40755c0d1f8SRoland McGrath #endif
40855c0d1f8SRoland McGrath 
40955c0d1f8SRoland McGrath #if SIGRTMIN > BITS_PER_LONG
41055c0d1f8SRoland McGrath #define rt_sigmask(sig)	(1ULL << ((sig)-1))
41155c0d1f8SRoland McGrath #else
41255c0d1f8SRoland McGrath #define rt_sigmask(sig)	sigmask(sig)
41355c0d1f8SRoland McGrath #endif
4145c8ccefdSOleg Nesterov 
4155c8ccefdSOleg Nesterov #define siginmask(sig, mask) \
416ee17e5d6SEric W. Biederman 	((sig) > 0 && (sig) < SIGRTMIN && (rt_sigmask(sig) & (mask)))
41755c0d1f8SRoland McGrath 
41855c0d1f8SRoland McGrath #define SIG_KERNEL_ONLY_MASK (\
41955c0d1f8SRoland McGrath 	rt_sigmask(SIGKILL)   |  rt_sigmask(SIGSTOP))
42055c0d1f8SRoland McGrath 
42155c0d1f8SRoland McGrath #define SIG_KERNEL_STOP_MASK (\
42255c0d1f8SRoland McGrath 	rt_sigmask(SIGSTOP)   |  rt_sigmask(SIGTSTP)   | \
42355c0d1f8SRoland McGrath 	rt_sigmask(SIGTTIN)   |  rt_sigmask(SIGTTOU)   )
42455c0d1f8SRoland McGrath 
42555c0d1f8SRoland McGrath #define SIG_KERNEL_COREDUMP_MASK (\
42655c0d1f8SRoland McGrath         rt_sigmask(SIGQUIT)   |  rt_sigmask(SIGILL)    | \
42755c0d1f8SRoland McGrath 	rt_sigmask(SIGTRAP)   |  rt_sigmask(SIGABRT)   | \
42855c0d1f8SRoland McGrath         rt_sigmask(SIGFPE)    |  rt_sigmask(SIGSEGV)   | \
42955c0d1f8SRoland McGrath 	rt_sigmask(SIGBUS)    |  rt_sigmask(SIGSYS)    | \
43055c0d1f8SRoland McGrath         rt_sigmask(SIGXCPU)   |  rt_sigmask(SIGXFSZ)   | \
43155c0d1f8SRoland McGrath 	SIGEMT_MASK				       )
43255c0d1f8SRoland McGrath 
43355c0d1f8SRoland McGrath #define SIG_KERNEL_IGNORE_MASK (\
43455c0d1f8SRoland McGrath         rt_sigmask(SIGCONT)   |  rt_sigmask(SIGCHLD)   | \
43555c0d1f8SRoland McGrath 	rt_sigmask(SIGWINCH)  |  rt_sigmask(SIGURG)    )
43655c0d1f8SRoland McGrath 
437d08477aaSEric W. Biederman #define SIG_SPECIFIC_SICODES_MASK (\
438d08477aaSEric W. Biederman 	rt_sigmask(SIGILL)    |  rt_sigmask(SIGFPE)    | \
439d08477aaSEric W. Biederman 	rt_sigmask(SIGSEGV)   |  rt_sigmask(SIGBUS)    | \
440d08477aaSEric W. Biederman 	rt_sigmask(SIGTRAP)   |  rt_sigmask(SIGCHLD)   | \
441d08477aaSEric W. Biederman 	rt_sigmask(SIGPOLL)   |  rt_sigmask(SIGSYS)    | \
442d08477aaSEric W. Biederman 	SIGEMT_MASK                                    )
443d08477aaSEric W. Biederman 
4445c8ccefdSOleg Nesterov #define sig_kernel_only(sig)		siginmask(sig, SIG_KERNEL_ONLY_MASK)
4455c8ccefdSOleg Nesterov #define sig_kernel_coredump(sig)	siginmask(sig, SIG_KERNEL_COREDUMP_MASK)
4465c8ccefdSOleg Nesterov #define sig_kernel_ignore(sig)		siginmask(sig, SIG_KERNEL_IGNORE_MASK)
4475c8ccefdSOleg Nesterov #define sig_kernel_stop(sig)		siginmask(sig, SIG_KERNEL_STOP_MASK)
448d08477aaSEric W. Biederman #define sig_specific_sicodes(sig)	siginmask(sig, SIG_SPECIFIC_SICODES_MASK)
44955c0d1f8SRoland McGrath 
45055c0d1f8SRoland McGrath #define sig_fatal(t, signr) \
45155c0d1f8SRoland McGrath 	(!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
45255c0d1f8SRoland McGrath 	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
45355c0d1f8SRoland McGrath 
454a1c9eea9SAdrian Bunk void signals_init(void);
455a1c9eea9SAdrian Bunk 
4565c49574fSAl Viro int restore_altstack(const stack_t __user *);
457c40702c4SAl Viro int __save_altstack(stack_t __user *, unsigned long);
4585c49574fSAl Viro 
459119cd59fSAl Viro #define unsafe_save_altstack(uss, sp, label) do { \
460bd1c149aSAl Viro 	stack_t __user *__uss = uss; \
461bd1c149aSAl Viro 	struct task_struct *t = current; \
462119cd59fSAl Viro 	unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
463119cd59fSAl Viro 	unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
464119cd59fSAl Viro 	unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
465bd1c149aSAl Viro } while (0);
466bd1c149aSAl Viro 
4671bdda24cSThomas Gleixner #ifdef CONFIG_DYNAMIC_SIGFRAME
4681bdda24cSThomas Gleixner bool sigaltstack_size_valid(size_t ss_size);
4691bdda24cSThomas Gleixner #else
sigaltstack_size_valid(size_t size)4701bdda24cSThomas Gleixner static inline bool sigaltstack_size_valid(size_t size) { return true; }
4711bdda24cSThomas Gleixner #endif /* !CONFIG_DYNAMIC_SIGFRAME */
4721bdda24cSThomas Gleixner 
47334db8aafSDavid Howells #ifdef CONFIG_PROC_FS
47434db8aafSDavid Howells struct seq_file;
47534db8aafSDavid Howells extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);
47634db8aafSDavid Howells #endif
47734db8aafSDavid Howells 
4786ac05e83SPeter Collingbourne #ifndef arch_untagged_si_addr
4796ac05e83SPeter Collingbourne /*
4806ac05e83SPeter Collingbourne  * Given a fault address and a signal and si_code which correspond to the
4816ac05e83SPeter Collingbourne  * _sigfault union member, returns the address that must appear in si_addr if
4826ac05e83SPeter Collingbourne  * the signal handler does not have SA_EXPOSE_TAGBITS enabled in sa_flags.
4836ac05e83SPeter Collingbourne  */
arch_untagged_si_addr(void __user * addr,unsigned long sig,unsigned long si_code)4846ac05e83SPeter Collingbourne static inline void __user *arch_untagged_si_addr(void __user *addr,
4856ac05e83SPeter Collingbourne 						 unsigned long sig,
4866ac05e83SPeter Collingbourne 						 unsigned long si_code)
4876ac05e83SPeter Collingbourne {
4886ac05e83SPeter Collingbourne 	return addr;
4896ac05e83SPeter Collingbourne }
4906ac05e83SPeter Collingbourne #endif
4916ac05e83SPeter Collingbourne 
4921da177e4SLinus Torvalds #endif /* _LINUX_SIGNAL_H */
493