VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
b24413180f560 (Greg Kroah-Hartman  2017-11-01 15:07:57 +0100   1) // SPDX-License-Identifier: GPL-2.0
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   2) /*
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   3)  *  fs/signalfd.c
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   4)  *
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   5)  *  Copyright (C) 2003  Linus Torvalds
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   6)  *
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   7)  *  Mon Mar 5, 2007: Davide Libenzi <davidel@xmailserver.org>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   8)  *      Changed ->read() to return a siginfo strcture instead of signal number.
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700   9)  *      Fixed locking in ->poll().
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  10)  *      Added sighand-detach notification.
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  11)  *      Added fd re-use in sys_signalfd() syscall.
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  12)  *      Now using anonymous inode source.
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  13)  *      Thanks to Oleg Nesterov for useful code review and suggestions.
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  14)  *      More comments and suggestions from Arnd Bergmann.
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  15)  *  Sat May 19, 2007: Davi E. M. Arnaut <davi@haxent.com.br>
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700  16)  *      Retrieve multiple signals with one read() call
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  17)  *  Sun Jul 15, 2007: Davide Libenzi <davidel@xmailserver.org>
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  18)  *      Attach to the sighand only during read() and poll().
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  19)  */
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  20) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  21) #include <linux/file.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  22) #include <linux/poll.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  23) #include <linux/init.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  24) #include <linux/fs.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  25) #include <linux/sched.h>
5a0e3ad6af866 (Tejun Heo           2010-03-24 17:04:11 +0900  26) #include <linux/slab.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  27) #include <linux/kernel.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  28) #include <linux/signal.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  29) #include <linux/list.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  30) #include <linux/anon_inodes.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  31) #include <linux/signalfd.h>
7ec37dfd4d282 (Adrian Bunk         2008-02-06 01:36:48 -0800  32) #include <linux/syscalls.h>
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800  33) #include <linux/proc_fs.h>
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500  34) #include <linux/compat.h>
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  35) 
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  36) void signalfd_cleanup(struct sighand_struct *sighand)
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  37) {
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  38) 	wait_queue_head_t *wqh = &sighand->signalfd_wqh;
971316f0503a5 (Oleg Nesterov       2012-02-24 20:07:29 +0100  39) 	/*
971316f0503a5 (Oleg Nesterov       2012-02-24 20:07:29 +0100  40) 	 * The lockless check can race with remove_wait_queue() in progress,
971316f0503a5 (Oleg Nesterov       2012-02-24 20:07:29 +0100  41) 	 * but in this case its caller should run under rcu_read_lock() and
5f0d5a3ae7cff (Paul E. McKenney    2017-01-18 02:53:44 -0800  42) 	 * sighand_cachep is SLAB_TYPESAFE_BY_RCU, we can safely return.
971316f0503a5 (Oleg Nesterov       2012-02-24 20:07:29 +0100  43) 	 */
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  44) 	if (likely(!waitqueue_active(wqh)))
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  45) 		return;
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  46) 
ac6424b981bce (Ingo Molnar         2017-06-20 12:06:13 +0200  47) 	/* wait_queue_entry_t->func(POLLFREE) should do remove_wait_queue() */
a9a08845e9acb (Linus Torvalds      2018-02-11 14:34:03 -0800  48) 	wake_up_poll(wqh, EPOLLHUP | POLLFREE);
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  49) }
d80e731ecab42 (Oleg Nesterov       2012-02-24 20:07:11 +0100  50) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  51) struct signalfd_ctx {
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  52) 	sigset_t sigmask;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  53) };
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  54) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  55) static int signalfd_release(struct inode *inode, struct file *file)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  56) {
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  57) 	kfree(file->private_data);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  58) 	return 0;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  59) }
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  60) 
076ccb76e1a6c (Al Viro             2017-07-03 01:02:18 -0400  61) static __poll_t signalfd_poll(struct file *file, poll_table *wait)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  62) {
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  63) 	struct signalfd_ctx *ctx = file->private_data;
076ccb76e1a6c (Al Viro             2017-07-03 01:02:18 -0400  64) 	__poll_t events = 0;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  65) 
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  66) 	poll_wait(file, &current->sighand->signalfd_wqh, wait);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  67) 
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  68) 	spin_lock_irq(&current->sighand->siglock);
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  69) 	if (next_signal(&current->pending, &ctx->sigmask) ||
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  70) 	    next_signal(&current->signal->shared_pending,
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  71) 			&ctx->sigmask))
a9a08845e9acb (Linus Torvalds      2018-02-11 14:34:03 -0800  72) 		events |= EPOLLIN;
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700  73) 	spin_unlock_irq(&current->sighand->siglock);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  74) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  75) 	return events;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  76) }
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  77) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  78) /*
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  79)  * Copied from copy_siginfo_to_user() in kernel/signal.c
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  80)  */
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  81) static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
ae7795bc6187a (Eric W. Biederman   2018-09-25 11:27:20 +0200  82) 			     kernel_siginfo_t const *kinfo)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  83) {
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500  84) 	struct signalfd_siginfo new;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  85) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  86) 	BUILD_BUG_ON(sizeof(struct signalfd_siginfo) != 128);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  87) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  88) 	/*
14e4a0f2bb242 (Robert P. J. Day    2008-02-03 15:12:15 +0200  89) 	 * Unused members should be zero ...
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  90) 	 */
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500  91) 	memset(&new, 0, sizeof(new));
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  92) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  93) 	/*
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  94) 	 * If you change siginfo_t structure, please be sure
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  95) 	 * this code is fixed accordingly.
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700  96) 	 */
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500  97) 	new.ssi_signo = kinfo->si_signo;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500  98) 	new.ssi_errno = kinfo->si_errno;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500  99) 	new.ssi_code  = kinfo->si_code;
cc731525f26af (Eric W. Biederman   2017-07-16 22:36:59 -0500 100) 	switch (siginfo_layout(kinfo->si_signo, kinfo->si_code)) {
cc731525f26af (Eric W. Biederman   2017-07-16 22:36:59 -0500 101) 	case SIL_KILL:
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 102) 		new.ssi_pid = kinfo->si_pid;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 103) 		new.ssi_uid = kinfo->si_uid;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 104) 		break;
cc731525f26af (Eric W. Biederman   2017-07-16 22:36:59 -0500 105) 	case SIL_TIMER:
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 106) 		new.ssi_tid = kinfo->si_tid;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 107) 		new.ssi_overrun = kinfo->si_overrun;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 108) 		new.ssi_ptr = (long) kinfo->si_ptr;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 109) 		new.ssi_int = kinfo->si_int;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 110) 		break;
cc731525f26af (Eric W. Biederman   2017-07-16 22:36:59 -0500 111) 	case SIL_POLL:
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 112) 		new.ssi_band = kinfo->si_band;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 113) 		new.ssi_fd   = kinfo->si_fd;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 114) 		break;
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 115) 	case SIL_FAULT_BNDERR:
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 116) 	case SIL_FAULT_PKUERR:
922e3013046b7 (Eric W. Biederman   2021-05-03 12:52:43 -0500 117) 	case SIL_PERF_EVENT:
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 118) 		/*
922e3013046b7 (Eric W. Biederman   2021-05-03 12:52:43 -0500 119) 		 * Fall through to the SIL_FAULT case.  SIL_FAULT_BNDERR,
922e3013046b7 (Eric W. Biederman   2021-05-03 12:52:43 -0500 120) 		 * SIL_FAULT_PKUERR, and SIL_PERF_EVENT are only
922e3013046b7 (Eric W. Biederman   2021-05-03 12:52:43 -0500 121) 		 * generated by faults that deliver them synchronously to
922e3013046b7 (Eric W. Biederman   2021-05-03 12:52:43 -0500 122) 		 * userspace.  In case someone injects one of these signals
922e3013046b7 (Eric W. Biederman   2021-05-03 12:52:43 -0500 123) 		 * and signalfd catches it treat it as SIL_FAULT.
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 124) 		 */
cc731525f26af (Eric W. Biederman   2017-07-16 22:36:59 -0500 125) 	case SIL_FAULT:
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 126) 		new.ssi_addr = (long) kinfo->si_addr;
9abcabe311181 (Eric W. Biederman   2021-04-30 17:29:36 -0500 127) 		break;
9abcabe311181 (Eric W. Biederman   2021-04-30 17:29:36 -0500 128) 	case SIL_FAULT_TRAPNO:
9abcabe311181 (Eric W. Biederman   2021-04-30 17:29:36 -0500 129) 		new.ssi_addr = (long) kinfo->si_addr;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 130) 		new.ssi_trapno = kinfo->si_trapno;
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 131) 		break;
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 132) 	case SIL_FAULT_MCEERR:
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 133) 		new.ssi_addr = (long) kinfo->si_addr;
31931c93dfe05 (Eric W. Biederman   2018-04-24 20:59:47 -0500 134) 		new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 135) 		break;
cc731525f26af (Eric W. Biederman   2017-07-16 22:36:59 -0500 136) 	case SIL_CHLD:
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 137) 		new.ssi_pid    = kinfo->si_pid;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 138) 		new.ssi_uid    = kinfo->si_uid;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 139) 		new.ssi_status = kinfo->si_status;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 140) 		new.ssi_utime  = kinfo->si_utime;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 141) 		new.ssi_stime  = kinfo->si_stime;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 142) 		break;
cc731525f26af (Eric W. Biederman   2017-07-16 22:36:59 -0500 143) 	case SIL_RT:
0859ab59a8a48 (Davide Libenzi      2008-04-10 21:29:29 -0700 144) 		/*
0859ab59a8a48 (Davide Libenzi      2008-04-10 21:29:29 -0700 145) 		 * This case catches also the signals queued by sigqueue().
0859ab59a8a48 (Davide Libenzi      2008-04-10 21:29:29 -0700 146) 		 */
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 147) 		new.ssi_pid = kinfo->si_pid;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 148) 		new.ssi_uid = kinfo->si_uid;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 149) 		new.ssi_ptr = (long) kinfo->si_ptr;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 150) 		new.ssi_int = kinfo->si_int;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 151) 		break;
76b7f670730e8 (Eric W. Biederman   2018-04-24 20:48:32 -0500 152) 	case SIL_SYS:
76b7f670730e8 (Eric W. Biederman   2018-04-24 20:48:32 -0500 153) 		new.ssi_call_addr = (long) kinfo->si_call_addr;
76b7f670730e8 (Eric W. Biederman   2018-04-24 20:48:32 -0500 154) 		new.ssi_syscall   = kinfo->si_syscall;
76b7f670730e8 (Eric W. Biederman   2018-04-24 20:48:32 -0500 155) 		new.ssi_arch      = kinfo->si_arch;
76b7f670730e8 (Eric W. Biederman   2018-04-24 20:48:32 -0500 156) 		break;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 157) 	}
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 158) 
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 159) 	if (copy_to_user(uinfo, &new, sizeof(struct signalfd_siginfo)))
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 160) 		return -EFAULT;
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 161) 
5611f55ee4df7 (Eric W. Biederman   2018-04-24 20:39:16 -0500 162) 	return sizeof(*uinfo);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 163) }
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 164) 
ae7795bc6187a (Eric W. Biederman   2018-09-25 11:27:20 +0200 165) static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info,
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 166) 				int nonblock)
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 167) {
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 168) 	ssize_t ret;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 169) 	DECLARE_WAITQUEUE(wait, current);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 170) 
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 171) 	spin_lock_irq(&current->sighand->siglock);
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 172) 	ret = dequeue_signal(current, &ctx->sigmask, info);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 173) 	switch (ret) {
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 174) 	case 0:
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 175) 		if (!nonblock)
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 176) 			break;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 177) 		ret = -EAGAIN;
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 178) 		fallthrough;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 179) 	default:
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 180) 		spin_unlock_irq(&current->sighand->siglock);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 181) 		return ret;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 182) 	}
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 183) 
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 184) 	add_wait_queue(&current->sighand->signalfd_wqh, &wait);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 185) 	for (;;) {
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 186) 		set_current_state(TASK_INTERRUPTIBLE);
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 187) 		ret = dequeue_signal(current, &ctx->sigmask, info);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 188) 		if (ret != 0)
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 189) 			break;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 190) 		if (signal_pending(current)) {
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 191) 			ret = -ERESTARTSYS;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 192) 			break;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 193) 		}
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 194) 		spin_unlock_irq(&current->sighand->siglock);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 195) 		schedule();
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 196) 		spin_lock_irq(&current->sighand->siglock);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 197) 	}
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 198) 	spin_unlock_irq(&current->sighand->siglock);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 199) 
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 200) 	remove_wait_queue(&current->sighand->signalfd_wqh, &wait);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 201) 	__set_current_state(TASK_RUNNING);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 202) 
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 203) 	return ret;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 204) }
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 205) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 206) /*
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 207)  * Returns a multiple of the size of a "struct signalfd_siginfo", or a negative
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 208)  * error code. The "count" parameter must be at least the size of a
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 209)  * "struct signalfd_siginfo".
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 210)  */
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 211) static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 212) 			     loff_t *ppos)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 213) {
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 214) 	struct signalfd_ctx *ctx = file->private_data;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 215) 	struct signalfd_siginfo __user *siginfo;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 216) 	int nonblock = file->f_flags & O_NONBLOCK;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 217) 	ssize_t ret, total = 0;
ae7795bc6187a (Eric W. Biederman   2018-09-25 11:27:20 +0200 218) 	kernel_siginfo_t info;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 219) 
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 220) 	count /= sizeof(struct signalfd_siginfo);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 221) 	if (!count)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 222) 		return -EINVAL;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 223) 
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 224) 	siginfo = (struct signalfd_siginfo __user *) buf;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 225) 	do {
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 226) 		ret = signalfd_dequeue(ctx, &info, nonblock);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 227) 		if (unlikely(ret <= 0))
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 228) 			break;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 229) 		ret = signalfd_copyinfo(siginfo, &info);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 230) 		if (ret < 0)
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 231) 			break;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 232) 		siginfo++;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 233) 		total += ret;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 234) 		nonblock = 1;
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 235) 	} while (--count);
b3762bfc8d046 (Davi Arnaut         2007-05-23 13:58:04 -0700 236) 
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 237) 	return total ? total: ret;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 238) }
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 239) 
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 240) #ifdef CONFIG_PROC_FS
a3816ab0e8fe5 (Joe Perches         2014-09-29 16:08:25 -0700 241) static void signalfd_show_fdinfo(struct seq_file *m, struct file *f)
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 242) {
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 243) 	struct signalfd_ctx *ctx = f->private_data;
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 244) 	sigset_t sigmask;
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 245) 
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 246) 	sigmask = ctx->sigmask;
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 247) 	signotset(&sigmask);
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 248) 	render_sigset_t(m, "sigmask:\t", &sigmask);
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 249) }
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 250) #endif
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 251) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 252) static const struct file_operations signalfd_fops = {
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 253) #ifdef CONFIG_PROC_FS
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 254) 	.show_fdinfo	= signalfd_show_fdinfo,
138d22b58696c (Cyrill Gorcunov     2012-12-17 16:05:02 -0800 255) #endif
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 256) 	.release	= signalfd_release,
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 257) 	.poll		= signalfd_poll,
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 258) 	.read		= signalfd_read,
6038f373a3dc1 (Arnd Bergmann       2010-08-15 18:52:59 +0200 259) 	.llseek		= noop_llseek,
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 260) };
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 261) 
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 262) static int do_signalfd4(int ufd, sigset_t *mask, int flags)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 263) {
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 264) 	struct signalfd_ctx *ctx;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 265) 
e38b36f325153 (Ulrich Drepper      2008-07-23 21:29:42 -0700 266) 	/* Check the SFD_* constants for consistency.  */
e38b36f325153 (Ulrich Drepper      2008-07-23 21:29:42 -0700 267) 	BUILD_BUG_ON(SFD_CLOEXEC != O_CLOEXEC);
e38b36f325153 (Ulrich Drepper      2008-07-23 21:29:42 -0700 268) 	BUILD_BUG_ON(SFD_NONBLOCK != O_NONBLOCK);
e38b36f325153 (Ulrich Drepper      2008-07-23 21:29:42 -0700 269) 
5fb5e04926a54 (Ulrich Drepper      2008-07-23 21:29:37 -0700 270) 	if (flags & ~(SFD_CLOEXEC | SFD_NONBLOCK))
9deb27baedb79 (Ulrich Drepper      2008-07-23 21:29:24 -0700 271) 		return -EINVAL;
9deb27baedb79 (Ulrich Drepper      2008-07-23 21:29:24 -0700 272) 
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 273) 	sigdelsetmask(mask, sigmask(SIGKILL) | sigmask(SIGSTOP));
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 274) 	signotset(mask);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 275) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 276) 	if (ufd == -1) {
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 277) 		ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 278) 		if (!ctx)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 279) 			return -ENOMEM;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 280) 
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 281) 		ctx->sigmask = *mask;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 282) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 283) 		/*
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 284) 		 * When we call this, the initialization must be complete, since
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 285) 		 * anon_inode_getfd() will install the fd.
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 286) 		 */
7d9dbca34240e (Ulrich Drepper      2008-07-23 21:29:22 -0700 287) 		ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx,
628ff7c1d8d84 (Roland Dreier       2009-12-18 09:41:24 -0800 288) 				       O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK)));
2030a42cecd4d (Al Viro             2008-02-23 06:46:49 -0500 289) 		if (ufd < 0)
2030a42cecd4d (Al Viro             2008-02-23 06:46:49 -0500 290) 			kfree(ctx);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 291) 	} else {
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400 292) 		struct fd f = fdget(ufd);
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400 293) 		if (!f.file)
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 294) 			return -EBADF;
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400 295) 		ctx = f.file->private_data;
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400 296) 		if (f.file->f_op != &signalfd_fops) {
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400 297) 			fdput(f);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 298) 			return -EINVAL;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 299) 		}
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 300) 		spin_lock_irq(&current->sighand->siglock);
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 301) 		ctx->sigmask = *mask;
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 302) 		spin_unlock_irq(&current->sighand->siglock);
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 303) 
b8fceee17a310 (Davide Libenzi      2007-09-20 12:40:16 -0700 304) 		wake_up(&current->sighand->signalfd_wqh);
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400 305) 		fdput(f);
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 306) 	}
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 307) 
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 308) 	return ufd;
fba2afaaec790 (Davide Libenzi      2007-05-10 22:23:13 -0700 309) }
9deb27baedb79 (Ulrich Drepper      2008-07-23 21:29:24 -0700 310) 
52fb6db0fd6f5 (Dominik Brodowski   2018-03-11 11:34:36 +0100 311) SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
52fb6db0fd6f5 (Dominik Brodowski   2018-03-11 11:34:36 +0100 312) 		size_t, sizemask, int, flags)
52fb6db0fd6f5 (Dominik Brodowski   2018-03-11 11:34:36 +0100 313) {
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 314) 	sigset_t mask;
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 315) 
a089e3fd5a82a (Helge Deller        2020-08-11 18:36:04 -0700 316) 	if (sizemask != sizeof(sigset_t))
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 317) 		return -EINVAL;
a089e3fd5a82a (Helge Deller        2020-08-11 18:36:04 -0700 318) 	if (copy_from_user(&mask, user_mask, sizeof(mask)))
a089e3fd5a82a (Helge Deller        2020-08-11 18:36:04 -0700 319) 		return -EFAULT;
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 320) 	return do_signalfd4(ufd, &mask, flags);
52fb6db0fd6f5 (Dominik Brodowski   2018-03-11 11:34:36 +0100 321) }
52fb6db0fd6f5 (Dominik Brodowski   2018-03-11 11:34:36 +0100 322) 
836f92adf121f (Heiko Carstens      2009-01-14 14:14:33 +0100 323) SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask,
836f92adf121f (Heiko Carstens      2009-01-14 14:14:33 +0100 324) 		size_t, sizemask)
9deb27baedb79 (Ulrich Drepper      2008-07-23 21:29:24 -0700 325) {
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 326) 	sigset_t mask;
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 327) 
a089e3fd5a82a (Helge Deller        2020-08-11 18:36:04 -0700 328) 	if (sizemask != sizeof(sigset_t))
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 329) 		return -EINVAL;
a089e3fd5a82a (Helge Deller        2020-08-11 18:36:04 -0700 330) 	if (copy_from_user(&mask, user_mask, sizeof(mask)))
a089e3fd5a82a (Helge Deller        2020-08-11 18:36:04 -0700 331) 		return -EFAULT;
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 332) 	return do_signalfd4(ufd, &mask, 0);
9deb27baedb79 (Ulrich Drepper      2008-07-23 21:29:24 -0700 333) }
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 334) 
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 335) #ifdef CONFIG_COMPAT
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 336) static long do_compat_signalfd4(int ufd,
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 337) 			const compat_sigset_t __user *user_mask,
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 338) 			compat_size_t sigsetsize, int flags)
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 339) {
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 340) 	sigset_t mask;
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 341) 
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 342) 	if (sigsetsize != sizeof(compat_sigset_t))
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 343) 		return -EINVAL;
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 344) 	if (get_compat_sigset(&mask, user_mask))
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 345) 		return -EFAULT;
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 346) 	return do_signalfd4(ufd, &mask, flags);
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 347) }
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 348) 
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 349) COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd,
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 350) 		     const compat_sigset_t __user *, user_mask,
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 351) 		     compat_size_t, sigsetsize,
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 352) 		     int, flags)
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 353) {
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 354) 	return do_compat_signalfd4(ufd, user_mask, sigsetsize, flags);
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 355) }
570484bfe813f (Dominik Brodowski   2018-03-20 19:36:46 +0100 356) 
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 357) COMPAT_SYSCALL_DEFINE3(signalfd, int, ufd,
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 358) 		     const compat_sigset_t __user *, user_mask,
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 359) 		     compat_size_t, sigsetsize)
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 360) {
5ed0127fc3619 (Al Viro             2018-05-27 08:35:50 -0400 361) 	return do_compat_signalfd4(ufd, user_mask, sigsetsize, 0);
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 362) }
7d197ed4a68e7 (Al Viro             2013-02-24 01:41:39 -0500 363) #endif