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)