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
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    2) /*
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    3)  *  linux/fs/fcntl.c
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    4)  *
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    5)  *  Copyright (C) 1991, 1992  Linus Torvalds
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    6)  */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    7) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    8) #include <linux/syscalls.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700    9) #include <linux/init.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   10) #include <linux/mm.h>
299300258d1bc (Ingo Molnar           2017-02-08 18:51:36 +0100   11) #include <linux/sched/task.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   12) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   13) #include <linux/file.h>
9f3acc3140444 (Al Viro               2008-04-24 07:44:08 -0400   14) #include <linux/fdtable.h>
16f7e0fe2ecc3 (Randy Dunlap          2006-01-11 12:17:46 -0800   15) #include <linux/capability.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   16) #include <linux/dnotify.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   17) #include <linux/slab.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   18) #include <linux/module.h>
35f3d14dbbc58 (Jens Axboe            2010-05-20 10:43:18 +0200   19) #include <linux/pipe_fs_i.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   20) #include <linux/security.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   21) #include <linux/ptrace.h>
7ed20e1ad521b (Jesper Juhl           2005-05-01 08:59:14 -0700   22) #include <linux/signal.h>
ab2af1f500506 (Dipankar Sarma        2005-09-09 13:04:13 -0700   23) #include <linux/rcupdate.h>
b488893a390ed (Pavel Emelyanov       2007-10-18 23:40:14 -0700   24) #include <linux/pid_namespace.h>
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700   25) #include <linux/user_namespace.h>
5d752600a8c37 (Mike Kravetz          2018-06-07 17:06:01 -0700   26) #include <linux/memfd.h>
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400   27) #include <linux/compat.h>
9eccd12ce7f1c (Christian Brauner     2021-01-21 14:19:38 +0100   28) #include <linux/mount.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   29) 
cfe39442ab8ce (Al Viro               2018-02-01 12:14:57 -0500   30) #include <linux/poll.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   31) #include <asm/siginfo.h>
7c0f6ba682b9c (Linus Torvalds        2016-12-24 11:46:01 -0800   32) #include <linux/uaccess.h>
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   33) 
76398425bb06b (Jonathan Corbet       2009-02-01 14:26:59 -0700   34) #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   35) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   36) static int setfl(int fd, struct file * filp, unsigned long arg)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   37) {
496ad9aa8ef44 (Al Viro               2013-01-23 17:07:38 -0500   38) 	struct inode * inode = file_inode(filp);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   39) 	int error = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   40) 
7d95c8f27d9be (dean gaudet           2006-02-03 03:04:30 -0800   41) 	/*
7d95c8f27d9be (dean gaudet           2006-02-03 03:04:30 -0800   42) 	 * O_APPEND cannot be cleared if the file is marked as append-only
7d95c8f27d9be (dean gaudet           2006-02-03 03:04:30 -0800   43) 	 * and the file is open for write.
7d95c8f27d9be (dean gaudet           2006-02-03 03:04:30 -0800   44) 	 */
7d95c8f27d9be (dean gaudet           2006-02-03 03:04:30 -0800   45) 	if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   46) 		return -EPERM;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   47) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   48) 	/* O_NOATIME can only be set by the owner or superuser */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   49) 	if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME))
9eccd12ce7f1c (Christian Brauner     2021-01-21 14:19:38 +0100   50) 		if (!inode_owner_or_capable(file_mnt_user_ns(filp), inode))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   51) 			return -EPERM;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   52) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   53) 	/* required for strict SunOS emulation */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   54) 	if (O_NONBLOCK != O_NDELAY)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   55) 	       if (arg & O_NDELAY)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   56) 		   arg |= O_NONBLOCK;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   57) 
0dbf5f2065210 (Stanislav Kinsburskiy 2015-12-15 19:41:31 +0400   58) 	/* Pipe packetized mode is controlled by O_DIRECT flag */
450630975da9e (Al Viro               2016-12-04 18:24:56 -0500   59) 	if (!S_ISFIFO(inode->i_mode) && (arg & O_DIRECT)) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   60) 		if (!filp->f_mapping || !filp->f_mapping->a_ops ||
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   61) 			!filp->f_mapping->a_ops->direct_IO)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   62) 				return -EINVAL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   63) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   64) 
72c2d53192004 (Al Viro               2013-09-22 16:27:52 -0400   65) 	if (filp->f_op->check_flags)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   66) 		error = filp->f_op->check_flags(arg);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   67) 	if (error)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   68) 		return error;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   69) 
218d11a8b071b (Jonathan Corbet       2008-12-05 16:12:48 -0700   70) 	/*
76398425bb06b (Jonathan Corbet       2009-02-01 14:26:59 -0700   71) 	 * ->fasync() is responsible for setting the FASYNC bit.
218d11a8b071b (Jonathan Corbet       2008-12-05 16:12:48 -0700   72) 	 */
72c2d53192004 (Al Viro               2013-09-22 16:27:52 -0400   73) 	if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op->fasync) {
76398425bb06b (Jonathan Corbet       2009-02-01 14:26:59 -0700   74) 		error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
76398425bb06b (Jonathan Corbet       2009-02-01 14:26:59 -0700   75) 		if (error < 0)
76398425bb06b (Jonathan Corbet       2009-02-01 14:26:59 -0700   76) 			goto out;
60aa49243d09a (Jonathan Corbet       2009-02-01 14:52:56 -0700   77) 		if (error > 0)
60aa49243d09a (Jonathan Corbet       2009-02-01 14:52:56 -0700   78) 			error = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   79) 	}
db1dd4d376134 (Jonathan Corbet       2009-02-06 15:25:24 -0700   80) 	spin_lock(&filp->f_lock);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   81) 	filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
db1dd4d376134 (Jonathan Corbet       2009-02-06 15:25:24 -0700   82) 	spin_unlock(&filp->f_lock);
76398425bb06b (Jonathan Corbet       2009-02-01 14:26:59 -0700   83) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   84)  out:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   85) 	return error;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   86) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   87) 
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700   88) static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200   89)                      int force)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   90) {
80e1e823989ec (Linus Torvalds        2010-02-07 10:11:23 -0800   91) 	write_lock_irq(&filp->f_owner.lock);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700   92) 	if (force || !filp->f_owner.pid) {
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700   93) 		put_pid(filp->f_owner.pid);
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700   94) 		filp->f_owner.pid = get_pid(pid);
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700   95) 		filp->f_owner.pid_type = type;
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200   96) 
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200   97) 		if (pid) {
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200   98) 			const struct cred *cred = current_cred();
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200   99) 			filp->f_owner.uid = cred->uid;
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200  100) 			filp->f_owner.euid = cred->euid;
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200  101) 		}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  102) 	}
80e1e823989ec (Linus Torvalds        2010-02-07 10:11:23 -0800  103) 	write_unlock_irq(&filp->f_owner.lock);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  104) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  105) 
e0b93eddfe17d (Jeff Layton           2014-08-22 11:27:32 -0400  106) void __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  107) 		int force)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  108) {
e0b93eddfe17d (Jeff Layton           2014-08-22 11:27:32 -0400  109) 	security_file_set_fowner(filp);
2f38d70fb4e97 (Oleg Nesterov         2009-06-16 22:07:46 +0200  110) 	f_modown(filp, pid, type, force);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  111) }
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  112) EXPORT_SYMBOL(__f_setown);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  113) 
393cc3f51135e (Jiri Slaby            2017-06-13 13:35:50 +0200  114) int f_setown(struct file *filp, unsigned long arg, int force)
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  115) {
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  116) 	enum pid_type type;
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  117) 	struct pid *pid = NULL;
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  118) 	int who = arg, ret = 0;
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  119) 
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  120) 	type = PIDTYPE_TGID;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  121) 	if (who < 0) {
fc3dc67471461 (Jiri Slaby            2017-06-13 13:35:51 +0200  122) 		/* avoid overflow below */
fc3dc67471461 (Jiri Slaby            2017-06-13 13:35:51 +0200  123) 		if (who == INT_MIN)
fc3dc67471461 (Jiri Slaby            2017-06-13 13:35:51 +0200  124) 			return -EINVAL;
fc3dc67471461 (Jiri Slaby            2017-06-13 13:35:51 +0200  125) 
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  126) 		type = PIDTYPE_PGID;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  127) 		who = -who;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  128) 	}
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  129) 
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  130) 	rcu_read_lock();
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  131) 	if (who) {
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  132) 		pid = find_vpid(who);
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  133) 		if (!pid)
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  134) 			ret = -ESRCH;
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  135) 	}
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  136) 
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  137) 	if (!ret)
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  138) 		__f_setown(filp, pid, type, force);
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  139) 	rcu_read_unlock();
393cc3f51135e (Jiri Slaby            2017-06-13 13:35:50 +0200  140) 
f73127356f344 (Jeff Layton           2017-06-14 09:11:54 -0400  141) 	return ret;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  142) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  143) EXPORT_SYMBOL(f_setown);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  144) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  145) void f_delown(struct file *filp)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  146) {
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  147) 	f_modown(filp, NULL, PIDTYPE_TGID, 1);
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  148) }
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  149) 
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  150) pid_t f_getown(struct file *filp)
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  151) {
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  152) 	pid_t pid = 0;
43fa1adb9334b (Eric W. Biederman     2006-10-02 02:17:27 -0700  153) 	read_lock(&filp->f_owner.lock);
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  154) 	rcu_read_lock();
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  155) 	if (pid_task(filp->f_owner.pid, filp->f_owner.pid_type)) {
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  156) 		pid = pid_vnr(filp->f_owner.pid);
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  157) 		if (filp->f_owner.pid_type == PIDTYPE_PGID)
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  158) 			pid = -pid;
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  159) 	}
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  160) 	rcu_read_unlock();
43fa1adb9334b (Eric W. Biederman     2006-10-02 02:17:27 -0700  161) 	read_unlock(&filp->f_owner.lock);
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  162) 	return pid;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  163) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  164) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  165) static int f_setown_ex(struct file *filp, unsigned long arg)
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  166) {
63784dd02b2ac (Al Viro               2012-09-26 21:43:05 -0400  167) 	struct f_owner_ex __user *owner_p = (void __user *)arg;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  168) 	struct f_owner_ex owner;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  169) 	struct pid *pid;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  170) 	int type;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  171) 	int ret;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  172) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  173) 	ret = copy_from_user(&owner, owner_p, sizeof(owner));
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  174) 	if (ret)
5b54470daded1 (Dan Carpenter         2010-06-03 12:35:42 +0200  175) 		return -EFAULT;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  176) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  177) 	switch (owner.type) {
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  178) 	case F_OWNER_TID:
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  179) 		type = PIDTYPE_PID;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  180) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  181) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  182) 	case F_OWNER_PID:
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  183) 		type = PIDTYPE_TGID;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  184) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  185) 
978b4053aefd4 (Peter Zijlstra        2009-11-17 14:06:24 -0800  186) 	case F_OWNER_PGRP:
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  187) 		type = PIDTYPE_PGID;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  188) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  189) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  190) 	default:
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  191) 		return -EINVAL;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  192) 	}
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  193) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  194) 	rcu_read_lock();
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  195) 	pid = find_vpid(owner.pid);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  196) 	if (owner.pid && !pid)
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  197) 		ret = -ESRCH;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  198) 	else
e0b93eddfe17d (Jeff Layton           2014-08-22 11:27:32 -0400  199) 		 __f_setown(filp, pid, type, 1);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  200) 	rcu_read_unlock();
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  201) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  202) 	return ret;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  203) }
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  204) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  205) static int f_getown_ex(struct file *filp, unsigned long arg)
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  206) {
63784dd02b2ac (Al Viro               2012-09-26 21:43:05 -0400  207) 	struct f_owner_ex __user *owner_p = (void __user *)arg;
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  208) 	struct f_owner_ex owner = {};
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  209) 	int ret = 0;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  210) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  211) 	read_lock(&filp->f_owner.lock);
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  212) 	rcu_read_lock();
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  213) 	if (pid_task(filp->f_owner.pid, filp->f_owner.pid_type))
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  214) 		owner.pid = pid_vnr(filp->f_owner.pid);
cc4a3f885e8f2 (Pavel Tikhomirov      2021-02-03 15:41:56 +0300  215) 	rcu_read_unlock();
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  216) 	switch (filp->f_owner.pid_type) {
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  217) 	case PIDTYPE_PID:
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  218) 		owner.type = F_OWNER_TID;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  219) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  220) 
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  221) 	case PIDTYPE_TGID:
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  222) 		owner.type = F_OWNER_PID;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  223) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  224) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  225) 	case PIDTYPE_PGID:
978b4053aefd4 (Peter Zijlstra        2009-11-17 14:06:24 -0800  226) 		owner.type = F_OWNER_PGRP;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  227) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  228) 
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  229) 	default:
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  230) 		WARN_ON(1);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  231) 		ret = -EINVAL;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  232) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  233) 	}
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  234) 	read_unlock(&filp->f_owner.lock);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  235) 
5b54470daded1 (Dan Carpenter         2010-06-03 12:35:42 +0200  236) 	if (!ret) {
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  237) 		ret = copy_to_user(owner_p, &owner, sizeof(owner));
5b54470daded1 (Dan Carpenter         2010-06-03 12:35:42 +0200  238) 		if (ret)
5b54470daded1 (Dan Carpenter         2010-06-03 12:35:42 +0200  239) 			ret = -EFAULT;
5b54470daded1 (Dan Carpenter         2010-06-03 12:35:42 +0200  240) 	}
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  241) 	return ret;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  242) }
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  243) 
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  244) #ifdef CONFIG_CHECKPOINT_RESTORE
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  245) static int f_getowner_uids(struct file *filp, unsigned long arg)
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  246) {
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  247) 	struct user_namespace *user_ns = current_user_ns();
63784dd02b2ac (Al Viro               2012-09-26 21:43:05 -0400  248) 	uid_t __user *dst = (void __user *)arg;
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  249) 	uid_t src[2];
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  250) 	int err;
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  251) 
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  252) 	read_lock(&filp->f_owner.lock);
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  253) 	src[0] = from_kuid(user_ns, filp->f_owner.uid);
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  254) 	src[1] = from_kuid(user_ns, filp->f_owner.euid);
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  255) 	read_unlock(&filp->f_owner.lock);
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  256) 
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  257) 	err  = put_user(src[0], &dst[0]);
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  258) 	err |= put_user(src[1], &dst[1]);
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  259) 
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  260) 	return err;
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  261) }
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  262) #else
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  263) static int f_getowner_uids(struct file *filp, unsigned long arg)
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  264) {
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  265) 	return -EINVAL;
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  266) }
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  267) #endif
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  268) 
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  269) static bool rw_hint_valid(enum rw_hint hint)
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  270) {
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  271) 	switch (hint) {
9a7f12edf8848 (Eugene Syromiatnikov  2019-09-20 17:58:21 +0200  272) 	case RWH_WRITE_LIFE_NOT_SET:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  273) 	case RWH_WRITE_LIFE_NONE:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  274) 	case RWH_WRITE_LIFE_SHORT:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  275) 	case RWH_WRITE_LIFE_MEDIUM:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  276) 	case RWH_WRITE_LIFE_LONG:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  277) 	case RWH_WRITE_LIFE_EXTREME:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  278) 		return true;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  279) 	default:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  280) 		return false;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  281) 	}
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  282) }
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  283) 
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  284) static long fcntl_rw_hint(struct file *file, unsigned int cmd,
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  285) 			  unsigned long arg)
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  286) {
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  287) 	struct inode *inode = file_inode(file);
e200327708e69 (Ben Dooks             2019-10-15 11:50:49 +0100  288) 	u64 __user *argp = (u64 __user *)arg;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  289) 	enum rw_hint hint;
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  290) 	u64 h;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  291) 
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  292) 	switch (cmd) {
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  293) 	case F_GET_FILE_RW_HINT:
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  294) 		h = file_write_hint(file);
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  295) 		if (copy_to_user(argp, &h, sizeof(*argp)))
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  296) 			return -EFAULT;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  297) 		return 0;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  298) 	case F_SET_FILE_RW_HINT:
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  299) 		if (copy_from_user(&h, argp, sizeof(h)))
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  300) 			return -EFAULT;
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  301) 		hint = (enum rw_hint) h;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  302) 		if (!rw_hint_valid(hint))
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  303) 			return -EINVAL;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  304) 
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  305) 		spin_lock(&file->f_lock);
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  306) 		file->f_write_hint = hint;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  307) 		spin_unlock(&file->f_lock);
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  308) 		return 0;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  309) 	case F_GET_RW_HINT:
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  310) 		h = inode->i_write_hint;
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  311) 		if (copy_to_user(argp, &h, sizeof(*argp)))
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  312) 			return -EFAULT;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  313) 		return 0;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  314) 	case F_SET_RW_HINT:
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  315) 		if (copy_from_user(&h, argp, sizeof(h)))
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  316) 			return -EFAULT;
5657cb0797c4a (Jens Axboe            2017-06-28 08:09:45 -0600  317) 		hint = (enum rw_hint) h;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  318) 		if (!rw_hint_valid(hint))
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  319) 			return -EINVAL;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  320) 
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  321) 		inode_lock(inode);
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  322) 		inode->i_write_hint = hint;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  323) 		inode_unlock(inode);
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  324) 		return 0;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  325) 	default:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  326) 		return -EINVAL;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  327) 	}
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  328) }
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  329) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  330) static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  331) 		struct file *filp)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  332) {
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  333) 	void __user *argp = (void __user *)arg;
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  334) 	struct flock flock;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  335) 	long err = -EINVAL;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  336) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  337) 	switch (cmd) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  338) 	case F_DUPFD:
fe17f22d7fd0e (Al Viro               2012-08-21 11:48:11 -0400  339) 		err = f_dupfd(arg, filp, 0);
fe17f22d7fd0e (Al Viro               2012-08-21 11:48:11 -0400  340) 		break;
22d2b35b200f7 (Ulrich Drepper        2007-10-16 23:30:26 -0700  341) 	case F_DUPFD_CLOEXEC:
121977187ca0a (Al Viro               2012-10-08 23:21:58 +0100  342) 		err = f_dupfd(arg, filp, O_CLOEXEC);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  343) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  344) 	case F_GETFD:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  345) 		err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  346) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  347) 	case F_SETFD:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  348) 		err = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  349) 		set_close_on_exec(fd, arg & FD_CLOEXEC);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  350) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  351) 	case F_GETFL:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  352) 		err = filp->f_flags;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  353) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  354) 	case F_SETFL:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  355) 		err = setfl(fd, filp, arg);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  356) 		break;
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  357) #if BITS_PER_LONG != 32
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  358) 	/* 32-bit arches must use fcntl64() */
0d3f7a2dd2f5c (Jeff Layton           2014-04-22 08:23:58 -0400  359) 	case F_OFD_GETLK:
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  360) #endif
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  361) 	case F_GETLK:
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  362) 		if (copy_from_user(&flock, argp, sizeof(flock)))
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  363) 			return -EFAULT;
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  364) 		err = fcntl_getlk(filp, cmd, &flock);
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  365) 		if (!err && copy_to_user(argp, &flock, sizeof(flock)))
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  366) 			return -EFAULT;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  367) 		break;
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  368) #if BITS_PER_LONG != 32
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  369) 	/* 32-bit arches must use fcntl64() */
0d3f7a2dd2f5c (Jeff Layton           2014-04-22 08:23:58 -0400  370) 	case F_OFD_SETLK:
0d3f7a2dd2f5c (Jeff Layton           2014-04-22 08:23:58 -0400  371) 	case F_OFD_SETLKW:
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  372) #endif
df561f6688fef (Gustavo A. R. Silva   2020-08-23 17:36:59 -0500  373) 		fallthrough;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  374) 	case F_SETLK:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  375) 	case F_SETLKW:
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  376) 		if (copy_from_user(&flock, argp, sizeof(flock)))
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  377) 			return -EFAULT;
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  378) 		err = fcntl_setlk(fd, filp, cmd, &flock);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  379) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  380) 	case F_GETOWN:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  381) 		/*
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  382) 		 * XXX If f_owner is a process group, the
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  383) 		 * negative return value will get converted
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  384) 		 * into an error.  Oops.  If we keep the
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  385) 		 * current syscall conventions, the only way
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  386) 		 * to fix this will be in libc.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  387) 		 */
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  388) 		err = f_getown(filp);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  389) 		force_successful_syscall_return();
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  390) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  391) 	case F_SETOWN:
393cc3f51135e (Jiri Slaby            2017-06-13 13:35:50 +0200  392) 		err = f_setown(filp, arg, 1);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  393) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  394) 	case F_GETOWN_EX:
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  395) 		err = f_getown_ex(filp, arg);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  396) 		break;
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  397) 	case F_SETOWN_EX:
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  398) 		err = f_setown_ex(filp, arg);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  399) 		break;
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  400) 	case F_GETOWNER_UIDS:
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  401) 		err = f_getowner_uids(filp, arg);
1d151c337d79f (Cyrill Gorcunov       2012-07-30 14:43:00 -0700  402) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  403) 	case F_GETSIG:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  404) 		err = filp->f_owner.signum;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  405) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  406) 	case F_SETSIG:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  407) 		/* arg == 0 restores default behaviour. */
7ed20e1ad521b (Jesper Juhl           2005-05-01 08:59:14 -0700  408) 		if (!valid_signal(arg)) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  409) 			break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  410) 		}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  411) 		err = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  412) 		filp->f_owner.signum = arg;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  413) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  414) 	case F_GETLEASE:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  415) 		err = fcntl_getlease(filp);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  416) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  417) 	case F_SETLEASE:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  418) 		err = fcntl_setlease(fd, filp, arg);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  419) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  420) 	case F_NOTIFY:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  421) 		err = fcntl_dirnotify(fd, filp, arg);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  422) 		break;
35f3d14dbbc58 (Jens Axboe            2010-05-20 10:43:18 +0200  423) 	case F_SETPIPE_SZ:
35f3d14dbbc58 (Jens Axboe            2010-05-20 10:43:18 +0200  424) 	case F_GETPIPE_SZ:
35f3d14dbbc58 (Jens Axboe            2010-05-20 10:43:18 +0200  425) 		err = pipe_fcntl(filp, cmd, arg);
35f3d14dbbc58 (Jens Axboe            2010-05-20 10:43:18 +0200  426) 		break;
40e041a2c858b (David Rheinsberg      2014-08-08 14:25:27 -0700  427) 	case F_ADD_SEALS:
40e041a2c858b (David Rheinsberg      2014-08-08 14:25:27 -0700  428) 	case F_GET_SEALS:
5aadc431a593a (Marc-André Lureau     2018-01-31 16:19:18 -0800  429) 		err = memfd_fcntl(filp, cmd, arg);
40e041a2c858b (David Rheinsberg      2014-08-08 14:25:27 -0700  430) 		break;
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  431) 	case F_GET_RW_HINT:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  432) 	case F_SET_RW_HINT:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  433) 	case F_GET_FILE_RW_HINT:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  434) 	case F_SET_FILE_RW_HINT:
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  435) 		err = fcntl_rw_hint(filp, cmd, arg);
c75b1d9421f80 (Jens Axboe            2017-06-27 11:47:04 -0600  436) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  437) 	default:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  438) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  439) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  440) 	return err;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  441) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  442) 
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  443) static int check_fcntl_cmd(unsigned cmd)
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  444) {
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  445) 	switch (cmd) {
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  446) 	case F_DUPFD:
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  447) 	case F_DUPFD_CLOEXEC:
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  448) 	case F_GETFD:
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  449) 	case F_SETFD:
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  450) 	case F_GETFL:
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  451) 		return 1;
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  452) 	}
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  453) 	return 0;
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  454) }
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  455) 
a26eab2400f04 (Heiko Carstens        2009-01-14 14:14:17 +0100  456) SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  457) {	
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  458) 	struct fd f = fdget_raw(fd);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  459) 	long err = -EBADF;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  460) 
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  461) 	if (!f.file)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  462) 		goto out;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  463) 
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  464) 	if (unlikely(f.file->f_mode & FMODE_PATH)) {
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  465) 		if (!check_fcntl_cmd(cmd))
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  466) 			goto out1;
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  467) 	}
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  468) 
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  469) 	err = security_file_fcntl(f.file, cmd, arg);
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  470) 	if (!err)
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  471) 		err = do_fcntl(fd, cmd, arg, f.file);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  472) 
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  473) out1:
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  474)  	fdput(f);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  475) out:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  476) 	return err;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  477) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  478) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  479) #if BITS_PER_LONG == 32
a26eab2400f04 (Heiko Carstens        2009-01-14 14:14:17 +0100  480) SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
a26eab2400f04 (Heiko Carstens        2009-01-14 14:14:17 +0100  481) 		unsigned long, arg)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  482) {	
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  483) 	void __user *argp = (void __user *)arg;
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  484) 	struct fd f = fdget_raw(fd);
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  485) 	struct flock64 flock;
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  486) 	long err = -EBADF;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  487) 
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  488) 	if (!f.file)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  489) 		goto out;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  490) 
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  491) 	if (unlikely(f.file->f_mode & FMODE_PATH)) {
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  492) 		if (!check_fcntl_cmd(cmd))
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  493) 			goto out1;
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  494) 	}
1abf0c718f15a (Al Viro               2011-03-13 03:51:11 -0400  495) 
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  496) 	err = security_file_fcntl(f.file, cmd, arg);
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  497) 	if (err)
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  498) 		goto out1;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  499) 	
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  500) 	switch (cmd) {
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  501) 	case F_GETLK64:
0d3f7a2dd2f5c (Jeff Layton           2014-04-22 08:23:58 -0400  502) 	case F_OFD_GETLK:
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  503) 		err = -EFAULT;
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  504) 		if (copy_from_user(&flock, argp, sizeof(flock)))
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  505) 			break;
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  506) 		err = fcntl_getlk64(f.file, cmd, &flock);
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  507) 		if (!err && copy_to_user(argp, &flock, sizeof(flock)))
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  508) 			err = -EFAULT;
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  509) 		break;
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  510) 	case F_SETLK64:
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  511) 	case F_SETLKW64:
0d3f7a2dd2f5c (Jeff Layton           2014-04-22 08:23:58 -0400  512) 	case F_OFD_SETLK:
0d3f7a2dd2f5c (Jeff Layton           2014-04-22 08:23:58 -0400  513) 	case F_OFD_SETLKW:
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  514) 		err = -EFAULT;
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  515) 		if (copy_from_user(&flock, argp, sizeof(flock)))
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  516) 			break;
a75d30c772078 (Christoph Hellwig     2017-05-27 06:07:19 -0400  517) 		err = fcntl_setlk64(fd, f.file, cmd, &flock);
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  518) 		break;
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  519) 	default:
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  520) 		err = do_fcntl(fd, cmd, arg, f.file);
5d50ffd7c31da (Jeff Layton           2014-02-03 12:13:10 -0500  521) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  522) 	}
545ec2c7945bf (Al Viro               2012-04-21 18:42:19 -0400  523) out1:
2903ff019b346 (Al Viro               2012-08-28 12:52:22 -0400  524) 	fdput(f);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  525) out:
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  526) 	return err;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  527) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  528) #endif
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  529) 
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  530) #ifdef CONFIG_COMPAT
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  531) /* careful - don't use anywhere else */
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  532) #define copy_flock_fields(dst, src)		\
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  533) 	(dst)->l_type = (src)->l_type;		\
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  534) 	(dst)->l_whence = (src)->l_whence;	\
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  535) 	(dst)->l_start = (src)->l_start;	\
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  536) 	(dst)->l_len = (src)->l_len;		\
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  537) 	(dst)->l_pid = (src)->l_pid;
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  538) 
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  539) static int get_compat_flock(struct flock *kfl, const struct compat_flock __user *ufl)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  540) {
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  541) 	struct compat_flock fl;
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  542) 
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  543) 	if (copy_from_user(&fl, ufl, sizeof(struct compat_flock)))
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  544) 		return -EFAULT;
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  545) 	copy_flock_fields(kfl, &fl);
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  546) 	return 0;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  547) }
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  548) 
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  549) static int get_compat_flock64(struct flock *kfl, const struct compat_flock64 __user *ufl)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  550) {
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  551) 	struct compat_flock64 fl;
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  552) 
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  553) 	if (copy_from_user(&fl, ufl, sizeof(struct compat_flock64)))
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  554) 		return -EFAULT;
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  555) 	copy_flock_fields(kfl, &fl);
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  556) 	return 0;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  557) }
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  558) 
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  559) static int put_compat_flock(const struct flock *kfl, struct compat_flock __user *ufl)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  560) {
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  561) 	struct compat_flock fl;
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  562) 
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  563) 	memset(&fl, 0, sizeof(struct compat_flock));
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  564) 	copy_flock_fields(&fl, kfl);
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  565) 	if (copy_to_user(ufl, &fl, sizeof(struct compat_flock)))
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  566) 		return -EFAULT;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  567) 	return 0;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  568) }
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  569) 
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  570) static int put_compat_flock64(const struct flock *kfl, struct compat_flock64 __user *ufl)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  571) {
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  572) 	struct compat_flock64 fl;
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  573) 
4d2dc2cc766c3 (Jeff Layton           2017-11-14 14:42:57 -0500  574) 	BUILD_BUG_ON(sizeof(kfl->l_start) > sizeof(ufl->l_start));
4d2dc2cc766c3 (Jeff Layton           2017-11-14 14:42:57 -0500  575) 	BUILD_BUG_ON(sizeof(kfl->l_len) > sizeof(ufl->l_len));
4d2dc2cc766c3 (Jeff Layton           2017-11-14 14:42:57 -0500  576) 
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  577) 	memset(&fl, 0, sizeof(struct compat_flock64));
b59eea554f57b (Linus Torvalds        2017-07-07 13:48:18 -0700  578) 	copy_flock_fields(&fl, kfl);
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  579) 	if (copy_to_user(ufl, &fl, sizeof(struct compat_flock64)))
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  580) 		return -EFAULT;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  581) 	return 0;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  582) }
8c6657cb50cb0 (Al Viro               2017-06-26 23:51:31 -0400  583) #undef copy_flock_fields
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  584) 
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  585) static unsigned int
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  586) convert_fcntl_cmd(unsigned int cmd)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  587) {
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  588) 	switch (cmd) {
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  589) 	case F_GETLK64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  590) 		return F_GETLK;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  591) 	case F_SETLK64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  592) 		return F_SETLK;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  593) 	case F_SETLKW64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  594) 		return F_SETLKW;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  595) 	}
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  596) 
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  597) 	return cmd;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  598) }
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  599) 
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  600) /*
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  601)  * GETLK was successful and we need to return the data, but it needs to fit in
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  602)  * the compat structure.
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  603)  * l_start shouldn't be too big, unless the original start + end is greater than
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  604)  * COMPAT_OFF_T_MAX, in which case the app was asking for trouble, so we return
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  605)  * -EOVERFLOW in that case.  l_len could be too big, in which case we just
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  606)  * truncate it, and only allow the app to see that part of the conflicting lock
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  607)  * that might make sense to it anyway
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  608)  */
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  609) static int fixup_compat_flock(struct flock *flock)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  610) {
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  611) 	if (flock->l_start > COMPAT_OFF_T_MAX)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  612) 		return -EOVERFLOW;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  613) 	if (flock->l_len > COMPAT_OFF_T_MAX)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  614) 		flock->l_len = COMPAT_OFF_T_MAX;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  615) 	return 0;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  616) }
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  617) 
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  618) static long do_compat_fcntl64(unsigned int fd, unsigned int cmd,
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  619) 			     compat_ulong_t arg)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  620) {
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  621) 	struct fd f = fdget_raw(fd);
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  622) 	struct flock flock;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  623) 	long err = -EBADF;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  624) 
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  625) 	if (!f.file)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  626) 		return err;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  627) 
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  628) 	if (unlikely(f.file->f_mode & FMODE_PATH)) {
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  629) 		if (!check_fcntl_cmd(cmd))
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  630) 			goto out_put;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  631) 	}
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  632) 
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  633) 	err = security_file_fcntl(f.file, cmd, arg);
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  634) 	if (err)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  635) 		goto out_put;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  636) 
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  637) 	switch (cmd) {
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  638) 	case F_GETLK:
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  639) 		err = get_compat_flock(&flock, compat_ptr(arg));
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  640) 		if (err)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  641) 			break;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  642) 		err = fcntl_getlk(f.file, convert_fcntl_cmd(cmd), &flock);
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  643) 		if (err)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  644) 			break;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  645) 		err = fixup_compat_flock(&flock);
9280a601e6080 (Jeff Layton           2017-11-14 14:43:56 -0500  646) 		if (!err)
9280a601e6080 (Jeff Layton           2017-11-14 14:43:56 -0500  647) 			err = put_compat_flock(&flock, compat_ptr(arg));
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  648) 		break;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  649) 	case F_GETLK64:
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  650) 	case F_OFD_GETLK:
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  651) 		err = get_compat_flock64(&flock, compat_ptr(arg));
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  652) 		if (err)
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  653) 			break;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  654) 		err = fcntl_getlk(f.file, convert_fcntl_cmd(cmd), &flock);
4d2dc2cc766c3 (Jeff Layton           2017-11-14 14:42:57 -0500  655) 		if (!err)
4d2dc2cc766c3 (Jeff Layton           2017-11-14 14:42:57 -0500  656) 			err = put_compat_flock64(&flock, compat_ptr(arg));
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  657) 		break;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  658) 	case F_SETLK:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  659) 	case F_SETLKW:
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  660) 		err = get_compat_flock(&flock, compat_ptr(arg));
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  661) 		if (err)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  662) 			break;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  663) 		err = fcntl_setlk(fd, f.file, convert_fcntl_cmd(cmd), &flock);
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  664) 		break;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  665) 	case F_SETLK64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  666) 	case F_SETLKW64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  667) 	case F_OFD_SETLK:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  668) 	case F_OFD_SETLKW:
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  669) 		err = get_compat_flock64(&flock, compat_ptr(arg));
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  670) 		if (err)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  671) 			break;
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  672) 		err = fcntl_setlk(fd, f.file, convert_fcntl_cmd(cmd), &flock);
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  673) 		break;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  674) 	default:
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  675) 		err = do_fcntl(fd, cmd, arg, f.file);
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  676) 		break;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  677) 	}
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  678) out_put:
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  679) 	fdput(f);
94073ad77fff2 (Christoph Hellwig     2017-05-27 06:07:20 -0400  680) 	return err;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  681) }
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  682) 
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  683) COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  684) 		       compat_ulong_t, arg)
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  685) {
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  686) 	return do_compat_fcntl64(fd, cmd, arg);
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  687) }
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  688) 
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  689) COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  690) 		       compat_ulong_t, arg)
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  691) {
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  692) 	switch (cmd) {
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  693) 	case F_GETLK64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  694) 	case F_SETLK64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  695) 	case F_SETLKW64:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  696) 	case F_OFD_GETLK:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  697) 	case F_OFD_SETLK:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  698) 	case F_OFD_SETLKW:
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  699) 		return -EINVAL;
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  700) 	}
e02af2ff65480 (Dominik Brodowski     2018-03-20 19:29:53 +0100  701) 	return do_compat_fcntl64(fd, cmd, arg);
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  702) }
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  703) #endif
80f0cce6aadeb (Al Viro               2017-04-08 18:10:56 -0400  704) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  705) /* Table to convert sigio signal codes into poll band bitmaps */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  706) 
5dc533c66b131 (Al Viro               2017-07-16 22:14:00 -0400  707) static const __poll_t band_table[NSIGPOLL] = {
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  708) 	EPOLLIN | EPOLLRDNORM,			/* POLL_IN */
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  709) 	EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND,	/* POLL_OUT */
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  710) 	EPOLLIN | EPOLLRDNORM | EPOLLMSG,		/* POLL_MSG */
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  711) 	EPOLLERR,				/* POLL_ERR */
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  712) 	EPOLLPRI | EPOLLRDBAND,			/* POLL_PRI */
a9a08845e9acb (Linus Torvalds        2018-02-11 14:34:03 -0800  713) 	EPOLLHUP | EPOLLERR			/* POLL_HUP */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  714) };
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  715) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  716) static inline int sigio_perm(struct task_struct *p,
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  717)                              struct fown_struct *fown, int sig)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  718) {
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  719) 	const struct cred *cred;
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  720) 	int ret;
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  721) 
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  722) 	rcu_read_lock();
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  723) 	cred = __task_cred(p);
8e96e3b7b8407 (Eric W. Biederman     2012-03-03 21:17:15 -0800  724) 	ret = ((uid_eq(fown->euid, GLOBAL_ROOT_UID) ||
8e96e3b7b8407 (Eric W. Biederman     2012-03-03 21:17:15 -0800  725) 		uid_eq(fown->euid, cred->suid) || uid_eq(fown->euid, cred->uid) ||
8e96e3b7b8407 (Eric W. Biederman     2012-03-03 21:17:15 -0800  726) 		uid_eq(fown->uid,  cred->suid) || uid_eq(fown->uid,  cred->uid)) &&
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  727) 	       !security_file_send_sigiotask(p, fown, sig));
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  728) 	rcu_read_unlock();
c69e8d9c01db2 (David Howells         2008-11-14 10:39:19 +1100  729) 	return ret;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  730) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  731) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  732) static void send_sigio_to_task(struct task_struct *p,
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  733) 			       struct fown_struct *fown,
9c2db007787ef (Eric W. Biederman     2018-07-21 08:17:29 -0500  734) 			       int fd, int reason, enum pid_type type)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  735) {
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  736) 	/*
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  737) 	 * F_SETSIG can change ->signum lockless in parallel, make
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  738) 	 * sure we read it once and use the same value throughout.
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  739) 	 */
6aa7de059173a (Mark Rutland          2017-10-23 14:07:29 -0700  740) 	int signum = READ_ONCE(fown->signum);
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  741) 
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  742) 	if (!sigio_perm(p, fown, signum))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  743) 		return;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  744) 
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  745) 	switch (signum) {
0a68ff5e2e7cf (Kees Cook             2020-02-19 22:22:43 -0800  746) 		default: {
0a68ff5e2e7cf (Kees Cook             2020-02-19 22:22:43 -0800  747) 			kernel_siginfo_t si;
0a68ff5e2e7cf (Kees Cook             2020-02-19 22:22:43 -0800  748) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  749) 			/* Queue a rt signal with the appropriate fd as its
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  750) 			   value.  We use SI_SIGIO as the source, not 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  751) 			   SI_KERNEL, since kernel signals always get 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  752) 			   delivered even if we can't queue.  Failure to
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  753) 			   queue in this case _should_ be reported; we fall
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  754) 			   back to SIGIO in that case. --sct */
faf1f22b61f27 (Eric W. Biederman     2018-01-05 17:27:42 -0600  755) 			clear_siginfo(&si);
8eeee4e2f04fc (Oleg Nesterov         2009-06-17 00:27:10 +0200  756) 			si.si_signo = signum;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  757) 			si.si_errno = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  758) 		        si.si_code  = reason;
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  759) 			/*
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  760) 			 * Posix definies POLL_IN and friends to be signal
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  761) 			 * specific si_codes for SIG_POLL.  Linux extended
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  762) 			 * these si_codes to other signals in a way that is
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  763) 			 * ambiguous if other signals also have signal
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  764) 			 * specific si_codes.  In that case use SI_SIGIO instead
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  765) 			 * to remove the ambiguity.
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  766) 			 */
54640d238760a (Eric W. Biederman     2017-09-18 22:51:14 -0500  767) 			if ((signum != SIGPOLL) && sig_specific_sicodes(signum))
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  768) 				si.si_code = SI_SIGIO;
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  769) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  770) 			/* Make sure we are called with one of the POLL_*
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  771) 			   reasons, otherwise we could leak kernel stack into
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  772) 			   userspace.  */
d08477aa975e9 (Eric W. Biederman     2017-06-29 09:28:50 -0500  773) 			BUG_ON((reason < POLL_IN) || ((reason - POLL_IN) >= NSIGPOLL));
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  774) 			if (reason - POLL_IN >= NSIGPOLL)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  775) 				si.si_band  = ~0L;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  776) 			else
c71d227fc4133 (Al Viro               2017-11-29 19:00:41 -0500  777) 				si.si_band = mangle_poll(band_table[reason - POLL_IN]);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  778) 			si.si_fd    = fd;
40b3b02535621 (Eric W. Biederman     2018-07-21 10:45:15 -0500  779) 			if (!do_send_sig_info(signum, &si, p, type))
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  780) 				break;
0a68ff5e2e7cf (Kees Cook             2020-02-19 22:22:43 -0800  781) 		}
df561f6688fef (Gustavo A. R. Silva   2020-08-23 17:36:59 -0500  782) 			fallthrough;	/* fall back on the old plain SIGIO signal */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  783) 		case 0:
40b3b02535621 (Eric W. Biederman     2018-07-21 10:45:15 -0500  784) 			do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, type);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  785) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  786) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  787) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  788) void send_sigio(struct fown_struct *fown, int fd, int band)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  789) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  790) 	struct task_struct *p;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  791) 	enum pid_type type;
8d1ddb5e79374 (Boqun Feng            2020-11-05 14:23:51 +0800  792) 	unsigned long flags;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  793) 	struct pid *pid;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  794) 	
8d1ddb5e79374 (Boqun Feng            2020-11-05 14:23:51 +0800  795) 	read_lock_irqsave(&fown->lock, flags);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  796) 
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  797) 	type = fown->pid_type;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  798) 	pid = fown->pid;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  799) 	if (!pid)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  800) 		goto out_unlock_fown;
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  801) 
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  802) 	if (type <= PIDTYPE_TGID) {
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  803) 		rcu_read_lock();
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  804) 		p = pid_task(pid, PIDTYPE_PID);
84fe4cc09abc1 (Eric W. Biederman     2018-08-15 21:20:46 -0500  805) 		if (p)
84fe4cc09abc1 (Eric W. Biederman     2018-08-15 21:20:46 -0500  806) 			send_sigio_to_task(p, fown, fd, band, type);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  807) 		rcu_read_unlock();
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  808) 	} else {
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  809) 		read_lock(&tasklist_lock);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  810) 		do_each_pid_task(pid, type, p) {
9c2db007787ef (Eric W. Biederman     2018-07-21 08:17:29 -0500  811) 			send_sigio_to_task(p, fown, fd, band, type);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  812) 		} while_each_pid_task(pid, type, p);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  813) 		read_unlock(&tasklist_lock);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  814) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  815)  out_unlock_fown:
8d1ddb5e79374 (Boqun Feng            2020-11-05 14:23:51 +0800  816) 	read_unlock_irqrestore(&fown->lock, flags);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  817) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  818) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  819) static void send_sigurg_to_task(struct task_struct *p,
9c2db007787ef (Eric W. Biederman     2018-07-21 08:17:29 -0500  820) 				struct fown_struct *fown, enum pid_type type)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  821) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  822) 	if (sigio_perm(p, fown, SIGURG))
40b3b02535621 (Eric W. Biederman     2018-07-21 10:45:15 -0500  823) 		do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, type);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  824) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  825) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  826) int send_sigurg(struct fown_struct *fown)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  827) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  828) 	struct task_struct *p;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  829) 	enum pid_type type;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  830) 	struct pid *pid;
8d1ddb5e79374 (Boqun Feng            2020-11-05 14:23:51 +0800  831) 	unsigned long flags;
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  832) 	int ret = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  833) 	
8d1ddb5e79374 (Boqun Feng            2020-11-05 14:23:51 +0800  834) 	read_lock_irqsave(&fown->lock, flags);
ba0a6c9f6fcee (Peter Zijlstra        2009-09-23 15:57:03 -0700  835) 
609d7fa9565c7 (Eric W. Biederman     2006-10-02 02:17:15 -0700  836) 	type = fown->pid_type;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  837) 	pid = fown->pid;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  838) 	if (!pid)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  839) 		goto out_unlock_fown;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  840) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  841) 	ret = 1;
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  842) 
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  843) 	if (type <= PIDTYPE_TGID) {
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  844) 		rcu_read_lock();
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  845) 		p = pid_task(pid, PIDTYPE_PID);
84fe4cc09abc1 (Eric W. Biederman     2018-08-15 21:20:46 -0500  846) 		if (p)
84fe4cc09abc1 (Eric W. Biederman     2018-08-15 21:20:46 -0500  847) 			send_sigurg_to_task(p, fown, type);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  848) 		rcu_read_unlock();
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  849) 	} else {
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  850) 		read_lock(&tasklist_lock);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  851) 		do_each_pid_task(pid, type, p) {
9c2db007787ef (Eric W. Biederman     2018-07-21 08:17:29 -0500  852) 			send_sigurg_to_task(p, fown, type);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  853) 		} while_each_pid_task(pid, type, p);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  854) 		read_unlock(&tasklist_lock);
019191342fecc (Eric W. Biederman     2017-07-16 22:05:57 -0500  855) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  856)  out_unlock_fown:
8d1ddb5e79374 (Boqun Feng            2020-11-05 14:23:51 +0800  857) 	read_unlock_irqrestore(&fown->lock, flags);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  858) 	return ret;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  859) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  860) 
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  861) static DEFINE_SPINLOCK(fasync_lock);
e18b890bb0881 (Christoph Lameter     2006-12-06 20:33:20 -0800  862) static struct kmem_cache *fasync_cache __read_mostly;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  863) 
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  864) static void fasync_free_rcu(struct rcu_head *head)
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  865) {
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  866) 	kmem_cache_free(fasync_cache,
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  867) 			container_of(head, struct fasync_struct, fa_rcu));
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  868) }
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  869) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  870) /*
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  871)  * Remove a fasync entry. If successfully removed, return
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  872)  * positive and clear the FASYNC flag. If no entry exists,
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  873)  * do nothing and return 0.
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  874)  *
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  875)  * NOTE! It is very important that the FASYNC flag always
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  876)  * match the state "is the filp on a fasync list".
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  877)  *
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  878)  */
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  879) int fasync_remove_entry(struct file *filp, struct fasync_struct **fapp)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  880) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  881) 	struct fasync_struct *fa, **fp;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  882) 	int result = 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  883) 
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  884) 	spin_lock(&filp->f_lock);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  885) 	spin_lock(&fasync_lock);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  886) 	for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  887) 		if (fa->fa_file != filp)
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  888) 			continue;
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  889) 
7a107c0f55a3b (Kirill Tkhai          2018-04-05 14:58:06 +0300  890) 		write_lock_irq(&fa->fa_lock);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  891) 		fa->fa_file = NULL;
7a107c0f55a3b (Kirill Tkhai          2018-04-05 14:58:06 +0300  892) 		write_unlock_irq(&fa->fa_lock);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  893) 
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  894) 		*fp = fa->fa_next;
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  895) 		call_rcu(&fa->fa_rcu, fasync_free_rcu);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  896) 		filp->f_flags &= ~FASYNC;
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  897) 		result = 1;
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  898) 		break;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  899) 	}
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  900) 	spin_unlock(&fasync_lock);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  901) 	spin_unlock(&filp->f_lock);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  902) 	return result;
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  903) }
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  904) 
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  905) struct fasync_struct *fasync_alloc(void)
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  906) {
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  907) 	return kmem_cache_alloc(fasync_cache, GFP_KERNEL);
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  908) }
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  909) 
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  910) /*
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  911)  * NOTE! This can be used only for unused fasync entries:
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  912)  * entries that actually got inserted on the fasync list
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  913)  * need to be released by rcu - see fasync_remove_entry.
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  914)  */
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  915) void fasync_free(struct fasync_struct *new)
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  916) {
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  917) 	kmem_cache_free(fasync_cache, new);
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  918) }
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  919) 
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  920) /*
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  921)  * Insert a new entry into the fasync list.  Return the pointer to the
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  922)  * old one if we didn't use the new one.
55f335a8857db (Linus Torvalds        2010-10-27 18:17:02 -0700  923)  *
55f335a8857db (Linus Torvalds        2010-10-27 18:17:02 -0700  924)  * NOTE! It is very important that the FASYNC flag always
55f335a8857db (Linus Torvalds        2010-10-27 18:17:02 -0700  925)  * match the state "is the filp on a fasync list".
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  926)  */
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  927) struct fasync_struct *fasync_insert_entry(int fd, struct file *filp, struct fasync_struct **fapp, struct fasync_struct *new)
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  928) {
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  929)         struct fasync_struct *fa, **fp;
4a6a4499693a4 (Jonathan Corbet       2009-03-27 12:24:31 -0600  930) 
4a6a4499693a4 (Jonathan Corbet       2009-03-27 12:24:31 -0600  931) 	spin_lock(&filp->f_lock);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  932) 	spin_lock(&fasync_lock);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  933) 	for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  934) 		if (fa->fa_file != filp)
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  935) 			continue;
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  936) 
7a107c0f55a3b (Kirill Tkhai          2018-04-05 14:58:06 +0300  937) 		write_lock_irq(&fa->fa_lock);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  938) 		fa->fa_fd = fd;
7a107c0f55a3b (Kirill Tkhai          2018-04-05 14:58:06 +0300  939) 		write_unlock_irq(&fa->fa_lock);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  940) 		goto out;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  941) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  942) 
7a107c0f55a3b (Kirill Tkhai          2018-04-05 14:58:06 +0300  943) 	rwlock_init(&new->fa_lock);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  944) 	new->magic = FASYNC_MAGIC;
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  945) 	new->fa_file = filp;
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  946) 	new->fa_fd = fd;
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  947) 	new->fa_next = *fapp;
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  948) 	rcu_assign_pointer(*fapp, new);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  949) 	filp->f_flags |= FASYNC;
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  950) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  951) out:
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  952) 	spin_unlock(&fasync_lock);
4a6a4499693a4 (Jonathan Corbet       2009-03-27 12:24:31 -0600  953) 	spin_unlock(&filp->f_lock);
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  954) 	return fa;
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  955) }
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  956) 
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  957) /*
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  958)  * Add a fasync entry. Return negative on error, positive if
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  959)  * added, and zero if did nothing but change an existing one.
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  960)  */
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  961) static int fasync_add_entry(int fd, struct file *filp, struct fasync_struct **fapp)
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  962) {
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  963) 	struct fasync_struct *new;
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  964) 
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  965) 	new = fasync_alloc();
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  966) 	if (!new)
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  967) 		return -ENOMEM;
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  968) 
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  969) 	/*
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  970) 	 * fasync_insert_entry() returns the old (update) entry if
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  971) 	 * it existed.
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  972) 	 *
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  973) 	 * So free the (unused) new entry and return 0 to let the
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  974) 	 * caller know that we didn't add any new fasync entries.
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  975) 	 */
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  976) 	if (fasync_insert_entry(fd, filp, fapp, new)) {
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  977) 		fasync_free(new);
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  978) 		return 0;
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  979) 	}
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  980) 
f7347ce4ee7c6 (Linus Torvalds        2010-10-27 12:38:12 -0400  981) 	return 1;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  982) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  983) 
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  984) /*
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  985)  * fasync_helper() is used by almost all character device drivers
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  986)  * to set up the fasync queue, and for regular files by the file
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  987)  * lease code. It returns negative on error, 0 if it did no changes
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  988)  * and positive if it added/deleted the entry.
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  989)  */
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  990) int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  991) {
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  992) 	if (!on)
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  993) 		return fasync_remove_entry(filp, fapp);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  994) 	return fasync_add_entry(fd, filp, fapp);
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  995) }
53281b6d34d44 (Linus Torvalds        2009-12-16 08:23:37 -0800  996) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  997) EXPORT_SYMBOL(fasync_helper);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700  998) 
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000  999) /*
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1000)  * rcu_read_lock() is held
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1001)  */
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1002) static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1003) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1004) 	while (fa) {
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1005) 		struct fown_struct *fown;
f4985dc714d7a (Andrew Morton         2010-06-29 15:05:42 -0700 1006) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1007) 		if (fa->magic != FASYNC_MAGIC) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1008) 			printk(KERN_ERR "kill_fasync: bad magic number in "
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1009) 			       "fasync_struct!\n");
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1010) 			return;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1011) 		}
7a107c0f55a3b (Kirill Tkhai          2018-04-05 14:58:06 +0300 1012) 		read_lock(&fa->fa_lock);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1013) 		if (fa->fa_file) {
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1014) 			fown = &fa->fa_file->f_owner;
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1015) 			/* Don't send SIGURG to processes which have not set a
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1016) 			   queued signum: SIGURG has its own default signalling
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1017) 			   mechanism. */
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1018) 			if (!(sig == SIGURG && fown->signum == 0))
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1019) 				send_sigio(fown, fa->fa_fd, band);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1020) 		}
7a107c0f55a3b (Kirill Tkhai          2018-04-05 14:58:06 +0300 1021) 		read_unlock(&fa->fa_lock);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1022) 		fa = rcu_dereference(fa->fa_next);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1023) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1024) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1025) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1026) void kill_fasync(struct fasync_struct **fp, int sig, int band)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1027) {
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1028) 	/* First a quick test without locking: usually
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1029) 	 * the list is empty.
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1030) 	 */
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1031) 	if (*fp) {
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1032) 		rcu_read_lock();
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1033) 		kill_fasync_rcu(rcu_dereference(*fp), sig, band);
989a2979205dd (Eric Dumazet          2010-04-14 09:55:35 +0000 1034) 		rcu_read_unlock();
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1035) 	}
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1036) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1037) EXPORT_SYMBOL(kill_fasync);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1038) 
454eedb8901da (Wu Fengguang          2010-08-10 18:01:29 -0700 1039) static int __init fcntl_init(void)
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1040) {
3ab04d5cf9736 (James Bottomley       2010-09-09 16:38:12 -0700 1041) 	/*
3ab04d5cf9736 (James Bottomley       2010-09-09 16:38:12 -0700 1042) 	 * Please add new bits here to ensure allocation uniqueness.
3ab04d5cf9736 (James Bottomley       2010-09-09 16:38:12 -0700 1043) 	 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
3ab04d5cf9736 (James Bottomley       2010-09-09 16:38:12 -0700 1044) 	 * is defined as O_NONBLOCK on some platforms and not on others.
3ab04d5cf9736 (James Bottomley       2010-09-09 16:38:12 -0700 1045) 	 */
80f18379a7c35 (Christoph Hellwig     2017-04-27 09:42:24 +0200 1046) 	BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
80f18379a7c35 (Christoph Hellwig     2017-04-27 09:42:24 +0200 1047) 		HWEIGHT32(
80f18379a7c35 (Christoph Hellwig     2017-04-27 09:42:24 +0200 1048) 			(VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
80f18379a7c35 (Christoph Hellwig     2017-04-27 09:42:24 +0200 1049) 			__FMODE_EXEC | __FMODE_NONOTIFY));
454eedb8901da (Wu Fengguang          2010-08-10 18:01:29 -0700 1050) 
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1051) 	fasync_cache = kmem_cache_create("fasync_cache",
20c2df83d25c6 (Paul Mundt            2007-07-20 10:11:58 +0900 1052) 		sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL);
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1053) 	return 0;
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1054) }
^1da177e4c3f4 (Linus Torvalds        2005-04-16 15:20:36 -0700 1055) 
454eedb8901da (Wu Fengguang          2010-08-10 18:01:29 -0700 1056) module_init(fcntl_init)