1
2#ifndef _LINUX_SIGNAL_H
3#define _LINUX_SIGNAL_H
4
5#include <linux/bug.h>
6#include <linux/signal_types.h>
7#include <linux/string.h>
8
9struct task_struct;
10
11
12extern int print_fatal_signals;
13
14static inline void copy_siginfo(kernel_siginfo_t *to,
15 const kernel_siginfo_t *from)
16{
17 memcpy(to, from, sizeof(*to));
18}
19
20static inline void clear_siginfo(kernel_siginfo_t *info)
21{
22 memset(info, 0, sizeof(*info));
23}
24
25#define SI_EXPANSION_SIZE (sizeof(struct siginfo) - sizeof(struct kernel_siginfo))
26
27static inline void copy_siginfo_to_external(siginfo_t *to,
28 const kernel_siginfo_t *from)
29{
30 memcpy(to, from, sizeof(*from));
31 memset(((char *)to) + sizeof(struct kernel_siginfo), 0,
32 SI_EXPANSION_SIZE);
33}
34
35int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from);
36int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from);
37
38enum siginfo_layout {
39 SIL_KILL,
40 SIL_TIMER,
41 SIL_POLL,
42 SIL_FAULT,
43 SIL_FAULT_MCEERR,
44 SIL_FAULT_BNDERR,
45 SIL_FAULT_PKUERR,
46 SIL_CHLD,
47 SIL_RT,
48 SIL_SYS,
49};
50
51enum siginfo_layout siginfo_layout(unsigned sig, int si_code);
52
53
54
55
56
57#ifndef __HAVE_ARCH_SIG_BITOPS
58#include <linux/bitops.h>
59
60
61
62static inline void sigaddset(sigset_t *set, int _sig)
63{
64 unsigned long sig = _sig - 1;
65 if (_NSIG_WORDS == 1)
66 set->sig[0] |= 1UL << sig;
67 else
68 set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW);
69}
70
71static inline void sigdelset(sigset_t *set, int _sig)
72{
73 unsigned long sig = _sig - 1;
74 if (_NSIG_WORDS == 1)
75 set->sig[0] &= ~(1UL << sig);
76 else
77 set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW));
78}
79
80static inline int sigismember(sigset_t *set, int _sig)
81{
82 unsigned long sig = _sig - 1;
83 if (_NSIG_WORDS == 1)
84 return 1 & (set->sig[0] >> sig);
85 else
86 return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
87}
88
89#endif
90
91static inline int sigisemptyset(sigset_t *set)
92{
93 switch (_NSIG_WORDS) {
94 case 4:
95 return (set->sig[3] | set->sig[2] |
96 set->sig[1] | set->sig[0]) == 0;
97 case 2:
98 return (set->sig[1] | set->sig[0]) == 0;
99 case 1:
100 return set->sig[0] == 0;
101 default:
102 BUILD_BUG();
103 return 0;
104 }
105}
106
107static inline int sigequalsets(const sigset_t *set1, const sigset_t *set2)
108{
109 switch (_NSIG_WORDS) {
110 case 4:
111 return (set1->sig[3] == set2->sig[3]) &&
112 (set1->sig[2] == set2->sig[2]) &&
113 (set1->sig[1] == set2->sig[1]) &&
114 (set1->sig[0] == set2->sig[0]);
115 case 2:
116 return (set1->sig[1] == set2->sig[1]) &&
117 (set1->sig[0] == set2->sig[0]);
118 case 1:
119 return set1->sig[0] == set2->sig[0];
120 }
121 return 0;
122}
123
124#define sigmask(sig) (1UL << ((sig) - 1))
125
126#ifndef __HAVE_ARCH_SIG_SETOPS
127#include <linux/string.h>
128
129#define _SIG_SET_BINOP(name, op) \
130static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
131{ \
132 unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \
133 \
134 switch (_NSIG_WORDS) { \
135 case 4: \
136 a3 = a->sig[3]; a2 = a->sig[2]; \
137 b3 = b->sig[3]; b2 = b->sig[2]; \
138 r->sig[3] = op(a3, b3); \
139 r->sig[2] = op(a2, b2); \
140 fallthrough; \
141 case 2: \
142 a1 = a->sig[1]; b1 = b->sig[1]; \
143 r->sig[1] = op(a1, b1); \
144 fallthrough; \
145 case 1: \
146 a0 = a->sig[0]; b0 = b->sig[0]; \
147 r->sig[0] = op(a0, b0); \
148 break; \
149 default: \
150 BUILD_BUG(); \
151 } \
152}
153
154#define _sig_or(x,y) ((x) | (y))
155_SIG_SET_BINOP(sigorsets, _sig_or)
156
157#define _sig_and(x,y) ((x) & (y))
158_SIG_SET_BINOP(sigandsets, _sig_and)
159
160#define _sig_andn(x,y) ((x) & ~(y))
161_SIG_SET_BINOP(sigandnsets, _sig_andn)
162
163#undef _SIG_SET_BINOP
164#undef _sig_or
165#undef _sig_and
166#undef _sig_andn
167
168#define _SIG_SET_OP(name, op) \
169static inline void name(sigset_t *set) \
170{ \
171 switch (_NSIG_WORDS) { \
172 case 4: set->sig[3] = op(set->sig[3]); \
173 set->sig[2] = op(set->sig[2]); \
174 fallthrough; \
175 case 2: set->sig[1] = op(set->sig[1]); \
176 fallthrough; \
177 case 1: set->sig[0] = op(set->sig[0]); \
178 break; \
179 default: \
180 BUILD_BUG(); \
181 } \
182}
183
184#define _sig_not(x) (~(x))
185_SIG_SET_OP(signotset, _sig_not)
186
187#undef _SIG_SET_OP
188#undef _sig_not
189
190static inline void sigemptyset(sigset_t *set)
191{
192 switch (_NSIG_WORDS) {
193 default:
194 memset(set, 0, sizeof(sigset_t));
195 break;
196 case 2: set->sig[1] = 0;
197 fallthrough;
198 case 1: set->sig[0] = 0;
199 break;
200 }
201}
202
203static inline void sigfillset(sigset_t *set)
204{
205 switch (_NSIG_WORDS) {
206 default:
207 memset(set, -1, sizeof(sigset_t));
208 break;
209 case 2: set->sig[1] = -1;
210 fallthrough;
211 case 1: set->sig[0] = -1;
212 break;
213 }
214}
215
216
217
218static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
219{
220 set->sig[0] |= mask;
221}
222
223static inline void sigdelsetmask(sigset_t *set, unsigned long mask)
224{
225 set->sig[0] &= ~mask;
226}
227
228static inline int sigtestsetmask(sigset_t *set, unsigned long mask)
229{
230 return (set->sig[0] & mask) != 0;
231}
232
233static inline void siginitset(sigset_t *set, unsigned long mask)
234{
235 set->sig[0] = mask;
236 switch (_NSIG_WORDS) {
237 default:
238 memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1));
239 break;
240 case 2: set->sig[1] = 0;
241 break;
242 case 1: ;
243 }
244}
245
246static inline void siginitsetinv(sigset_t *set, unsigned long mask)
247{
248 set->sig[0] = ~mask;
249 switch (_NSIG_WORDS) {
250 default:
251 memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1));
252 break;
253 case 2: set->sig[1] = -1;
254 break;
255 case 1: ;
256 }
257}
258
259#endif
260
261static inline void init_sigpending(struct sigpending *sig)
262{
263 sigemptyset(&sig->signal);
264 INIT_LIST_HEAD(&sig->list);
265}
266
267extern void flush_sigqueue(struct sigpending *queue);
268
269
270static inline int valid_signal(unsigned long sig)
271{
272 return sig <= _NSIG ? 1 : 0;
273}
274
275struct timespec;
276struct pt_regs;
277enum pid_type;
278
279extern int next_signal(struct sigpending *pending, sigset_t *mask);
280extern int do_send_sig_info(int sig, struct kernel_siginfo *info,
281 struct task_struct *p, enum pid_type type);
282extern int group_send_sig_info(int sig, struct kernel_siginfo *info,
283 struct task_struct *p, enum pid_type type);
284extern int __group_send_sig_info(int, struct kernel_siginfo *, struct task_struct *);
285extern int sigprocmask(int, sigset_t *, sigset_t *);
286extern void set_current_blocked(sigset_t *);
287extern void __set_current_blocked(const sigset_t *);
288extern int show_unhandled_signals;
289
290extern bool get_signal(struct ksignal *ksig);
291extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
292extern void exit_signals(struct task_struct *tsk);
293extern void kernel_sigaction(int, __sighandler_t);
294
295#define SIG_KTHREAD ((__force __sighandler_t)2)
296#define SIG_KTHREAD_KERNEL ((__force __sighandler_t)3)
297
298static inline void allow_signal(int sig)
299{
300
301
302
303
304
305 kernel_sigaction(sig, SIG_KTHREAD);
306}
307
308static inline void allow_kernel_signal(int sig)
309{
310
311
312
313
314
315 kernel_sigaction(sig, SIG_KTHREAD_KERNEL);
316}
317
318static inline void disallow_signal(int sig)
319{
320 kernel_sigaction(sig, SIG_IGN);
321}
322
323extern struct kmem_cache *sighand_cachep;
324
325extern bool unhandled_signal(struct task_struct *tsk, int sig);
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401#ifdef SIGEMT
402#define SIGEMT_MASK rt_sigmask(SIGEMT)
403#else
404#define SIGEMT_MASK 0
405#endif
406
407#if SIGRTMIN > BITS_PER_LONG
408#define rt_sigmask(sig) (1ULL << ((sig)-1))
409#else
410#define rt_sigmask(sig) sigmask(sig)
411#endif
412
413#define siginmask(sig, mask) \
414 ((sig) > 0 && (sig) < SIGRTMIN && (rt_sigmask(sig) & (mask)))
415
416#define SIG_KERNEL_ONLY_MASK (\
417 rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP))
418
419#define SIG_KERNEL_STOP_MASK (\
420 rt_sigmask(SIGSTOP) | rt_sigmask(SIGTSTP) | \
421 rt_sigmask(SIGTTIN) | rt_sigmask(SIGTTOU) )
422
423#define SIG_KERNEL_COREDUMP_MASK (\
424 rt_sigmask(SIGQUIT) | rt_sigmask(SIGILL) | \
425 rt_sigmask(SIGTRAP) | rt_sigmask(SIGABRT) | \
426 rt_sigmask(SIGFPE) | rt_sigmask(SIGSEGV) | \
427 rt_sigmask(SIGBUS) | rt_sigmask(SIGSYS) | \
428 rt_sigmask(SIGXCPU) | rt_sigmask(SIGXFSZ) | \
429 SIGEMT_MASK )
430
431#define SIG_KERNEL_IGNORE_MASK (\
432 rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \
433 rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) )
434
435#define SIG_SPECIFIC_SICODES_MASK (\
436 rt_sigmask(SIGILL) | rt_sigmask(SIGFPE) | \
437 rt_sigmask(SIGSEGV) | rt_sigmask(SIGBUS) | \
438 rt_sigmask(SIGTRAP) | rt_sigmask(SIGCHLD) | \
439 rt_sigmask(SIGPOLL) | rt_sigmask(SIGSYS) | \
440 SIGEMT_MASK )
441
442#define sig_kernel_only(sig) siginmask(sig, SIG_KERNEL_ONLY_MASK)
443#define sig_kernel_coredump(sig) siginmask(sig, SIG_KERNEL_COREDUMP_MASK)
444#define sig_kernel_ignore(sig) siginmask(sig, SIG_KERNEL_IGNORE_MASK)
445#define sig_kernel_stop(sig) siginmask(sig, SIG_KERNEL_STOP_MASK)
446#define sig_specific_sicodes(sig) siginmask(sig, SIG_SPECIFIC_SICODES_MASK)
447
448#define sig_fatal(t, signr) \
449 (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
450 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
451
452void signals_init(void);
453
454int restore_altstack(const stack_t __user *);
455int __save_altstack(stack_t __user *, unsigned long);
456
457#define unsafe_save_altstack(uss, sp, label) do { \
458 stack_t __user *__uss = uss; \
459 struct task_struct *t = current; \
460 unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
461 unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
462 unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
463 if (t->sas_ss_flags & SS_AUTODISARM) \
464 sas_ss_reset(t); \
465} while (0);
466
467#ifdef CONFIG_PROC_FS
468struct seq_file;
469extern void render_sigset_t(struct seq_file *, const char *, sigset_t *);
470#endif
471
472#endif
473