xref: /openbmc/linux/fs/signalfd.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2fba2afaaSDavide Libenzi /*
3fba2afaaSDavide Libenzi  *  fs/signalfd.c
4fba2afaaSDavide Libenzi  *
5fba2afaaSDavide Libenzi  *  Copyright (C) 2003  Linus Torvalds
6fba2afaaSDavide Libenzi  *
7fba2afaaSDavide Libenzi  *  Mon Mar 5, 2007: Davide Libenzi <davidel@xmailserver.org>
8fba2afaaSDavide Libenzi  *      Changed ->read() to return a siginfo strcture instead of signal number.
9fba2afaaSDavide Libenzi  *      Fixed locking in ->poll().
10fba2afaaSDavide Libenzi  *      Added sighand-detach notification.
11fba2afaaSDavide Libenzi  *      Added fd re-use in sys_signalfd() syscall.
12fba2afaaSDavide Libenzi  *      Now using anonymous inode source.
13fba2afaaSDavide Libenzi  *      Thanks to Oleg Nesterov for useful code review and suggestions.
14fba2afaaSDavide Libenzi  *      More comments and suggestions from Arnd Bergmann.
15b3762bfcSDavi Arnaut  *  Sat May 19, 2007: Davi E. M. Arnaut <davi@haxent.com.br>
16b3762bfcSDavi Arnaut  *      Retrieve multiple signals with one read() call
17b8fceee1SDavide Libenzi  *  Sun Jul 15, 2007: Davide Libenzi <davidel@xmailserver.org>
18b8fceee1SDavide Libenzi  *      Attach to the sighand only during read() and poll().
19fba2afaaSDavide Libenzi  */
20fba2afaaSDavide Libenzi 
21fba2afaaSDavide Libenzi #include <linux/file.h>
22fba2afaaSDavide Libenzi #include <linux/poll.h>
23fba2afaaSDavide Libenzi #include <linux/init.h>
24fba2afaaSDavide Libenzi #include <linux/fs.h>
25fba2afaaSDavide Libenzi #include <linux/sched.h>
265a0e3ad6STejun Heo #include <linux/slab.h>
27fba2afaaSDavide Libenzi #include <linux/kernel.h>
28fba2afaaSDavide Libenzi #include <linux/signal.h>
29fba2afaaSDavide Libenzi #include <linux/list.h>
30fba2afaaSDavide Libenzi #include <linux/anon_inodes.h>
31fba2afaaSDavide Libenzi #include <linux/signalfd.h>
327ec37dfdSAdrian Bunk #include <linux/syscalls.h>
33138d22b5SCyrill Gorcunov #include <linux/proc_fs.h>
347d197ed4SAl Viro #include <linux/compat.h>
35fba2afaaSDavide Libenzi 
signalfd_cleanup(struct sighand_struct * sighand)36d80e731eSOleg Nesterov void signalfd_cleanup(struct sighand_struct *sighand)
37d80e731eSOleg Nesterov {
38*9537bae0SEric Biggers 	wake_up_pollfree(&sighand->signalfd_wqh);
39d80e731eSOleg Nesterov }
40d80e731eSOleg Nesterov 
41fba2afaaSDavide Libenzi struct signalfd_ctx {
42fba2afaaSDavide Libenzi 	sigset_t sigmask;
43fba2afaaSDavide Libenzi };
44fba2afaaSDavide Libenzi 
signalfd_release(struct inode * inode,struct file * file)45fba2afaaSDavide Libenzi static int signalfd_release(struct inode *inode, struct file *file)
46fba2afaaSDavide Libenzi {
47b8fceee1SDavide Libenzi 	kfree(file->private_data);
48fba2afaaSDavide Libenzi 	return 0;
49fba2afaaSDavide Libenzi }
50fba2afaaSDavide Libenzi 
signalfd_poll(struct file * file,poll_table * wait)51076ccb76SAl Viro static __poll_t signalfd_poll(struct file *file, poll_table *wait)
52fba2afaaSDavide Libenzi {
53fba2afaaSDavide Libenzi 	struct signalfd_ctx *ctx = file->private_data;
54076ccb76SAl Viro 	__poll_t events = 0;
55fba2afaaSDavide Libenzi 
56b8fceee1SDavide Libenzi 	poll_wait(file, &current->sighand->signalfd_wqh, wait);
57fba2afaaSDavide Libenzi 
58b8fceee1SDavide Libenzi 	spin_lock_irq(&current->sighand->siglock);
59b8fceee1SDavide Libenzi 	if (next_signal(&current->pending, &ctx->sigmask) ||
60b8fceee1SDavide Libenzi 	    next_signal(&current->signal->shared_pending,
61b8fceee1SDavide Libenzi 			&ctx->sigmask))
62a9a08845SLinus Torvalds 		events |= EPOLLIN;
63b8fceee1SDavide Libenzi 	spin_unlock_irq(&current->sighand->siglock);
64fba2afaaSDavide Libenzi 
65fba2afaaSDavide Libenzi 	return events;
66fba2afaaSDavide Libenzi }
67fba2afaaSDavide Libenzi 
68fba2afaaSDavide Libenzi /*
69fba2afaaSDavide Libenzi  * Copied from copy_siginfo_to_user() in kernel/signal.c
70fba2afaaSDavide Libenzi  */
signalfd_copyinfo(struct signalfd_siginfo __user * uinfo,kernel_siginfo_t const * kinfo)71fba2afaaSDavide Libenzi static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
72ae7795bcSEric W. Biederman 			     kernel_siginfo_t const *kinfo)
73fba2afaaSDavide Libenzi {
745611f55eSEric W. Biederman 	struct signalfd_siginfo new;
75fba2afaaSDavide Libenzi 
76fba2afaaSDavide Libenzi 	BUILD_BUG_ON(sizeof(struct signalfd_siginfo) != 128);
77fba2afaaSDavide Libenzi 
78fba2afaaSDavide Libenzi 	/*
7914e4a0f2SRobert P. J. Day 	 * Unused members should be zero ...
80fba2afaaSDavide Libenzi 	 */
815611f55eSEric W. Biederman 	memset(&new, 0, sizeof(new));
82fba2afaaSDavide Libenzi 
83fba2afaaSDavide Libenzi 	/*
84fba2afaaSDavide Libenzi 	 * If you change siginfo_t structure, please be sure
85fba2afaaSDavide Libenzi 	 * this code is fixed accordingly.
86fba2afaaSDavide Libenzi 	 */
875611f55eSEric W. Biederman 	new.ssi_signo = kinfo->si_signo;
885611f55eSEric W. Biederman 	new.ssi_errno = kinfo->si_errno;
895611f55eSEric W. Biederman 	new.ssi_code  = kinfo->si_code;
90cc731525SEric W. Biederman 	switch (siginfo_layout(kinfo->si_signo, kinfo->si_code)) {
91cc731525SEric W. Biederman 	case SIL_KILL:
925611f55eSEric W. Biederman 		new.ssi_pid = kinfo->si_pid;
935611f55eSEric W. Biederman 		new.ssi_uid = kinfo->si_uid;
94fba2afaaSDavide Libenzi 		break;
95cc731525SEric W. Biederman 	case SIL_TIMER:
965611f55eSEric W. Biederman 		new.ssi_tid = kinfo->si_tid;
975611f55eSEric W. Biederman 		new.ssi_overrun = kinfo->si_overrun;
985611f55eSEric W. Biederman 		new.ssi_ptr = (long) kinfo->si_ptr;
995611f55eSEric W. Biederman 		new.ssi_int = kinfo->si_int;
100fba2afaaSDavide Libenzi 		break;
101cc731525SEric W. Biederman 	case SIL_POLL:
1025611f55eSEric W. Biederman 		new.ssi_band = kinfo->si_band;
1035611f55eSEric W. Biederman 		new.ssi_fd   = kinfo->si_fd;
104fba2afaaSDavide Libenzi 		break;
10531931c93SEric W. Biederman 	case SIL_FAULT_BNDERR:
10631931c93SEric W. Biederman 	case SIL_FAULT_PKUERR:
107f4ac7302SEric W. Biederman 	case SIL_FAULT_PERF_EVENT:
10831931c93SEric W. Biederman 		/*
109922e3013SEric W. Biederman 		 * Fall through to the SIL_FAULT case.  SIL_FAULT_BNDERR,
110f4ac7302SEric W. Biederman 		 * SIL_FAULT_PKUERR, and SIL_FAULT_PERF_EVENT are only
111922e3013SEric W. Biederman 		 * generated by faults that deliver them synchronously to
112922e3013SEric W. Biederman 		 * userspace.  In case someone injects one of these signals
113922e3013SEric W. Biederman 		 * and signalfd catches it treat it as SIL_FAULT.
11431931c93SEric W. Biederman 		 */
115cc731525SEric W. Biederman 	case SIL_FAULT:
1165611f55eSEric W. Biederman 		new.ssi_addr = (long) kinfo->si_addr;
1179abcabe3SEric W. Biederman 		break;
1189abcabe3SEric W. Biederman 	case SIL_FAULT_TRAPNO:
1199abcabe3SEric W. Biederman 		new.ssi_addr = (long) kinfo->si_addr;
1205611f55eSEric W. Biederman 		new.ssi_trapno = kinfo->si_trapno;
12131931c93SEric W. Biederman 		break;
12231931c93SEric W. Biederman 	case SIL_FAULT_MCEERR:
12331931c93SEric W. Biederman 		new.ssi_addr = (long) kinfo->si_addr;
1245611f55eSEric W. Biederman 		new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
125fba2afaaSDavide Libenzi 		break;
126cc731525SEric W. Biederman 	case SIL_CHLD:
1275611f55eSEric W. Biederman 		new.ssi_pid    = kinfo->si_pid;
1285611f55eSEric W. Biederman 		new.ssi_uid    = kinfo->si_uid;
1295611f55eSEric W. Biederman 		new.ssi_status = kinfo->si_status;
1305611f55eSEric W. Biederman 		new.ssi_utime  = kinfo->si_utime;
1315611f55eSEric W. Biederman 		new.ssi_stime  = kinfo->si_stime;
132fba2afaaSDavide Libenzi 		break;
133cc731525SEric W. Biederman 	case SIL_RT:
1340859ab59SDavide Libenzi 		/*
1350859ab59SDavide Libenzi 		 * This case catches also the signals queued by sigqueue().
1360859ab59SDavide Libenzi 		 */
1375611f55eSEric W. Biederman 		new.ssi_pid = kinfo->si_pid;
1385611f55eSEric W. Biederman 		new.ssi_uid = kinfo->si_uid;
1395611f55eSEric W. Biederman 		new.ssi_ptr = (long) kinfo->si_ptr;
1405611f55eSEric W. Biederman 		new.ssi_int = kinfo->si_int;
141fba2afaaSDavide Libenzi 		break;
14276b7f670SEric W. Biederman 	case SIL_SYS:
14376b7f670SEric W. Biederman 		new.ssi_call_addr = (long) kinfo->si_call_addr;
14476b7f670SEric W. Biederman 		new.ssi_syscall   = kinfo->si_syscall;
14576b7f670SEric W. Biederman 		new.ssi_arch      = kinfo->si_arch;
14676b7f670SEric W. Biederman 		break;
147fba2afaaSDavide Libenzi 	}
148fba2afaaSDavide Libenzi 
1495611f55eSEric W. Biederman 	if (copy_to_user(uinfo, &new, sizeof(struct signalfd_siginfo)))
1505611f55eSEric W. Biederman 		return -EFAULT;
1515611f55eSEric W. Biederman 
1525611f55eSEric W. Biederman 	return sizeof(*uinfo);
153fba2afaaSDavide Libenzi }
154fba2afaaSDavide Libenzi 
signalfd_dequeue(struct signalfd_ctx * ctx,kernel_siginfo_t * info,int nonblock)155ae7795bcSEric W. Biederman static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info,
156b3762bfcSDavi Arnaut 				int nonblock)
157b3762bfcSDavi Arnaut {
1585768d890SEric W. Biederman 	enum pid_type type;
159b3762bfcSDavi Arnaut 	ssize_t ret;
160b3762bfcSDavi Arnaut 	DECLARE_WAITQUEUE(wait, current);
161b3762bfcSDavi Arnaut 
162b8fceee1SDavide Libenzi 	spin_lock_irq(&current->sighand->siglock);
1635768d890SEric W. Biederman 	ret = dequeue_signal(current, &ctx->sigmask, info, &type);
164b3762bfcSDavi Arnaut 	switch (ret) {
165b3762bfcSDavi Arnaut 	case 0:
166b3762bfcSDavi Arnaut 		if (!nonblock)
167b3762bfcSDavi Arnaut 			break;
168b3762bfcSDavi Arnaut 		ret = -EAGAIN;
169df561f66SGustavo A. R. Silva 		fallthrough;
170b3762bfcSDavi Arnaut 	default:
171b8fceee1SDavide Libenzi 		spin_unlock_irq(&current->sighand->siglock);
172b3762bfcSDavi Arnaut 		return ret;
173b3762bfcSDavi Arnaut 	}
174b3762bfcSDavi Arnaut 
175b8fceee1SDavide Libenzi 	add_wait_queue(&current->sighand->signalfd_wqh, &wait);
176b3762bfcSDavi Arnaut 	for (;;) {
177b3762bfcSDavi Arnaut 		set_current_state(TASK_INTERRUPTIBLE);
1785768d890SEric W. Biederman 		ret = dequeue_signal(current, &ctx->sigmask, info, &type);
179b3762bfcSDavi Arnaut 		if (ret != 0)
180b3762bfcSDavi Arnaut 			break;
181b3762bfcSDavi Arnaut 		if (signal_pending(current)) {
182b3762bfcSDavi Arnaut 			ret = -ERESTARTSYS;
183b3762bfcSDavi Arnaut 			break;
184b3762bfcSDavi Arnaut 		}
185b8fceee1SDavide Libenzi 		spin_unlock_irq(&current->sighand->siglock);
186b3762bfcSDavi Arnaut 		schedule();
187b8fceee1SDavide Libenzi 		spin_lock_irq(&current->sighand->siglock);
188b3762bfcSDavi Arnaut 	}
189b8fceee1SDavide Libenzi 	spin_unlock_irq(&current->sighand->siglock);
190b3762bfcSDavi Arnaut 
191b8fceee1SDavide Libenzi 	remove_wait_queue(&current->sighand->signalfd_wqh, &wait);
192b3762bfcSDavi Arnaut 	__set_current_state(TASK_RUNNING);
193b3762bfcSDavi Arnaut 
194b3762bfcSDavi Arnaut 	return ret;
195b3762bfcSDavi Arnaut }
196b3762bfcSDavi Arnaut 
197fba2afaaSDavide Libenzi /*
198b8fceee1SDavide Libenzi  * Returns a multiple of the size of a "struct signalfd_siginfo", or a negative
199b8fceee1SDavide Libenzi  * error code. The "count" parameter must be at least the size of a
200b8fceee1SDavide Libenzi  * "struct signalfd_siginfo".
201fba2afaaSDavide Libenzi  */
signalfd_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)202fba2afaaSDavide Libenzi static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
203fba2afaaSDavide Libenzi 			     loff_t *ppos)
204fba2afaaSDavide Libenzi {
205fba2afaaSDavide Libenzi 	struct signalfd_ctx *ctx = file->private_data;
206b3762bfcSDavi Arnaut 	struct signalfd_siginfo __user *siginfo;
207b3762bfcSDavi Arnaut 	int nonblock = file->f_flags & O_NONBLOCK;
208b3762bfcSDavi Arnaut 	ssize_t ret, total = 0;
209ae7795bcSEric W. Biederman 	kernel_siginfo_t info;
210fba2afaaSDavide Libenzi 
211b3762bfcSDavi Arnaut 	count /= sizeof(struct signalfd_siginfo);
212b3762bfcSDavi Arnaut 	if (!count)
213fba2afaaSDavide Libenzi 		return -EINVAL;
214fba2afaaSDavide Libenzi 
215b3762bfcSDavi Arnaut 	siginfo = (struct signalfd_siginfo __user *) buf;
216b3762bfcSDavi Arnaut 	do {
217b3762bfcSDavi Arnaut 		ret = signalfd_dequeue(ctx, &info, nonblock);
218b3762bfcSDavi Arnaut 		if (unlikely(ret <= 0))
219b3762bfcSDavi Arnaut 			break;
220b3762bfcSDavi Arnaut 		ret = signalfd_copyinfo(siginfo, &info);
221b3762bfcSDavi Arnaut 		if (ret < 0)
222b3762bfcSDavi Arnaut 			break;
223b3762bfcSDavi Arnaut 		siginfo++;
224b3762bfcSDavi Arnaut 		total += ret;
225b3762bfcSDavi Arnaut 		nonblock = 1;
226b3762bfcSDavi Arnaut 	} while (--count);
227b3762bfcSDavi Arnaut 
228b3762bfcSDavi Arnaut 	return total ? total: ret;
229fba2afaaSDavide Libenzi }
230fba2afaaSDavide Libenzi 
231138d22b5SCyrill Gorcunov #ifdef CONFIG_PROC_FS
signalfd_show_fdinfo(struct seq_file * m,struct file * f)232a3816ab0SJoe Perches static void signalfd_show_fdinfo(struct seq_file *m, struct file *f)
233138d22b5SCyrill Gorcunov {
234138d22b5SCyrill Gorcunov 	struct signalfd_ctx *ctx = f->private_data;
235138d22b5SCyrill Gorcunov 	sigset_t sigmask;
236138d22b5SCyrill Gorcunov 
237138d22b5SCyrill Gorcunov 	sigmask = ctx->sigmask;
238138d22b5SCyrill Gorcunov 	signotset(&sigmask);
239138d22b5SCyrill Gorcunov 	render_sigset_t(m, "sigmask:\t", &sigmask);
240138d22b5SCyrill Gorcunov }
241138d22b5SCyrill Gorcunov #endif
242138d22b5SCyrill Gorcunov 
243fba2afaaSDavide Libenzi static const struct file_operations signalfd_fops = {
244138d22b5SCyrill Gorcunov #ifdef CONFIG_PROC_FS
245138d22b5SCyrill Gorcunov 	.show_fdinfo	= signalfd_show_fdinfo,
246138d22b5SCyrill Gorcunov #endif
247fba2afaaSDavide Libenzi 	.release	= signalfd_release,
248fba2afaaSDavide Libenzi 	.poll		= signalfd_poll,
249fba2afaaSDavide Libenzi 	.read		= signalfd_read,
2506038f373SArnd Bergmann 	.llseek		= noop_llseek,
251fba2afaaSDavide Libenzi };
252fba2afaaSDavide Libenzi 
do_signalfd4(int ufd,sigset_t * mask,int flags)2535ed0127fSAl Viro static int do_signalfd4(int ufd, sigset_t *mask, int flags)
254fba2afaaSDavide Libenzi {
255fba2afaaSDavide Libenzi 	struct signalfd_ctx *ctx;
256fba2afaaSDavide Libenzi 
257e38b36f3SUlrich Drepper 	/* Check the SFD_* constants for consistency.  */
258e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SFD_CLOEXEC != O_CLOEXEC);
259e38b36f3SUlrich Drepper 	BUILD_BUG_ON(SFD_NONBLOCK != O_NONBLOCK);
260e38b36f3SUlrich Drepper 
2615fb5e049SUlrich Drepper 	if (flags & ~(SFD_CLOEXEC | SFD_NONBLOCK))
2629deb27baSUlrich Drepper 		return -EINVAL;
2639deb27baSUlrich Drepper 
2645ed0127fSAl Viro 	sigdelsetmask(mask, sigmask(SIGKILL) | sigmask(SIGSTOP));
2655ed0127fSAl Viro 	signotset(mask);
266fba2afaaSDavide Libenzi 
267fba2afaaSDavide Libenzi 	if (ufd == -1) {
268fba2afaaSDavide Libenzi 		ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
269fba2afaaSDavide Libenzi 		if (!ctx)
270fba2afaaSDavide Libenzi 			return -ENOMEM;
271fba2afaaSDavide Libenzi 
2725ed0127fSAl Viro 		ctx->sigmask = *mask;
273fba2afaaSDavide Libenzi 
274fba2afaaSDavide Libenzi 		/*
275fba2afaaSDavide Libenzi 		 * When we call this, the initialization must be complete, since
276fba2afaaSDavide Libenzi 		 * anon_inode_getfd() will install the fd.
277fba2afaaSDavide Libenzi 		 */
2787d9dbca3SUlrich Drepper 		ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx,
279628ff7c1SRoland Dreier 				       O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK)));
2802030a42cSAl Viro 		if (ufd < 0)
2812030a42cSAl Viro 			kfree(ctx);
282fba2afaaSDavide Libenzi 	} else {
2832903ff01SAl Viro 		struct fd f = fdget(ufd);
2842903ff01SAl Viro 		if (!f.file)
285fba2afaaSDavide Libenzi 			return -EBADF;
2862903ff01SAl Viro 		ctx = f.file->private_data;
2872903ff01SAl Viro 		if (f.file->f_op != &signalfd_fops) {
2882903ff01SAl Viro 			fdput(f);
289fba2afaaSDavide Libenzi 			return -EINVAL;
290fba2afaaSDavide Libenzi 		}
291b8fceee1SDavide Libenzi 		spin_lock_irq(&current->sighand->siglock);
2925ed0127fSAl Viro 		ctx->sigmask = *mask;
293b8fceee1SDavide Libenzi 		spin_unlock_irq(&current->sighand->siglock);
294b8fceee1SDavide Libenzi 
295b8fceee1SDavide Libenzi 		wake_up(&current->sighand->signalfd_wqh);
2962903ff01SAl Viro 		fdput(f);
297fba2afaaSDavide Libenzi 	}
298fba2afaaSDavide Libenzi 
299fba2afaaSDavide Libenzi 	return ufd;
300fba2afaaSDavide Libenzi }
3019deb27baSUlrich Drepper 
SYSCALL_DEFINE4(signalfd4,int,ufd,sigset_t __user *,user_mask,size_t,sizemask,int,flags)30252fb6db0SDominik Brodowski SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
30352fb6db0SDominik Brodowski 		size_t, sizemask, int, flags)
30452fb6db0SDominik Brodowski {
3055ed0127fSAl Viro 	sigset_t mask;
3065ed0127fSAl Viro 
307a089e3fdSHelge Deller 	if (sizemask != sizeof(sigset_t))
3085ed0127fSAl Viro 		return -EINVAL;
309a089e3fdSHelge Deller 	if (copy_from_user(&mask, user_mask, sizeof(mask)))
310a089e3fdSHelge Deller 		return -EFAULT;
3115ed0127fSAl Viro 	return do_signalfd4(ufd, &mask, flags);
31252fb6db0SDominik Brodowski }
31352fb6db0SDominik Brodowski 
SYSCALL_DEFINE3(signalfd,int,ufd,sigset_t __user *,user_mask,size_t,sizemask)314836f92adSHeiko Carstens SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask,
315836f92adSHeiko Carstens 		size_t, sizemask)
3169deb27baSUlrich Drepper {
3175ed0127fSAl Viro 	sigset_t mask;
3185ed0127fSAl Viro 
319a089e3fdSHelge Deller 	if (sizemask != sizeof(sigset_t))
3205ed0127fSAl Viro 		return -EINVAL;
321a089e3fdSHelge Deller 	if (copy_from_user(&mask, user_mask, sizeof(mask)))
322a089e3fdSHelge Deller 		return -EFAULT;
3235ed0127fSAl Viro 	return do_signalfd4(ufd, &mask, 0);
3249deb27baSUlrich Drepper }
3257d197ed4SAl Viro 
3267d197ed4SAl Viro #ifdef CONFIG_COMPAT
do_compat_signalfd4(int ufd,const compat_sigset_t __user * user_mask,compat_size_t sigsetsize,int flags)327570484bfSDominik Brodowski static long do_compat_signalfd4(int ufd,
3285ed0127fSAl Viro 			const compat_sigset_t __user *user_mask,
329570484bfSDominik Brodowski 			compat_size_t sigsetsize, int flags)
3307d197ed4SAl Viro {
3315ed0127fSAl Viro 	sigset_t mask;
3327d197ed4SAl Viro 
3337d197ed4SAl Viro 	if (sigsetsize != sizeof(compat_sigset_t))
3347d197ed4SAl Viro 		return -EINVAL;
3355ed0127fSAl Viro 	if (get_compat_sigset(&mask, user_mask))
3367d197ed4SAl Viro 		return -EFAULT;
3375ed0127fSAl Viro 	return do_signalfd4(ufd, &mask, flags);
3387d197ed4SAl Viro }
3397d197ed4SAl Viro 
COMPAT_SYSCALL_DEFINE4(signalfd4,int,ufd,const compat_sigset_t __user *,user_mask,compat_size_t,sigsetsize,int,flags)340570484bfSDominik Brodowski COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd,
3415ed0127fSAl Viro 		     const compat_sigset_t __user *, user_mask,
342570484bfSDominik Brodowski 		     compat_size_t, sigsetsize,
343570484bfSDominik Brodowski 		     int, flags)
344570484bfSDominik Brodowski {
3455ed0127fSAl Viro 	return do_compat_signalfd4(ufd, user_mask, sigsetsize, flags);
346570484bfSDominik Brodowski }
347570484bfSDominik Brodowski 
COMPAT_SYSCALL_DEFINE3(signalfd,int,ufd,const compat_sigset_t __user *,user_mask,compat_size_t,sigsetsize)3487d197ed4SAl Viro COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd,
3495ed0127fSAl Viro 		     const compat_sigset_t __user *, user_mask,
3507d197ed4SAl Viro 		     compat_size_t, sigsetsize)
3517d197ed4SAl Viro {
3525ed0127fSAl Viro 	return do_compat_signalfd4(ufd, user_mask, sigsetsize, 0);
3537d197ed4SAl Viro }
3547d197ed4SAl Viro #endif
355