VisionFive2 Linux kernel

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

More than 9999 Commits   32 Branches   54 Tags
457c899653991 (Thomas Gleixner     2019-05-19 13:08:55 +0100    1) // SPDX-License-Identifier: GPL-2.0-only
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700    2) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700    3)  *  linux/fs/open.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/string.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700    9) #include <linux/mm.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   10) #include <linux/file.h>
9f3acc3140444 (Al Viro             2008-04-24 07:44:08 -0400   11) #include <linux/fdtable.h>
0eeca28300df1 (Robert Love         2005-07-12 17:06:03 -0400   12) #include <linux/fsnotify.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   13) #include <linux/module.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   14) #include <linux/tty.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   15) #include <linux/namei.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   16) #include <linux/backing-dev.h>
16f7e0fe2ecc3 (Randy Dunlap        2006-01-11 12:17:46 -0800   17) #include <linux/capability.h>
086f7316f0d40 (Andrew G. Morgan    2008-07-04 09:59:58 -0700   18) #include <linux/securebits.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   19) #include <linux/security.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   20) #include <linux/mount.h>
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800   21) #include <linux/fcntl.h>
5a0e3ad6af866 (Tejun Heo           2010-03-24 17:04:11 +0900   22) #include <linux/slab.h>
7c0f6ba682b9c (Linus Torvalds      2016-12-24 11:46:01 -0800   23) #include <linux/uaccess.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   24) #include <linux/fs.h>
ef3daeda7b58f (Yoav Zach           2005-06-23 00:09:58 -0700   25) #include <linux/personality.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   26) #include <linux/pagemap.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   27) #include <linux/syscalls.h>
ab2af1f500506 (Dipankar Sarma      2005-09-09 13:04:13 -0700   28) #include <linux/rcupdate.h>
73241ccca0f77 (Amy Griffis         2005-11-03 16:00:25 +0000   29) #include <linux/audit.h>
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400   30) #include <linux/falloc.h>
5ad4e53bd5406 (Al Viro             2009-03-29 19:50:06 -0400   31) #include <linux/fs_struct.h>
b65a9cfc2c38e (Al Viro             2009-12-16 06:27:40 -0500   32) #include <linux/ima.h>
2dfc1cae4c42b (Eric Paris          2009-12-17 20:30:52 -0500   33) #include <linux/dnotify.h>
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500   34) #include <linux/compat.h>
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   35) 
e81e3f4dca6c5 (Eric Paris          2009-12-04 15:47:36 -0500   36) #include "internal.h"
e81e3f4dca6c5 (Eric Paris          2009-12-04 15:47:36 -0500   37) 
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100   38) int do_truncate(struct user_namespace *mnt_userns, struct dentry *dentry,
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100   39) 		loff_t length, unsigned int time_attrs, struct file *filp)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   40) {
939a9421eb53d (Amerigo Wang        2009-08-20 19:29:03 -0700   41) 	int ret;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   42) 	struct iattr newattrs;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   43) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   44) 	/* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   45) 	if (length < 0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   46) 		return -EINVAL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   47) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   48) 	newattrs.ia_size = length;
4a30131e7dbb1 (NeilBrown           2006-01-08 01:02:39 -0800   49) 	newattrs.ia_valid = ATTR_SIZE | time_attrs;
cc4e69dee4a08 (Miklos Szeredi      2005-11-07 00:59:49 -0800   50) 	if (filp) {
cc4e69dee4a08 (Miklos Szeredi      2005-11-07 00:59:49 -0800   51) 		newattrs.ia_file = filp;
cc4e69dee4a08 (Miklos Szeredi      2005-11-07 00:59:49 -0800   52) 		newattrs.ia_valid |= ATTR_FILE;
cc4e69dee4a08 (Miklos Szeredi      2005-11-07 00:59:49 -0800   53) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   54) 
45f147a1bc97c (Jan Kara            2015-05-21 16:05:55 +0200   55) 	/* Remove suid, sgid, and file capabilities on truncate too */
45f147a1bc97c (Jan Kara            2015-05-21 16:05:55 +0200   56) 	ret = dentry_needs_remove_privs(dentry);
45f147a1bc97c (Jan Kara            2015-05-21 16:05:55 +0200   57) 	if (ret < 0)
45f147a1bc97c (Jan Kara            2015-05-21 16:05:55 +0200   58) 		return ret;
939a9421eb53d (Amerigo Wang        2009-08-20 19:29:03 -0700   59) 	if (ret)
939a9421eb53d (Amerigo Wang        2009-08-20 19:29:03 -0700   60) 		newattrs.ia_valid |= ret | ATTR_FORCE;
7b82dc0e64e93 (Linus Torvalds      2007-05-08 20:10:00 -0700   61) 
5955102c9984f (Al Viro             2016-01-22 15:40:57 -0500   62) 	inode_lock(dentry->d_inode);
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400   63) 	/* Note any delegations or leases have already been broken: */
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100   64) 	ret = notify_change(mnt_userns, dentry, &newattrs, NULL);
5955102c9984f (Al Viro             2016-01-22 15:40:57 -0500   65) 	inode_unlock(dentry->d_inode);
939a9421eb53d (Amerigo Wang        2009-08-20 19:29:03 -0700   66) 	return ret;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   67) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   68) 
7df818b2370a9 (Al Viro             2016-03-25 14:24:09 -0400   69) long vfs_truncate(const struct path *path, loff_t length)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   70) {
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100   71) 	struct user_namespace *mnt_userns;
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400   72) 	struct inode *inode;
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000   73) 	long error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   74) 
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000   75) 	inode = path->dentry->d_inode;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   76) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   77) 	/* For directories it's -EISDIR, for other non-regulars - -EINVAL */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   78) 	if (S_ISDIR(inode->i_mode))
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000   79) 		return -EISDIR;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   80) 	if (!S_ISREG(inode->i_mode))
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000   81) 		return -EINVAL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   82) 
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000   83) 	error = mnt_want_write(path->mnt);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   84) 	if (error)
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000   85) 		goto out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   86) 
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100   87) 	mnt_userns = mnt_user_ns(path->mnt);
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100   88) 	error = inode_permission(mnt_userns, inode, MAY_WRITE);
9ac9b8474c39c (Dave Hansen         2008-02-15 14:37:52 -0800   89) 	if (error)
9ac9b8474c39c (Dave Hansen         2008-02-15 14:37:52 -0800   90) 		goto mnt_drop_write_and_out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   91) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   92) 	error = -EPERM;
c82e42da8a6b2 (Miklos Szeredi      2008-06-24 16:50:12 +0200   93) 	if (IS_APPEND(inode))
9ac9b8474c39c (Dave Hansen         2008-02-15 14:37:52 -0800   94) 		goto mnt_drop_write_and_out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   95) 
8cf9ee5061037 (Miklos Szeredi      2018-07-18 15:44:43 +0200   96) 	error = get_write_access(inode);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   97) 	if (error)
9ac9b8474c39c (Dave Hansen         2008-02-15 14:37:52 -0800   98) 		goto mnt_drop_write_and_out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   99) 
9700382c3c9ff (david m. richter    2007-07-31 00:39:12 -0700  100) 	/*
9700382c3c9ff (david m. richter    2007-07-31 00:39:12 -0700  101) 	 * Make sure that there are no leases.  get_write_access() protects
9700382c3c9ff (david m. richter    2007-07-31 00:39:12 -0700  102) 	 * against the truncate racing with a lease-granting setlease().
9700382c3c9ff (david m. richter    2007-07-31 00:39:12 -0700  103) 	 */
8737c9305bd56 (Al Viro             2009-12-24 06:47:55 -0500  104) 	error = break_lease(inode, O_WRONLY);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  105) 	if (error)
9700382c3c9ff (david m. richter    2007-07-31 00:39:12 -0700  106) 		goto put_write_and_out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  107) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  108) 	error = locks_verify_truncate(inode, NULL, length);
be6d3e56a6b9b (Kentaro Takeda      2008-12-17 13:24:15 +0900  109) 	if (!error)
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  110) 		error = security_path_truncate(path);
907f4554e2521 (Christoph Hellwig   2010-03-03 09:05:06 -0500  111) 	if (!error)
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100  112) 		error = do_truncate(mnt_userns, path->dentry, length, 0, NULL);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  113) 
9700382c3c9ff (david m. richter    2007-07-31 00:39:12 -0700  114) put_write_and_out:
8cf9ee5061037 (Miklos Szeredi      2018-07-18 15:44:43 +0200  115) 	put_write_access(inode);
9ac9b8474c39c (Dave Hansen         2008-02-15 14:37:52 -0800  116) mnt_drop_write_and_out:
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  117) 	mnt_drop_write(path->mnt);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  118) out:
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  119) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  120) }
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  121) EXPORT_SYMBOL_GPL(vfs_truncate);
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  122) 
df260e21e6cd5 (Dominik Brodowski   2018-03-19 17:32:11 +0100  123) long do_sys_truncate(const char __user *pathname, loff_t length)
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  124) {
48f7530d3f722 (Jeff Layton         2012-12-11 12:10:11 -0500  125) 	unsigned int lookup_flags = LOOKUP_FOLLOW;
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  126) 	struct path path;
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  127) 	int error;
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  128) 
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  129) 	if (length < 0)	/* sorry, but loff_t says... */
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  130) 		return -EINVAL;
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  131) 
48f7530d3f722 (Jeff Layton         2012-12-11 12:10:11 -0500  132) retry:
48f7530d3f722 (Jeff Layton         2012-12-11 12:10:11 -0500  133) 	error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  134) 	if (!error) {
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  135) 		error = vfs_truncate(&path, length);
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  136) 		path_put(&path);
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  137) 	}
48f7530d3f722 (Jeff Layton         2012-12-11 12:10:11 -0500  138) 	if (retry_estale(error, lookup_flags)) {
48f7530d3f722 (Jeff Layton         2012-12-11 12:10:11 -0500  139) 		lookup_flags |= LOOKUP_REVAL;
48f7530d3f722 (Jeff Layton         2012-12-11 12:10:11 -0500  140) 		goto retry;
48f7530d3f722 (Jeff Layton         2012-12-11 12:10:11 -0500  141) 	}
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  142) 	return error;
a02de9608595c (David Howells       2012-12-20 21:52:36 +0000  143) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  144) 
4fd8da8d62416 (Heiko Carstens      2009-09-23 17:49:55 +0200  145) SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  146) {
4fd8da8d62416 (Heiko Carstens      2009-09-23 17:49:55 +0200  147) 	return do_sys_truncate(path, length);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  148) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  149) 
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  150) #ifdef CONFIG_COMPAT
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  151) COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length)
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  152) {
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  153) 	return do_sys_truncate(path, length);
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  154) }
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  155) #endif
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  156) 
411d9475cf901 (Dominik Brodowski   2018-03-11 11:34:54 +0100  157) long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  158) {
bf2965d5b5950 (Al Viro             2012-08-26 20:13:36 -0400  159) 	struct inode *inode;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  160) 	struct dentry *dentry;
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  161) 	struct fd f;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  162) 	int error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  163) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  164) 	error = -EINVAL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  165) 	if (length < 0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  166) 		goto out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  167) 	error = -EBADF;
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  168) 	f = fdget(fd);
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  169) 	if (!f.file)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  170) 		goto out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  171) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  172) 	/* explicitly opened as large or we are on 64-bit box */
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  173) 	if (f.file->f_flags & O_LARGEFILE)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  174) 		small = 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  175) 
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  176) 	dentry = f.file->f_path.dentry;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  177) 	inode = dentry->d_inode;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  178) 	error = -EINVAL;
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  179) 	if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE))
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  180) 		goto out_putf;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  181) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  182) 	error = -EINVAL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  183) 	/* Cannot ftruncate over 2^31 bytes without large file support */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  184) 	if (small && length > MAX_NON_LFS)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  185) 		goto out_putf;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  186) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  187) 	error = -EPERM;
78757af6518a3 (Amir Goldstein      2017-04-08 14:49:06 +0300  188) 	/* Check IS_APPEND on real upper inode */
78757af6518a3 (Amir Goldstein      2017-04-08 14:49:06 +0300  189) 	if (IS_APPEND(file_inode(f.file)))
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  190) 		goto out_putf;
14da9200140f8 (Jan Kara            2012-06-12 16:20:37 +0200  191) 	sb_start_write(inode->i_sb);
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  192) 	error = locks_verify_truncate(inode, f.file, length);
be6d3e56a6b9b (Kentaro Takeda      2008-12-17 13:24:15 +0900  193) 	if (!error)
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  194) 		error = security_path_truncate(&f.file->f_path);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  195) 	if (!error)
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100  196) 		error = do_truncate(file_mnt_user_ns(f.file), dentry, length,
643fe55a0679a (Christian Brauner   2021-01-21 14:19:34 +0100  197) 				    ATTR_MTIME | ATTR_CTIME, f.file);
14da9200140f8 (Jan Kara            2012-06-12 16:20:37 +0200  198) 	sb_end_write(inode->i_sb);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  199) out_putf:
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  200) 	fdput(f);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  201) out:
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  202) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  203) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  204) 
bdc480e3bef6e (Heiko Carstens      2009-01-14 14:14:12 +0100  205) SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  206) {
2cf0966683430 (Al Viro             2013-01-21 15:25:54 -0500  207) 	return do_sys_ftruncate(fd, length, 1);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  208) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  209) 
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  210) #ifdef CONFIG_COMPAT
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  211) COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length)
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  212) {
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  213) 	return do_sys_ftruncate(fd, length, 1);
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  214) }
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  215) #endif
3f6d078d4accf (Al Viro             2013-02-24 13:49:08 -0500  216) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  217) /* LFS versions of truncate are only needed on 32 bit machines */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  218) #if BITS_PER_LONG == 32
4a0fd5bf0fd07 (Al Viro             2013-01-21 15:16:58 -0500  219) SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  220) {
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  221) 	return do_sys_truncate(path, length);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  222) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  223) 
4a0fd5bf0fd07 (Al Viro             2013-01-21 15:16:58 -0500  224) SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  225) {
2cf0966683430 (Al Viro             2013-01-21 15:25:54 -0500  226) 	return do_sys_ftruncate(fd, length, 0);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  227) }
6673e0c3fbeae (Heiko Carstens      2009-01-14 14:14:02 +0100  228) #endif /* BITS_PER_LONG == 32 */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  229) 
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  230) 
72c72bdf7bf53 (Anna Schumaker      2014-11-07 14:44:25 -0500  231) int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  232) {
496ad9aa8ef44 (Al Viro             2013-01-23 17:07:38 -0500  233) 	struct inode *inode = file_inode(file);
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  234) 	long ret;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  235) 
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  236) 	if (offset < 0 || len <= 0)
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  237) 		return -EINVAL;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  238) 
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  239) 	/* Return error if mode is not supported */
dd46c787788d5 (Namjae Jeon         2015-03-25 15:07:05 +1100  240) 	if (mode & ~FALLOC_FL_SUPPORTED_MASK)
409332b65d3ed (Lukas Czerner       2014-03-13 19:07:42 +1100  241) 		return -EOPNOTSUPP;
409332b65d3ed (Lukas Czerner       2014-03-13 19:07:42 +1100  242) 
409332b65d3ed (Lukas Czerner       2014-03-13 19:07:42 +1100  243) 	/* Punch hole and zero range are mutually exclusive */
409332b65d3ed (Lukas Czerner       2014-03-13 19:07:42 +1100  244) 	if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) ==
409332b65d3ed (Lukas Czerner       2014-03-13 19:07:42 +1100  245) 	    (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
79124f18b3351 (Josef Bacik         2010-11-17 20:46:15 -0500  246) 		return -EOPNOTSUPP;
79124f18b3351 (Josef Bacik         2010-11-17 20:46:15 -0500  247) 
79124f18b3351 (Josef Bacik         2010-11-17 20:46:15 -0500  248) 	/* Punch hole must have keep size set */
79124f18b3351 (Josef Bacik         2010-11-17 20:46:15 -0500  249) 	if ((mode & FALLOC_FL_PUNCH_HOLE) &&
79124f18b3351 (Josef Bacik         2010-11-17 20:46:15 -0500  250) 	    !(mode & FALLOC_FL_KEEP_SIZE))
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  251) 		return -EOPNOTSUPP;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  252) 
00f5e61998dd1 (Namjae Jeon         2014-02-24 10:58:15 +1100  253) 	/* Collapse range should only be used exclusively. */
00f5e61998dd1 (Namjae Jeon         2014-02-24 10:58:15 +1100  254) 	if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
00f5e61998dd1 (Namjae Jeon         2014-02-24 10:58:15 +1100  255) 	    (mode & ~FALLOC_FL_COLLAPSE_RANGE))
00f5e61998dd1 (Namjae Jeon         2014-02-24 10:58:15 +1100  256) 		return -EINVAL;
00f5e61998dd1 (Namjae Jeon         2014-02-24 10:58:15 +1100  257) 
dd46c787788d5 (Namjae Jeon         2015-03-25 15:07:05 +1100  258) 	/* Insert range should only be used exclusively. */
dd46c787788d5 (Namjae Jeon         2015-03-25 15:07:05 +1100  259) 	if ((mode & FALLOC_FL_INSERT_RANGE) &&
dd46c787788d5 (Namjae Jeon         2015-03-25 15:07:05 +1100  260) 	    (mode & ~FALLOC_FL_INSERT_RANGE))
dd46c787788d5 (Namjae Jeon         2015-03-25 15:07:05 +1100  261) 		return -EINVAL;
dd46c787788d5 (Namjae Jeon         2015-03-25 15:07:05 +1100  262) 
71be6b4942dd6 (Darrick J. Wong     2016-10-03 09:11:14 -0700  263) 	/* Unshare range should only be used with allocate mode. */
71be6b4942dd6 (Darrick J. Wong     2016-10-03 09:11:14 -0700  264) 	if ((mode & FALLOC_FL_UNSHARE_RANGE) &&
71be6b4942dd6 (Darrick J. Wong     2016-10-03 09:11:14 -0700  265) 	    (mode & ~(FALLOC_FL_UNSHARE_RANGE | FALLOC_FL_KEEP_SIZE)))
71be6b4942dd6 (Darrick J. Wong     2016-10-03 09:11:14 -0700  266) 		return -EINVAL;
71be6b4942dd6 (Darrick J. Wong     2016-10-03 09:11:14 -0700  267) 
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  268) 	if (!(file->f_mode & FMODE_WRITE))
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  269) 		return -EBADF;
1ca551c6caae7 (Marco Stornelli     2011-03-05 11:10:19 +0100  270) 
00f5e61998dd1 (Namjae Jeon         2014-02-24 10:58:15 +1100  271) 	/*
8fc61d92630d1 (Lukas Czerner       2014-04-12 09:51:34 -0400  272) 	 * We can only allow pure fallocate on append only files
00f5e61998dd1 (Namjae Jeon         2014-02-24 10:58:15 +1100  273) 	 */
8fc61d92630d1 (Lukas Czerner       2014-04-12 09:51:34 -0400  274) 	if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode))
1ca551c6caae7 (Marco Stornelli     2011-03-05 11:10:19 +0100  275) 		return -EPERM;
1ca551c6caae7 (Marco Stornelli     2011-03-05 11:10:19 +0100  276) 
1ca551c6caae7 (Marco Stornelli     2011-03-05 11:10:19 +0100  277) 	if (IS_IMMUTABLE(inode))
1ca551c6caae7 (Marco Stornelli     2011-03-05 11:10:19 +0100  278) 		return -EPERM;
1ca551c6caae7 (Marco Stornelli     2011-03-05 11:10:19 +0100  279) 
0790b31b69374 (Lukas Czerner       2014-04-12 10:05:37 -0400  280) 	/*
6d2b6170c8914 (Eric Biggers        2014-06-24 23:45:08 -0500  281) 	 * We cannot allow any fallocate operation on an active swapfile
0790b31b69374 (Lukas Czerner       2014-04-12 10:05:37 -0400  282) 	 */
0790b31b69374 (Lukas Czerner       2014-04-12 10:05:37 -0400  283) 	if (IS_SWAPFILE(inode))
6d2b6170c8914 (Eric Biggers        2014-06-24 23:45:08 -0500  284) 		return -ETXTBSY;
0790b31b69374 (Lukas Czerner       2014-04-12 10:05:37 -0400  285) 
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  286) 	/*
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  287) 	 * Revalidate the write permissions, in case security policy has
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  288) 	 * changed since the files were opened.
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  289) 	 */
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  290) 	ret = security_file_permission(file, MAY_WRITE);
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  291) 	if (ret)
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  292) 		return ret;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  293) 
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  294) 	if (S_ISFIFO(inode->i_mode))
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  295) 		return -ESPIPE;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  296) 
9e79b13263025 (Amir Goldstein      2017-01-31 10:34:55 +0200  297) 	if (S_ISDIR(inode->i_mode))
9e79b13263025 (Amir Goldstein      2017-01-31 10:34:55 +0200  298) 		return -EISDIR;
9e79b13263025 (Amir Goldstein      2017-01-31 10:34:55 +0200  299) 
9e79b13263025 (Amir Goldstein      2017-01-31 10:34:55 +0200  300) 	if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  301) 		return -ENODEV;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  302) 
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  303) 	/* Check for wrap through zero too */
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  304) 	if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  305) 		return -EFBIG;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  306) 
2fe17c1075836 (Christoph Hellwig   2011-01-14 13:07:43 +0100  307) 	if (!file->f_op->fallocate)
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  308) 		return -EOPNOTSUPP;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  309) 
bfe219d373cad (Amir Goldstein      2017-01-31 10:34:57 +0200  310) 	file_start_write(file);
14da9200140f8 (Jan Kara            2012-06-12 16:20:37 +0200  311) 	ret = file->f_op->fallocate(file, mode, offset, len);
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  312) 
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  313) 	/*
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  314) 	 * Create inotify and fanotify events.
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  315) 	 *
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  316) 	 * To keep the logic simple always create events if fallocate succeeds.
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  317) 	 * This implies that events are even created if the file size remains
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  318) 	 * unchanged, e.g. when using flag FALLOC_FL_KEEP_SIZE.
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  319) 	 */
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  320) 	if (ret == 0)
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  321) 		fsnotify_modify(file);
820c12d5d6c08 (Heinrich Schuchardt 2014-12-12 16:58:34 -0800  322) 
bfe219d373cad (Amir Goldstein      2017-01-31 10:34:57 +0200  323) 	file_end_write(file);
14da9200140f8 (Jan Kara            2012-06-12 16:20:37 +0200  324) 	return ret;
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  325) }
72c72bdf7bf53 (Anna Schumaker      2014-11-07 14:44:25 -0500  326) EXPORT_SYMBOL_GPL(vfs_fallocate);
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  327) 
edf292c76b884 (Dominik Brodowski   2018-03-19 17:46:32 +0100  328) int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len)
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  329) {
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  330) 	struct fd f = fdget(fd);
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  331) 	int error = -EBADF;
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  332) 
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  333) 	if (f.file) {
72c72bdf7bf53 (Anna Schumaker      2014-11-07 14:44:25 -0500  334) 		error = vfs_fallocate(f.file, mode, offset, len);
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  335) 		fdput(f);
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  336) 	}
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  337) 	return error;
97ac73506c0ba (Amit Arora          2007-07-17 21:42:44 -0400  338) }
3e63cbb1efca7 (Ankit Jain          2009-06-19 14:28:07 -0400  339) 
edf292c76b884 (Dominik Brodowski   2018-03-19 17:46:32 +0100  340) SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
edf292c76b884 (Dominik Brodowski   2018-03-19 17:46:32 +0100  341) {
edf292c76b884 (Dominik Brodowski   2018-03-19 17:46:32 +0100  342) 	return ksys_fallocate(fd, mode, offset, len);
edf292c76b884 (Dominik Brodowski   2018-03-19 17:46:32 +0100  343) }
edf292c76b884 (Dominik Brodowski   2018-03-19 17:46:32 +0100  344) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  345) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  346)  * access() needs to use the real uid/gid, not the effective uid/gid.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  347)  * We do this by temporarily clearing all FS-related capabilities and
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  348)  * switching the fsuid/fsgid around to the real ones.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  349)  */
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  350) static const struct cred *access_override_creds(void)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  351) {
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  352) 	const struct cred *old_cred;
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  353) 	struct cred *override_cred;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  354) 
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  355) 	override_cred = prepare_creds();
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  356) 	if (!override_cred)
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  357) 		return NULL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  358) 
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  359) 	override_cred->fsuid = override_cred->uid;
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  360) 	override_cred->fsgid = override_cred->gid;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  361) 
086f7316f0d40 (Andrew G. Morgan    2008-07-04 09:59:58 -0700  362) 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
1cdcbec1a3372 (David Howells       2008-11-14 10:39:14 +1100  363) 		/* Clear the capabilities if we switch to a non-root user */
18815a1808536 (Eric W. Biederman   2012-02-07 16:45:47 -0800  364) 		kuid_t root_uid = make_kuid(override_cred->user_ns, 0);
18815a1808536 (Eric W. Biederman   2012-02-07 16:45:47 -0800  365) 		if (!uid_eq(override_cred->uid, root_uid))
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  366) 			cap_clear(override_cred->cap_effective);
086f7316f0d40 (Andrew G. Morgan    2008-07-04 09:59:58 -0700  367) 		else
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  368) 			override_cred->cap_effective =
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  369) 				override_cred->cap_permitted;
086f7316f0d40 (Andrew G. Morgan    2008-07-04 09:59:58 -0700  370) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  371) 
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  372) 	/*
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  373) 	 * The new set of credentials can *only* be used in
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  374) 	 * task-synchronous circumstances, and does not need
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  375) 	 * RCU freeing, unless somebody then takes a separate
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  376) 	 * reference to it.
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  377) 	 *
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  378) 	 * NOTE! This is _only_ true because this credential
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  379) 	 * is used purely for override_creds() that installs
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  380) 	 * it as the subjective cred. Other threads will be
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  381) 	 * accessing ->real_cred, not the subjective cred.
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  382) 	 *
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  383) 	 * If somebody _does_ make a copy of this (using the
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  384) 	 * 'get_current_cred()' function), that will clear the
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  385) 	 * non_rcu field, because now that other user may be
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  386) 	 * expecting RCU freeing. But normal thread-synchronous
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  387) 	 * cred accesses will keep things non-RCY.
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  388) 	 */
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  389) 	override_cred->non_rcu = 1;
d7852fbd0f042 (Linus Torvalds      2019-07-11 09:54:40 -0700  390) 
d84f4f992cbd7 (David Howells       2008-11-14 10:39:23 +1100  391) 	old_cred = override_creds(override_cred);
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  392) 
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  393) 	/* override_cred() gets its own ref */
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  394) 	put_cred(override_cred);
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  395) 
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  396) 	return old_cred;
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  397) }
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  398) 
eb9d7d390e511 (Christoph Hellwig   2020-07-22 11:14:02 +0200  399) static long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  400) {
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  401) 	struct path path;
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  402) 	struct inode *inode;
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  403) 	int res;
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  404) 	unsigned int lookup_flags = LOOKUP_FOLLOW;
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  405) 	const struct cred *old_cred = NULL;
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  406) 
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  407) 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  408) 		return -EINVAL;
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  409) 
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  410) 	if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  411) 		return -EINVAL;
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  412) 
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  413) 	if (flags & AT_SYMLINK_NOFOLLOW)
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  414) 		lookup_flags &= ~LOOKUP_FOLLOW;
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  415) 	if (flags & AT_EMPTY_PATH)
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  416) 		lookup_flags |= LOOKUP_EMPTY;
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  417) 
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  418) 	if (!(flags & AT_EACCESS)) {
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  419) 		old_cred = access_override_creds();
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  420) 		if (!old_cred)
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  421) 			return -ENOMEM;
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  422) 	}
9470451505efb (Miklos Szeredi      2020-05-14 16:44:24 +0200  423) 
87fa55952b734 (Jeff Layton         2012-12-11 12:10:11 -0500  424) retry:
87fa55952b734 (Jeff Layton         2012-12-11 12:10:11 -0500  425) 	res = user_path_at(dfd, filename, lookup_flags, &path);
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  426) 	if (res)
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  427) 		goto out;
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  428) 
63afdfc781e10 (David Howells       2015-05-06 15:59:00 +0100  429) 	inode = d_backing_inode(path.dentry);
256984a83880f (Al Viro             2008-07-22 08:09:30 -0400  430) 
256984a83880f (Al Viro             2008-07-22 08:09:30 -0400  431) 	if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) {
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  432) 		/*
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  433) 		 * MAY_EXEC on regular files is denied if the fs is mounted
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  434) 		 * with the "noexec" flag.
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  435) 		 */
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  436) 		res = -EACCES;
90f8572b0f021 (Eric W. Biederman   2015-06-29 14:42:03 -0500  437) 		if (path_noexec(&path))
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  438) 			goto out_path_release;
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  439) 	}
30524472c2f72 (Al Viro             2008-07-22 00:02:33 -0400  440) 
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  441) 	res = inode_permission(mnt_user_ns(path.mnt), inode, mode | MAY_ACCESS);
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  442) 	/* SuS v2 requires we report a read only fs too */
256984a83880f (Al Viro             2008-07-22 08:09:30 -0400  443) 	if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  444) 		goto out_path_release;
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  445) 	/*
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  446) 	 * This is a rare case where using __mnt_is_readonly()
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  447) 	 * is OK without a mnt_want/drop_write() pair.  Since
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  448) 	 * no actual write to the fs is performed here, we do
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  449) 	 * not need to telegraph to that to anyone.
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  450) 	 *
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  451) 	 * By doing this, we accept that this access is
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  452) 	 * inherently racy and know that the fs may change
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  453) 	 * state before we even see this result.
2f676cbc0d60a (Dave Hansen         2008-02-15 14:37:55 -0800  454) 	 */
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  455) 	if (__mnt_is_readonly(path.mnt))
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  456) 		res = -EROFS;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  457) 
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  458) out_path_release:
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  459) 	path_put(&path);
87fa55952b734 (Jeff Layton         2012-12-11 12:10:11 -0500  460) 	if (retry_estale(res, lookup_flags)) {
87fa55952b734 (Jeff Layton         2012-12-11 12:10:11 -0500  461) 		lookup_flags |= LOOKUP_REVAL;
87fa55952b734 (Jeff Layton         2012-12-11 12:10:11 -0500  462) 		goto retry;
87fa55952b734 (Jeff Layton         2012-12-11 12:10:11 -0500  463) 	}
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  464) out:
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  465) 	if (old_cred)
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  466) 		revert_creds(old_cred);
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  467) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  468) 	return res;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  469) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  470) 
cbfe20f565228 (Dominik Brodowski   2018-03-11 11:34:54 +0100  471) SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
cbfe20f565228 (Dominik Brodowski   2018-03-11 11:34:54 +0100  472) {
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  473) 	return do_faccessat(dfd, filename, mode, 0);
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  474) }
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  475) 
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  476) SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode,
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  477) 		int, flags)
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  478) {
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  479) 	return do_faccessat(dfd, filename, mode, flags);
cbfe20f565228 (Dominik Brodowski   2018-03-11 11:34:54 +0100  480) }
cbfe20f565228 (Dominik Brodowski   2018-03-11 11:34:54 +0100  481) 
ca013e945b1ba (Heiko Carstens      2009-01-14 14:14:19 +0100  482) SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  483) {
c8ffd8bcdd282 (Miklos Szeredi      2020-05-14 16:44:25 +0200  484) 	return do_faccessat(AT_FDCWD, filename, mode, 0);
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  485) }
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  486) 
db63f1e315384 (Christoph Hellwig   2020-07-22 11:25:21 +0200  487) SYSCALL_DEFINE1(chdir, const char __user *, filename)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  488) {
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  489) 	struct path path;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  490) 	int error;
0291c0a551d5b (Jeff Layton         2012-12-11 12:10:12 -0500  491) 	unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
0291c0a551d5b (Jeff Layton         2012-12-11 12:10:12 -0500  492) retry:
0291c0a551d5b (Jeff Layton         2012-12-11 12:10:12 -0500  493) 	error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  494) 	if (error)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  495) 		goto out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  496) 
02f92b3868a1b (Christian Brauner   2021-01-21 14:19:22 +0100  497) 	error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  498) 	if (error)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  499) 		goto dput_and_out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  500) 
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  501) 	set_fs_pwd(current->fs, &path);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  502) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  503) dput_and_out:
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  504) 	path_put(&path);
0291c0a551d5b (Jeff Layton         2012-12-11 12:10:12 -0500  505) 	if (retry_estale(error, lookup_flags)) {
0291c0a551d5b (Jeff Layton         2012-12-11 12:10:12 -0500  506) 		lookup_flags |= LOOKUP_REVAL;
0291c0a551d5b (Jeff Layton         2012-12-11 12:10:12 -0500  507) 		goto retry;
0291c0a551d5b (Jeff Layton         2012-12-11 12:10:12 -0500  508) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  509) out:
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  510) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  511) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  512) 
3cdad42884bbd (Heiko Carstens      2009-01-14 14:14:22 +0100  513) SYSCALL_DEFINE1(fchdir, unsigned int, fd)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  514) {
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  515) 	struct fd f = fdget_raw(fd);
159b095628851 (Al Viro             2017-04-15 15:58:56 -0400  516) 	int error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  517) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  518) 	error = -EBADF;
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  519) 	if (!f.file)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  520) 		goto out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  521) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  522) 	error = -ENOTDIR;
159b095628851 (Al Viro             2017-04-15 15:58:56 -0400  523) 	if (!d_can_lookup(f.file->f_path.dentry))
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  524) 		goto out_putf;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  525) 
02f92b3868a1b (Christian Brauner   2021-01-21 14:19:22 +0100  526) 	error = file_permission(f.file, MAY_EXEC | MAY_CHDIR);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  527) 	if (!error)
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  528) 		set_fs_pwd(current->fs, &f.file->f_path);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  529) out_putf:
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  530) 	fdput(f);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  531) out:
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  532) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  533) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  534) 
4b7ca5014cbef (Christoph Hellwig   2020-07-22 11:26:13 +0200  535) SYSCALL_DEFINE1(chroot, const char __user *, filename)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  536) {
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  537) 	struct path path;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  538) 	int error;
2771261ec5b67 (Jeff Layton         2012-12-20 17:08:32 -0500  539) 	unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
2771261ec5b67 (Jeff Layton         2012-12-20 17:08:32 -0500  540) retry:
2771261ec5b67 (Jeff Layton         2012-12-20 17:08:32 -0500  541) 	error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  542) 	if (error)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  543) 		goto out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  544) 
02f92b3868a1b (Christian Brauner   2021-01-21 14:19:22 +0100  545) 	error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  546) 	if (error)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  547) 		goto dput_and_out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  548) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  549) 	error = -EPERM;
c7b96acf1456e (Eric W. Biederman   2013-03-20 12:49:49 -0700  550) 	if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  551) 		goto dput_and_out;
8b8efb44033c7 (Tetsuo Handa        2009-10-04 21:49:48 +0900  552) 	error = security_path_chroot(&path);
8b8efb44033c7 (Tetsuo Handa        2009-10-04 21:49:48 +0900  553) 	if (error)
8b8efb44033c7 (Tetsuo Handa        2009-10-04 21:49:48 +0900  554) 		goto dput_and_out;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  555) 
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  556) 	set_fs_root(current->fs, &path);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  557) 	error = 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  558) dput_and_out:
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  559) 	path_put(&path);
2771261ec5b67 (Jeff Layton         2012-12-20 17:08:32 -0500  560) 	if (retry_estale(error, lookup_flags)) {
2771261ec5b67 (Jeff Layton         2012-12-20 17:08:32 -0500  561) 		lookup_flags |= LOOKUP_REVAL;
2771261ec5b67 (Jeff Layton         2012-12-20 17:08:32 -0500  562) 		goto retry;
2771261ec5b67 (Jeff Layton         2012-12-20 17:08:32 -0500  563) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  564) out:
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  565) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  566) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  567) 
1097742efc643 (Christoph Hellwig   2020-07-22 11:41:02 +0200  568) int chmod_common(const struct path *path, umode_t mode)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  569) {
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  570) 	struct inode *inode = path->dentry->d_inode;
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  571) 	struct inode *delegated_inode = NULL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  572) 	struct iattr newattrs;
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  573) 	int error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  574) 
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  575) 	error = mnt_want_write(path->mnt);
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  576) 	if (error)
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  577) 		return error;
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  578) retry_deleg:
5955102c9984f (Al Viro             2016-01-22 15:40:57 -0500  579) 	inode_lock(inode);
cdcf116d44e78 (Al Viro             2011-12-08 10:51:53 -0500  580) 	error = security_path_chmod(path, mode);
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  581) 	if (error)
fe542cf59bf0b (Tetsuo Handa        2009-11-22 11:49:55 +0900  582) 		goto out_unlock;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  583) 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  584) 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  585) 	error = notify_change(mnt_user_ns(path->mnt), path->dentry,
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  586) 			      &newattrs, &delegated_inode);
fe542cf59bf0b (Tetsuo Handa        2009-11-22 11:49:55 +0900  587) out_unlock:
5955102c9984f (Al Viro             2016-01-22 15:40:57 -0500  588) 	inode_unlock(inode);
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  589) 	if (delegated_inode) {
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  590) 		error = break_deleg_wait(&delegated_inode);
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  591) 		if (!error)
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  592) 			goto retry_deleg;
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  593) 	}
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  594) 	mnt_drop_write(path->mnt);
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  595) 	return error;
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  596) }
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  597) 
9e96c8c0e94ee (Christoph Hellwig   2020-07-14 08:55:05 +0200  598) int vfs_fchmod(struct file *file, umode_t mode)
9e96c8c0e94ee (Christoph Hellwig   2020-07-14 08:55:05 +0200  599) {
9e96c8c0e94ee (Christoph Hellwig   2020-07-14 08:55:05 +0200  600) 	audit_file(file);
9e96c8c0e94ee (Christoph Hellwig   2020-07-14 08:55:05 +0200  601) 	return chmod_common(&file->f_path, mode);
9e96c8c0e94ee (Christoph Hellwig   2020-07-14 08:55:05 +0200  602) }
9e96c8c0e94ee (Christoph Hellwig   2020-07-14 08:55:05 +0200  603) 
b25ba7c3c9acd (Christoph Hellwig   2020-07-14 08:59:57 +0200  604) SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  605) {
173c84012a594 (Al Viro             2013-08-30 12:48:53 -0400  606) 	struct fd f = fdget(fd);
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  607) 	int err = -EBADF;
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  608) 
173c84012a594 (Al Viro             2013-08-30 12:48:53 -0400  609) 	if (f.file) {
9e96c8c0e94ee (Christoph Hellwig   2020-07-14 08:55:05 +0200  610) 		err = vfs_fchmod(f.file, mode);
173c84012a594 (Al Viro             2013-08-30 12:48:53 -0400  611) 		fdput(f);
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  612) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  613) 	return err;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  614) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  615) 
1097742efc643 (Christoph Hellwig   2020-07-22 11:41:02 +0200  616) static int do_fchmodat(int dfd, const char __user *filename, umode_t mode)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  617) {
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  618) 	struct path path;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  619) 	int error;
14ff690c0f94c (Jeff Layton         2012-12-11 12:10:13 -0500  620) 	unsigned int lookup_flags = LOOKUP_FOLLOW;
14ff690c0f94c (Jeff Layton         2012-12-11 12:10:13 -0500  621) retry:
14ff690c0f94c (Jeff Layton         2012-12-11 12:10:13 -0500  622) 	error = user_path_at(dfd, filename, lookup_flags, &path);
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  623) 	if (!error) {
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  624) 		error = chmod_common(&path, mode);
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  625) 		path_put(&path);
14ff690c0f94c (Jeff Layton         2012-12-11 12:10:13 -0500  626) 		if (retry_estale(error, lookup_flags)) {
14ff690c0f94c (Jeff Layton         2012-12-11 12:10:13 -0500  627) 			lookup_flags |= LOOKUP_REVAL;
14ff690c0f94c (Jeff Layton         2012-12-11 12:10:13 -0500  628) 			goto retry;
14ff690c0f94c (Jeff Layton         2012-12-11 12:10:13 -0500  629) 		}
e57712ebebbb9 (Al Viro             2011-07-26 04:15:54 -0400  630) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  631) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  632) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  633) 
03450e271a160 (Dominik Brodowski   2018-03-11 11:34:53 +0100  634) SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename,
03450e271a160 (Dominik Brodowski   2018-03-11 11:34:53 +0100  635) 		umode_t, mode)
03450e271a160 (Dominik Brodowski   2018-03-11 11:34:53 +0100  636) {
03450e271a160 (Dominik Brodowski   2018-03-11 11:34:53 +0100  637) 	return do_fchmodat(dfd, filename, mode);
03450e271a160 (Dominik Brodowski   2018-03-11 11:34:53 +0100  638) }
03450e271a160 (Dominik Brodowski   2018-03-11 11:34:53 +0100  639) 
49f0a0767211d (Al Viro             2011-07-26 04:22:01 -0400  640) SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  641) {
03450e271a160 (Dominik Brodowski   2018-03-11 11:34:53 +0100  642) 	return do_fchmodat(AT_FDCWD, filename, mode);
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  643) }
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  644) 
b873498f99c77 (Christoph Hellwig   2020-07-22 11:13:26 +0200  645) int chown_common(const struct path *path, uid_t user, gid_t group)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  646) {
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  647) 	struct user_namespace *mnt_userns;
fe542cf59bf0b (Tetsuo Handa        2009-11-22 11:49:55 +0900  648) 	struct inode *inode = path->dentry->d_inode;
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  649) 	struct inode *delegated_inode = NULL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  650) 	int error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  651) 	struct iattr newattrs;
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  652) 	kuid_t uid;
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  653) 	kgid_t gid;
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  654) 
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  655) 	uid = make_kuid(current_user_ns(), user);
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  656) 	gid = make_kgid(current_user_ns(), group);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  657) 
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  658) 	mnt_userns = mnt_user_ns(path->mnt);
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  659) 	uid = kuid_from_mnt(mnt_userns, uid);
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  660) 	gid = kgid_from_mnt(mnt_userns, gid);
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  661) 
c1b8940b42bb6 (Andrew Elble        2015-02-23 08:51:24 -0500  662) retry_deleg:
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  663) 	newattrs.ia_valid =  ATTR_CTIME;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  664) 	if (user != (uid_t) -1) {
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  665) 		if (!uid_valid(uid))
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  666) 			return -EINVAL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  667) 		newattrs.ia_valid |= ATTR_UID;
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  668) 		newattrs.ia_uid = uid;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  669) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  670) 	if (group != (gid_t) -1) {
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  671) 		if (!gid_valid(gid))
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  672) 			return -EINVAL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  673) 		newattrs.ia_valid |= ATTR_GID;
52137abe18201 (Eric W. Biederman   2012-03-03 19:52:01 -0800  674) 		newattrs.ia_gid = gid;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  675) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  676) 	if (!S_ISDIR(inode->i_mode))
b53767719b6cd (Serge Hallyn        2007-10-16 23:31:36 -0700  677) 		newattrs.ia_valid |=
b53767719b6cd (Serge Hallyn        2007-10-16 23:31:36 -0700  678) 			ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
5955102c9984f (Al Viro             2016-01-22 15:40:57 -0500  679) 	inode_lock(inode);
d2b31ca644fdc (Eric W. Biederman   2012-06-01 16:14:19 -0600  680) 	error = security_path_chown(path, uid, gid);
fe542cf59bf0b (Tetsuo Handa        2009-11-22 11:49:55 +0900  681) 	if (!error)
b8b546a061884 (Christian Brauner   2021-01-21 14:19:35 +0100  682) 		error = notify_change(mnt_userns, path->dentry, &newattrs,
2f221d6f7b881 (Christian Brauner   2021-01-21 14:19:26 +0100  683) 				      &delegated_inode);
5955102c9984f (Al Viro             2016-01-22 15:40:57 -0500  684) 	inode_unlock(inode);
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  685) 	if (delegated_inode) {
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  686) 		error = break_deleg_wait(&delegated_inode);
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  687) 		if (!error)
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  688) 			goto retry_deleg;
27ac0ffeac80b (J. Bruce Fields     2011-09-20 17:19:26 -0400  689) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  690) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  691) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  692) 
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  693) int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  694) 		int flag)
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  695) {
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  696) 	struct path path;
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  697) 	int error = -EINVAL;
65cfc67223615 (Al Viro             2011-03-13 15:56:26 -0400  698) 	int lookup_flags;
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  699) 
65cfc67223615 (Al Viro             2011-03-13 15:56:26 -0400  700) 	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  701) 		goto out;
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  702) 
65cfc67223615 (Al Viro             2011-03-13 15:56:26 -0400  703) 	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
65cfc67223615 (Al Viro             2011-03-13 15:56:26 -0400  704) 	if (flag & AT_EMPTY_PATH)
65cfc67223615 (Al Viro             2011-03-13 15:56:26 -0400  705) 		lookup_flags |= LOOKUP_EMPTY;
99a5df37a03c9 (Jeff Layton         2012-12-11 12:10:13 -0500  706) retry:
65cfc67223615 (Al Viro             2011-03-13 15:56:26 -0400  707) 	error = user_path_at(dfd, filename, lookup_flags, &path);
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  708) 	if (error)
6902d925d568c (Dave Hansen         2006-09-30 23:29:01 -0700  709) 		goto out;
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  710) 	error = mnt_want_write(path.mnt);
2af482a7edfb8 (Dave Hansen         2008-02-15 14:37:50 -0800  711) 	if (error)
2af482a7edfb8 (Dave Hansen         2008-02-15 14:37:50 -0800  712) 		goto out_release;
fe542cf59bf0b (Tetsuo Handa        2009-11-22 11:49:55 +0900  713) 	error = chown_common(&path, user, group);
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  714) 	mnt_drop_write(path.mnt);
2af482a7edfb8 (Dave Hansen         2008-02-15 14:37:50 -0800  715) out_release:
2d8f30380ab8c (Al Viro             2008-07-22 09:59:21 -0400  716) 	path_put(&path);
99a5df37a03c9 (Jeff Layton         2012-12-11 12:10:13 -0500  717) 	if (retry_estale(error, lookup_flags)) {
99a5df37a03c9 (Jeff Layton         2012-12-11 12:10:13 -0500  718) 		lookup_flags |= LOOKUP_REVAL;
99a5df37a03c9 (Jeff Layton         2012-12-11 12:10:13 -0500  719) 		goto retry;
99a5df37a03c9 (Jeff Layton         2012-12-11 12:10:13 -0500  720) 	}
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  721) out:
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  722) 	return error;
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  723) }
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800  724) 
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  725) SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  726) 		gid_t, group, int, flag)
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  727) {
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  728) 	return do_fchownat(dfd, filename, user, group, flag);
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  729) }
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  730) 
55e4def0a6e79 (David Howells       2012-06-25 12:55:09 +0100  731) SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  732) {
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  733) 	return do_fchownat(AT_FDCWD, filename, user, group, 0);
55e4def0a6e79 (David Howells       2012-06-25 12:55:09 +0100  734) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  735) 
55e4def0a6e79 (David Howells       2012-06-25 12:55:09 +0100  736) SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
55e4def0a6e79 (David Howells       2012-06-25 12:55:09 +0100  737) {
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  738) 	return do_fchownat(AT_FDCWD, filename, user, group,
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  739) 			   AT_SYMLINK_NOFOLLOW);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  740) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  741) 
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  742) int vfs_fchown(struct file *file, uid_t user, gid_t group)
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  743) {
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  744) 	int error;
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  745) 
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  746) 	error = mnt_want_write_file(file);
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  747) 	if (error)
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  748) 		return error;
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  749) 	audit_file(file);
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  750) 	error = chown_common(&file->f_path, user, group);
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  751) 	mnt_drop_write_file(file);
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  752) 	return error;
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  753) }
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  754) 
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  755) int ksys_fchown(unsigned int fd, uid_t user, gid_t group)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  756) {
2903ff019b346 (Al Viro             2012-08-28 12:52:22 -0400  757) 	struct fd f = fdget(fd);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  758) 	int error = -EBADF;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  759) 
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  760) 	if (f.file) {
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  761) 		error = vfs_fchown(f.file, user, group);
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  762) 		fdput(f);
c04011fe8cbd8 (Christoph Hellwig   2020-07-14 08:47:43 +0200  763) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  764) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  765) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  766) 
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  767) SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  768) {
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  769) 	return ksys_fchown(fd, user, group);
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  770) }
55731b3cda3a8 (Dominik Brodowski   2018-03-11 11:34:55 +0100  771) 
02e5180d991f2 (Al Viro             2012-06-10 14:32:45 -0400  772) static int do_dentry_open(struct file *f,
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  773) 			  struct inode *inode,
ae2bb293a3e8a (Al Viro             2018-07-10 13:22:28 -0400  774) 			  int (*open)(struct inode *, struct file *))
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  775) {
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400  776) 	static const struct file_operations empty_fops = {};
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  777) 	int error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  778) 
b5bcdda32736b (Al Viro             2012-07-20 23:28:46 +0400  779) 	path_get(&f->f_path);
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  780) 	f->f_inode = inode;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  781) 	f->f_mapping = inode->i_mapping;
5660e13d2fd6a (Jeff Layton         2017-07-06 07:02:25 -0400  782) 	f->f_wb_err = filemap_sample_wb_err(f->f_mapping);
735e4ae5ba28c (Jeff Layton         2020-06-01 21:45:36 -0700  783) 	f->f_sb_err = file_sample_sb_err(f);
5660e13d2fd6a (Jeff Layton         2017-07-06 07:02:25 -0400  784) 
3f4d5a00076b7 (Al Viro             2014-03-14 09:43:29 -0400  785) 	if (unlikely(f->f_flags & O_PATH)) {
f5d11409e61da (Al Viro             2018-07-09 02:35:08 -0400  786) 		f->f_mode = FMODE_PATH | FMODE_OPENED;
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400  787) 		f->f_op = &empty_fops;
af04fadcaa932 (Al Viro             2018-06-02 01:31:02 -0400  788) 		return 0;
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400  789) 	}
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400  790) 
dd20908a8a06b (Al Viro             2014-03-14 10:56:20 -0400  791) 	if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
0ccb286346c4c (Al Viro             2014-03-14 10:40:46 -0400  792) 		error = get_write_access(inode);
3f4d5a00076b7 (Al Viro             2014-03-14 09:43:29 -0400  793) 		if (unlikely(error))
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  794) 			goto cleanup_file;
0ccb286346c4c (Al Viro             2014-03-14 10:40:46 -0400  795) 		error = __mnt_want_write(f->f_path.mnt);
3f4d5a00076b7 (Al Viro             2014-03-14 09:43:29 -0400  796) 		if (unlikely(error)) {
0ccb286346c4c (Al Viro             2014-03-14 10:40:46 -0400  797) 			put_write_access(inode);
0ccb286346c4c (Al Viro             2014-03-14 10:40:46 -0400  798) 			goto cleanup_file;
0ccb286346c4c (Al Viro             2014-03-14 10:40:46 -0400  799) 		}
83f936c75e368 (Al Viro             2014-03-14 12:02:47 -0400  800) 		f->f_mode |= FMODE_WRITER;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  801) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  802) 
2be7d348fe924 (Linus Torvalds      2019-11-26 11:34:06 -0800  803) 	/* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */
2be7d348fe924 (Linus Torvalds      2019-11-26 11:34:06 -0800  804) 	if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))
2be7d348fe924 (Linus Torvalds      2019-11-26 11:34:06 -0800  805) 		f->f_mode |= FMODE_ATOMIC_POS;
2be7d348fe924 (Linus Torvalds      2019-11-26 11:34:06 -0800  806) 
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400  807) 	f->f_op = fops_get(inode->i_fop);
7159d54418e0a (Denis Efremov       2019-09-25 16:49:31 -0700  808) 	if (WARN_ON(!f->f_op)) {
72c2d53192004 (Al Viro             2013-09-22 16:27:52 -0400  809) 		error = -ENODEV;
72c2d53192004 (Al Viro             2013-09-22 16:27:52 -0400  810) 		goto cleanup_all;
72c2d53192004 (Al Viro             2013-09-22 16:27:52 -0400  811) 	}
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400  812) 
e3f20ae21079e (Al Viro             2018-07-10 13:25:29 -0400  813) 	error = security_file_open(f);
788e7dd4c22e6 (Yuichi Nakamura     2007-09-14 09:27:07 +0900  814) 	if (error)
788e7dd4c22e6 (Yuichi Nakamura     2007-09-14 09:27:07 +0900  815) 		goto cleanup_all;
788e7dd4c22e6 (Yuichi Nakamura     2007-09-14 09:27:07 +0900  816) 
c568d68341be7 (Miklos Szeredi      2016-09-16 12:44:20 +0200  817) 	error = break_lease(locks_inode(f), f->f_flags);
f3c7691e8d30d (J. Bruce Fields     2011-09-21 10:58:13 -0400  818) 	if (error)
f3c7691e8d30d (J. Bruce Fields     2011-09-21 10:58:13 -0400  819) 		goto cleanup_all;
f3c7691e8d30d (J. Bruce Fields     2011-09-21 10:58:13 -0400  820) 
ea73ea7279884 (Al Viro             2018-07-11 15:00:04 -0400  821) 	/* normally all 3 are set; ->open() can clear them if needed */
ea73ea7279884 (Al Viro             2018-07-11 15:00:04 -0400  822) 	f->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
72c2d53192004 (Al Viro             2013-09-22 16:27:52 -0400  823) 	if (!open)
834f2a4a1554d (Trond Myklebust     2005-10-18 14:20:16 -0700  824) 		open = f->f_op->open;
834f2a4a1554d (Trond Myklebust     2005-10-18 14:20:16 -0700  825) 	if (open) {
834f2a4a1554d (Trond Myklebust     2005-10-18 14:20:16 -0700  826) 		error = open(inode, f);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  827) 		if (error)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  828) 			goto cleanup_all;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  829) 	}
f5d11409e61da (Al Viro             2018-07-09 02:35:08 -0400  830) 	f->f_mode |= FMODE_OPENED;
890275b5eb79e (Mimi Zohar          2010-11-02 10:13:07 -0400  831) 	if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
890275b5eb79e (Mimi Zohar          2010-11-02 10:13:07 -0400  832) 		i_readcount_inc(inode);
293bc9822fa9b (Al Viro             2014-02-11 18:37:41 -0500  833) 	if ((f->f_mode & FMODE_READ) &&
8436318205b9f (Al Viro             2015-04-04 01:14:53 -0400  834) 	     likely(f->f_op->read || f->f_op->read_iter))
7f7f25e82d548 (Al Viro             2014-02-11 17:49:24 -0500  835) 		f->f_mode |= FMODE_CAN_READ;
293bc9822fa9b (Al Viro             2014-02-11 18:37:41 -0500  836) 	if ((f->f_mode & FMODE_WRITE) &&
8436318205b9f (Al Viro             2015-04-04 01:14:53 -0400  837) 	     likely(f->f_op->write || f->f_op->write_iter))
7f7f25e82d548 (Al Viro             2014-02-11 17:49:24 -0500  838) 		f->f_mode |= FMODE_CAN_WRITE;
834f2a4a1554d (Trond Myklebust     2005-10-18 14:20:16 -0700  839) 
c75b1d9421f80 (Jens Axboe          2017-06-27 11:47:04 -0600  840) 	f->f_write_hint = WRITE_LIFE_NOT_SET;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  841) 	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  842) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  843) 	file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
af04fadcaa932 (Al Viro             2018-06-02 01:31:02 -0400  844) 
69527c554f82d (Al Viro             2018-06-08 13:01:49 -0400  845) 	/* NB: we're sure to have correct a_ops only after f_op->open */
69527c554f82d (Al Viro             2018-06-08 13:01:49 -0400  846) 	if (f->f_flags & O_DIRECT) {
69527c554f82d (Al Viro             2018-06-08 13:01:49 -0400  847) 		if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO)
69527c554f82d (Al Viro             2018-06-08 13:01:49 -0400  848) 			return -EINVAL;
69527c554f82d (Al Viro             2018-06-08 13:01:49 -0400  849) 	}
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  850) 
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  851) 	/*
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  852) 	 * XXX: Huge page cache doesn't support writing yet. Drop all page
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  853) 	 * cache for this file before processing writes.
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  854) 	 */
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  855) 	if ((f->f_mode & FMODE_WRITE) && filemap_nr_thps(inode->i_mapping))
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  856) 		truncate_pagecache(inode, 0);
09d91cda0e820 (Song Liu            2019-09-23 15:38:03 -0700  857) 
96b7e579addd3 (Al Viro             2012-06-10 14:22:04 -0400  858) 	return 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  859) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  860) cleanup_all:
6b4e8085c0004 (Al Viro             2018-07-08 21:45:07 -0400  861) 	if (WARN_ON_ONCE(error > 0))
6b4e8085c0004 (Al Viro             2018-07-08 21:45:07 -0400  862) 		error = -EINVAL;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  863) 	fops_put(f->f_op);
83f936c75e368 (Al Viro             2014-03-14 12:02:47 -0400  864) 	if (f->f_mode & FMODE_WRITER) {
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  865) 		put_write_access(inode);
83f936c75e368 (Al Viro             2014-03-14 12:02:47 -0400  866) 		__mnt_drop_write(f->f_path.mnt);
4a3fd211ccfc0 (Dave Hansen         2008-02-15 14:37:48 -0800  867) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  868) cleanup_file:
02e5180d991f2 (Al Viro             2012-06-10 14:32:45 -0400  869) 	path_put(&f->f_path);
02e5180d991f2 (Al Viro             2012-06-10 14:32:45 -0400  870) 	f->f_path.mnt = NULL;
02e5180d991f2 (Al Viro             2012-06-10 14:32:45 -0400  871) 	f->f_path.dentry = NULL;
dd37978c50bc8 (Al Viro             2013-03-01 19:48:30 -0500  872) 	f->f_inode = NULL;
96b7e579addd3 (Al Viro             2012-06-10 14:22:04 -0400  873) 	return error;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  874) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  875) 
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  876) /**
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  877)  * finish_open - finish opening a file
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  878)  * @file: file pointer
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  879)  * @dentry: pointer to dentry
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  880)  * @open: open callback
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  881)  * @opened: state of open
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  882)  *
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  883)  * This can be used to finish opening a file passed to i_op->atomic_open().
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  884)  *
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  885)  * If the open callback is set to NULL, then the standard f_op->open()
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  886)  * filesystem callback is substituted.
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  887)  *
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  888)  * NB: the dentry reference is _not_ consumed.  If, for example, the dentry is
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  889)  * the return value of d_splice_alias(), then the caller needs to perform dput()
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  890)  * on it after finish_open().
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  891)  *
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  892)  * Returns zero on success or -errno if the open failed.
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  893)  */
30d904947459c (Al Viro             2012-06-22 12:40:19 +0400  894) int finish_open(struct file *file, struct dentry *dentry,
be12af3ef5e61 (Al Viro             2018-06-08 11:44:56 -0400  895) 		int (*open)(struct inode *, struct file *))
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  896) {
aad888f828fec (Al Viro             2018-06-08 12:58:04 -0400  897) 	BUG_ON(file->f_mode & FMODE_OPENED); /* once it's opened, it's opened */
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  898) 
b5bcdda32736b (Al Viro             2012-07-20 23:28:46 +0400  899) 	file->f_path.dentry = dentry;
aad888f828fec (Al Viro             2018-06-08 12:58:04 -0400  900) 	return do_dentry_open(file, d_backing_inode(dentry), open);
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  901) }
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  902) EXPORT_SYMBOL(finish_open);
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  903) 
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  904) /**
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  905)  * finish_no_open - finish ->atomic_open() without opening the file
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  906)  *
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  907)  * @file: file pointer
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  908)  * @dentry: dentry or NULL (as returned from ->lookup())
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  909)  *
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  910)  * This can be used to set the result of a successful lookup in ->atomic_open().
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  911)  *
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  912)  * NB: unlike finish_open() this function does consume the dentry reference and
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  913)  * the caller need not dput() it.
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  914)  *
64e1ac4d46f9f (Al Viro             2018-07-09 19:17:52 -0400  915)  * Returns "0" which must be the return value of ->atomic_open() after having
0854d450e229e (Miklos Szeredi      2013-09-16 14:51:55 +0200  916)  * called this function.
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  917)  */
e45198a6ac24b (Al Viro             2012-06-10 06:48:09 -0400  918) int finish_no_open(struct file *file, struct dentry *dentry)
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  919) {
30d904947459c (Al Viro             2012-06-22 12:40:19 +0400  920) 	file->f_path.dentry = dentry;
64e1ac4d46f9f (Al Viro             2018-07-09 19:17:52 -0400  921) 	return 0;
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  922) }
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  923) EXPORT_SYMBOL(finish_no_open);
d18e9008c377d (Miklos Szeredi      2012-06-05 15:10:17 +0200  924) 
9bf39ab2adafd (Miklos Szeredi      2015-06-19 10:29:13 +0200  925) char *file_path(struct file *filp, char *buf, int buflen)
9bf39ab2adafd (Miklos Szeredi      2015-06-19 10:29:13 +0200  926) {
9bf39ab2adafd (Miklos Szeredi      2015-06-19 10:29:13 +0200  927) 	return d_path(&filp->f_path, buf, buflen);
9bf39ab2adafd (Miklos Szeredi      2015-06-19 10:29:13 +0200  928) }
9bf39ab2adafd (Miklos Szeredi      2015-06-19 10:29:13 +0200  929) EXPORT_SYMBOL(file_path);
9bf39ab2adafd (Miklos Szeredi      2015-06-19 10:29:13 +0200  930) 
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  931) /**
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  932)  * vfs_open - open the file at the given path
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  933)  * @path: path to open
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  934)  * @file: newly allocated file with f_flag initialized
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  935)  * @cred: credentials to use
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  936)  */
ae2bb293a3e8a (Al Viro             2018-07-10 13:22:28 -0400  937) int vfs_open(const struct path *path, struct file *file)
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  938) {
54d5ca871e72f (Miklos Szeredi      2016-05-11 01:16:37 +0200  939) 	file->f_path = *path;
a6518f73e60e5 (Miklos Szeredi      2018-07-06 23:57:06 +0200  940) 	return do_dentry_open(file, d_backing_inode(path->dentry), NULL);
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  941) }
4bacc9c9234c7 (David Howells       2015-06-18 14:32:31 +0100  942) 
765927b2d5087 (Al Viro             2012-06-26 21:58:53 +0400  943) struct file *dentry_open(const struct path *path, int flags,
745ca2475a6ac (David Howells       2008-11-14 10:39:22 +1100  944) 			 const struct cred *cred)
a1a5b3d93ca45 (Peter Staubach      2005-09-13 01:25:12 -0700  945) {
a1a5b3d93ca45 (Peter Staubach      2005-09-13 01:25:12 -0700  946) 	int error;
a1a5b3d93ca45 (Peter Staubach      2005-09-13 01:25:12 -0700  947) 	struct file *f;
a1a5b3d93ca45 (Peter Staubach      2005-09-13 01:25:12 -0700  948) 
e0e817392b9ac (David Howells       2009-09-02 09:13:40 +0100  949) 	validate_creds(cred);
e0e817392b9ac (David Howells       2009-09-02 09:13:40 +0100  950) 
c212f9aaf9101 (Tetsuo Handa        2011-01-19 21:08:41 +0900  951) 	/* We must always pass in a valid mount pointer. */
765927b2d5087 (Al Viro             2012-06-26 21:58:53 +0400  952) 	BUG_ON(!path->mnt);
322ee5b36eac4 (Christoph Hellwig   2008-02-15 14:37:24 -0800  953) 
ea73ea7279884 (Al Viro             2018-07-11 15:00:04 -0400  954) 	f = alloc_empty_file(flags, cred);
af04fadcaa932 (Al Viro             2018-06-02 01:31:02 -0400  955) 	if (!IS_ERR(f)) {
ae2bb293a3e8a (Al Viro             2018-07-10 13:22:28 -0400  956) 		error = vfs_open(path, f);
4d27f3266f14e (Al Viro             2018-07-09 11:14:39 -0400  957) 		if (error) {
4d27f3266f14e (Al Viro             2018-07-09 11:14:39 -0400  958) 			fput(f);
af04fadcaa932 (Al Viro             2018-06-02 01:31:02 -0400  959) 			f = ERR_PTR(error);
af04fadcaa932 (Al Viro             2018-06-02 01:31:02 -0400  960) 		}
2a027e7a18738 (Al Viro             2012-06-10 14:24:38 -0400  961) 	}
2a027e7a18738 (Al Viro             2012-06-10 14:24:38 -0400  962) 	return f;
a1a5b3d93ca45 (Peter Staubach      2005-09-13 01:25:12 -0700  963) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  964) EXPORT_SYMBOL(dentry_open);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  965) 
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  966) struct file *open_with_fake_path(const struct path *path, int flags,
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  967) 				struct inode *inode, const struct cred *cred)
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  968) {
d3b1084dfd629 (Miklos Szeredi      2018-07-18 15:44:40 +0200  969) 	struct file *f = alloc_empty_file_noaccount(flags, cred);
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  970) 	if (!IS_ERR(f)) {
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  971) 		int error;
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  972) 
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  973) 		f->f_path = *path;
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  974) 		error = do_dentry_open(f, inode, NULL);
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  975) 		if (error) {
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  976) 			fput(f);
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  977) 			f = ERR_PTR(error);
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  978) 		}
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  979) 	}
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  980) 	return f;
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  981) }
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  982) EXPORT_SYMBOL(open_with_fake_path);
2abc77af89e17 (Al Viro             2018-07-12 11:18:42 -0400  983) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  984) #define WILL_CREATE(flags)	(flags & (O_CREAT | __O_TMPFILE))
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  985) #define O_PATH_FLAGS		(O_DIRECTORY | O_NOFOLLOW | O_PATH | O_CLOEXEC)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  986) 
35cb6d54c1d5d (Jens Axboe          2019-12-13 11:10:11 -0700  987) inline struct open_how build_open_how(int flags, umode_t mode)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  988) {
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  989) 	struct open_how how = {
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  990) 		.flags = flags & VALID_OPEN_FLAGS,
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  991) 		.mode = mode & S_IALLUGO,
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  992) 	};
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  993) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  994) 	/* O_PATH beats everything else. */
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  995) 	if (how.flags & O_PATH)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  996) 		how.flags &= O_PATH_FLAGS;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  997) 	/* Modes should only be set for create-like flags. */
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  998) 	if (!WILL_CREATE(how.flags))
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100  999) 		how.mode = 0;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1000) 	return how;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1001) }
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1002) 
35cb6d54c1d5d (Jens Axboe          2019-12-13 11:10:11 -0700 1003) inline int build_open_flags(const struct open_how *how, struct open_flags *op)
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1004) {
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1005) 	u64 flags = how->flags;
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1006) 	u64 strip = FMODE_NONOTIFY | O_CLOEXEC;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1007) 	int lookup_flags = 0;
62fb4a155f745 (Al Viro             2015-12-26 22:33:24 -0500 1008) 	int acc_mode = ACC_MODE(flags);
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1009) 
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1010) 	BUILD_BUG_ON_MSG(upper_32_bits(VALID_OPEN_FLAGS),
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1011) 			 "struct open_flags doesn't yet handle flags > 32 bits");
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1012) 
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1013) 	/*
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1014) 	 * Strip flags that either shouldn't be set by userspace like
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1015) 	 * FMODE_NONOTIFY or that aren't relevant in determining struct
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1016) 	 * open_flags like O_CLOEXEC.
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1017) 	 */
2b2a31cad66c1 (Christian Brauner   2021-05-28 11:24:16 +0200 1018) 	flags &= ~strip;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1019) 
629e014bb8349 (Christoph Hellwig   2017-04-27 09:42:25 +0200 1020) 	/*
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1021) 	 * Older syscalls implicitly clear all of the invalid flags or argument
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1022) 	 * values before calling build_open_flags(), but openat2(2) checks all
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1023) 	 * of its arguments.
629e014bb8349 (Christoph Hellwig   2017-04-27 09:42:25 +0200 1024) 	 */
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1025) 	if (flags & ~VALID_OPEN_FLAGS)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1026) 		return -EINVAL;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1027) 	if (how->resolve & ~VALID_RESOLVE_FLAGS)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1028) 		return -EINVAL;
629e014bb8349 (Christoph Hellwig   2017-04-27 09:42:25 +0200 1029) 
398840f8bb935 (Aleksa Sarai        2020-10-28 10:50:43 +1100 1030) 	/* Scoping flags are mutually exclusive. */
398840f8bb935 (Aleksa Sarai        2020-10-28 10:50:43 +1100 1031) 	if ((how->resolve & RESOLVE_BENEATH) && (how->resolve & RESOLVE_IN_ROOT))
398840f8bb935 (Aleksa Sarai        2020-10-28 10:50:43 +1100 1032) 		return -EINVAL;
398840f8bb935 (Aleksa Sarai        2020-10-28 10:50:43 +1100 1033) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1034) 	/* Deal with the mode. */
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1035) 	if (WILL_CREATE(flags)) {
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1036) 		if (how->mode & ~S_IALLUGO)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1037) 			return -EINVAL;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1038) 		op->mode = how->mode | S_IFREG;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1039) 	} else {
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1040) 		if (how->mode != 0)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1041) 			return -EINVAL;
e68726ff72cf7 (Miklos Szeredi      2012-08-15 13:01:24 +0200 1042) 		op->mode = 0;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1043) 	}
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1044) 
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1045) 	/*
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1046) 	 * In order to ensure programs get explicit errors when trying to use
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1047) 	 * O_TMPFILE on old kernels, O_TMPFILE is implemented such that it
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1048) 	 * looks like (O_DIRECTORY|O_RDWR & ~O_CREAT) to old kernels. But we
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1049) 	 * have to require userspace to explicitly set it.
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1050) 	 */
bb458c644a59d (Al Viro             2013-07-13 13:26:37 +0400 1051) 	if (flags & __O_TMPFILE) {
bb458c644a59d (Al Viro             2013-07-13 13:26:37 +0400 1052) 		if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
60545d0d4610b (Al Viro             2013-06-07 01:20:27 -0400 1053) 			return -EINVAL;
ba57ea64cb182 (Al Viro             2013-07-20 03:11:32 +0400 1054) 		if (!(acc_mode & MAY_WRITE))
ba57ea64cb182 (Al Viro             2013-07-20 03:11:32 +0400 1055) 			return -EINVAL;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1056) 	}
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1057) 	if (flags & O_PATH) {
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1058) 		/* O_PATH only permits certain other flags to be set. */
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1059) 		if (flags & ~O_PATH_FLAGS)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1060) 			return -EINVAL;
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1061) 		acc_mode = 0;
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1062) 	}
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1063) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1064) 	/*
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1065) 	 * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1066) 	 * check for O_DSYNC if the need any syncing at all we enforce it's
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1067) 	 * always set instead of having to deal with possibly weird behaviour
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1068) 	 * for malicious applications setting only __O_SYNC.
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1069) 	 */
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1070) 	if (flags & __O_SYNC)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1071) 		flags |= O_DSYNC;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1072) 
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1073) 	op->open_flag = flags;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1074) 
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1075) 	/* O_TRUNC implies we need access checks for write permissions */
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1076) 	if (flags & O_TRUNC)
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1077) 		acc_mode |= MAY_WRITE;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1078) 
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1079) 	/* Allow the LSM permission hook to distinguish append
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1080) 	   access from general write access. */
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1081) 	if (flags & O_APPEND)
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1082) 		acc_mode |= MAY_APPEND;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1083) 
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1084) 	op->acc_mode = acc_mode;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1085) 
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1086) 	op->intent = flags & O_PATH ? 0 : LOOKUP_OPEN;
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1087) 
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1088) 	if (flags & O_CREAT) {
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1089) 		op->intent |= LOOKUP_CREATE;
31d1726d72500 (Al Viro             2020-01-08 20:19:38 -0500 1090) 		if (flags & O_EXCL) {
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1091) 			op->intent |= LOOKUP_EXCL;
31d1726d72500 (Al Viro             2020-01-08 20:19:38 -0500 1092) 			flags |= O_NOFOLLOW;
31d1726d72500 (Al Viro             2020-01-08 20:19:38 -0500 1093) 		}
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1094) 	}
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1095) 
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1096) 	if (flags & O_DIRECTORY)
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1097) 		lookup_flags |= LOOKUP_DIRECTORY;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1098) 	if (!(flags & O_NOFOLLOW))
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1099) 		lookup_flags |= LOOKUP_FOLLOW;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1100) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1101) 	if (how->resolve & RESOLVE_NO_XDEV)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1102) 		lookup_flags |= LOOKUP_NO_XDEV;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1103) 	if (how->resolve & RESOLVE_NO_MAGICLINKS)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1104) 		lookup_flags |= LOOKUP_NO_MAGICLINKS;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1105) 	if (how->resolve & RESOLVE_NO_SYMLINKS)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1106) 		lookup_flags |= LOOKUP_NO_SYMLINKS;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1107) 	if (how->resolve & RESOLVE_BENEATH)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1108) 		lookup_flags |= LOOKUP_BENEATH;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1109) 	if (how->resolve & RESOLVE_IN_ROOT)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1110) 		lookup_flags |= LOOKUP_IN_ROOT;
99668f6180628 (Jens Axboe          2020-12-17 09:19:10 -0700 1111) 	if (how->resolve & RESOLVE_CACHED) {
99668f6180628 (Jens Axboe          2020-12-17 09:19:10 -0700 1112) 		/* Don't bother even trying for create/truncate/tmpfile open */
99668f6180628 (Jens Axboe          2020-12-17 09:19:10 -0700 1113) 		if (flags & (O_TRUNC | O_CREAT | O_TMPFILE))
99668f6180628 (Jens Axboe          2020-12-17 09:19:10 -0700 1114) 			return -EAGAIN;
99668f6180628 (Jens Axboe          2020-12-17 09:19:10 -0700 1115) 		lookup_flags |= LOOKUP_CACHED;
99668f6180628 (Jens Axboe          2020-12-17 09:19:10 -0700 1116) 	}
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1117) 
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1118) 	op->lookup_flags = lookup_flags;
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1119) 	return 0;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1120) }
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1121) 
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1122) /**
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1123)  * file_open_name - open file and return file pointer
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1124)  *
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1125)  * @name:	struct filename containing path to open
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1126)  * @flags:	open flags as per the open(2) second argument
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1127)  * @mode:	mode for the new file if O_CREAT is set, else ignored
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1128)  *
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1129)  * This is the helper to open a file from kernelspace if you really
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1130)  * have to.  But in generally you should not do this, so please move
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1131)  * along, nothing to see here..
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1132)  */
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1133) struct file *file_open_name(struct filename *name, int flags, umode_t mode)
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1134) {
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1135) 	struct open_flags op;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1136) 	struct open_how how = build_open_how(flags, mode);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1137) 	int err = build_open_flags(&how, &op);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1138) 	if (err)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1139) 		return ERR_PTR(err);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1140) 	return do_filp_open(AT_FDCWD, name, &op);
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1141) }
669abf4e5539c (Jeff Layton         2012-10-10 16:43:10 -0400 1142) 
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1143) /**
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1144)  * filp_open - open file and return file pointer
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1145)  *
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1146)  * @filename:	path to open
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1147)  * @flags:	open flags as per the open(2) second argument
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1148)  * @mode:	mode for the new file if O_CREAT is set, else ignored
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1149)  *
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1150)  * This is the helper to open a file from kernelspace if you really
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1151)  * have to.  But in generally you should not do this, so please move
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1152)  * along, nothing to see here..
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1153)  */
a218d0fdc5f90 (Al Viro             2011-11-21 14:59:34 -0500 1154) struct file *filp_open(const char *filename, int flags, umode_t mode)
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1155) {
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1156) 	struct filename *name = getname_kernel(filename);
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1157) 	struct file *file = ERR_CAST(name);
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1158) 	
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1159) 	if (!IS_ERR(name)) {
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1160) 		file = file_open_name(name, flags, mode);
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1161) 		putname(name);
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1162) 	}
5168910413830 (Paul Moore          2015-01-22 00:00:03 -0500 1163) 	return file;
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1164) }
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1165) EXPORT_SYMBOL(filp_open);
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1166) 
73d049a40fc62 (Al Viro             2011-03-11 12:08:24 -0500 1167) struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
378c6520e7d29 (Jann Horn           2016-03-22 14:25:36 -0700 1168) 			    const char *filename, int flags, umode_t mode)
73d049a40fc62 (Al Viro             2011-03-11 12:08:24 -0500 1169) {
73d049a40fc62 (Al Viro             2011-03-11 12:08:24 -0500 1170) 	struct open_flags op;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1171) 	struct open_how how = build_open_how(flags, mode);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1172) 	int err = build_open_flags(&how, &op);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1173) 	if (err)
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1174) 		return ERR_PTR(err);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1175) 	return do_file_open_root(dentry, mnt, filename, &op);
73d049a40fc62 (Al Viro             2011-03-11 12:08:24 -0500 1176) }
73d049a40fc62 (Al Viro             2011-03-11 12:08:24 -0500 1177) EXPORT_SYMBOL(file_open_root);
73d049a40fc62 (Al Viro             2011-03-11 12:08:24 -0500 1178) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1179) static long do_sys_openat2(int dfd, const char __user *filename,
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1180) 			   struct open_how *how)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1181) {
47c805dc2d2df (Al Viro             2011-02-23 17:44:09 -0500 1182) 	struct open_flags op;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1183) 	int fd = build_open_flags(how, &op);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1184) 	struct filename *tmp;
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1185) 
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1186) 	if (fd)
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1187) 		return fd;
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1188) 
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1189) 	tmp = getname(filename);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1190) 	if (IS_ERR(tmp))
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1191) 		return PTR_ERR(tmp);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1192) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1193) 	fd = get_unused_fd_flags(how->flags);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1194) 	if (fd >= 0) {
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1195) 		struct file *f = do_filp_open(dfd, tmp, &op);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1196) 		if (IS_ERR(f)) {
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1197) 			put_unused_fd(fd);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1198) 			fd = PTR_ERR(f);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1199) 		} else {
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1200) 			fsnotify_open(f);
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1201) 			fd_install(fd, f);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1202) 		}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1203) 	}
f9652e10c12b4 (Al Viro             2013-06-11 08:23:01 +0400 1204) 	putname(tmp);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1205) 	return fd;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1206) }
e922efc342d56 (Miklos Szeredi      2005-09-06 15:18:25 -0700 1207) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1208) long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
e922efc342d56 (Miklos Szeredi      2005-09-06 15:18:25 -0700 1209) {
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1210) 	struct open_how how = build_open_how(flags, mode);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1211) 	return do_sys_openat2(dfd, filename, &how);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1212) }
e922efc342d56 (Miklos Szeredi      2005-09-06 15:18:25 -0700 1213) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1214) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1215) SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1216) {
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1217) 	if (force_o_largefile())
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1218) 		flags |= O_LARGEFILE;
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1219) 	return do_sys_open(AT_FDCWD, filename, flags, mode);
e922efc342d56 (Miklos Szeredi      2005-09-06 15:18:25 -0700 1220) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1221) 
6559eed8ca7db (Heiko Carstens      2009-01-14 14:14:32 +0100 1222) SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags,
a218d0fdc5f90 (Al Viro             2011-11-21 14:59:34 -0500 1223) 		umode_t, mode)
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800 1224) {
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800 1225) 	if (force_o_largefile())
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800 1226) 		flags |= O_LARGEFILE;
2cf0966683430 (Al Viro             2013-01-21 15:25:54 -0500 1227) 	return do_sys_open(dfd, filename, flags, mode);
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800 1228) }
5590ff0d5528b (Ulrich Drepper      2006-01-18 17:43:53 -0800 1229) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1230) SYSCALL_DEFINE4(openat2, int, dfd, const char __user *, filename,
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1231) 		struct open_how __user *, how, size_t, usize)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1232) {
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1233) 	int err;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1234) 	struct open_how tmp;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1235) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1236) 	BUILD_BUG_ON(sizeof(struct open_how) < OPEN_HOW_SIZE_VER0);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1237) 	BUILD_BUG_ON(sizeof(struct open_how) != OPEN_HOW_SIZE_LATEST);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1238) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1239) 	if (unlikely(usize < OPEN_HOW_SIZE_VER0))
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1240) 		return -EINVAL;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1241) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1242) 	err = copy_struct_from_user(&tmp, sizeof(tmp), how, usize);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1243) 	if (err)
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1244) 		return err;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1245) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1246) 	/* O_LARGEFILE is only allowed for non-O_PATH. */
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1247) 	if (!(tmp.flags & O_PATH) && force_o_largefile())
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1248) 		tmp.flags |= O_LARGEFILE;
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1249) 
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1250) 	return do_sys_openat2(dfd, filename, &tmp);
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1251) }
fddb5d430ad9f (Aleksa Sarai        2020-01-18 23:07:59 +1100 1252) 
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1253) #ifdef CONFIG_COMPAT
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1254) /*
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1255)  * Exactly like sys_open(), except that it doesn't set the
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1256)  * O_LARGEFILE flag.
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1257)  */
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1258) COMPAT_SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1259) {
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1260) 	return do_sys_open(AT_FDCWD, filename, flags, mode);
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1261) }
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1262) 
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1263) /*
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1264)  * Exactly like sys_openat(), except that it doesn't set the
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1265)  * O_LARGEFILE flag.
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1266)  */
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1267) COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1268) {
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1269) 	return do_sys_open(dfd, filename, flags, mode);
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1270) }
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1271) #endif
e35d49f637d5c (Al Viro             2017-04-08 18:15:12 -0400 1272) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1273) #ifndef __alpha__
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1274) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1275) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1276)  * For backward compatibility?  Maybe this should be moved
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1277)  * into arch/i386 instead?
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1278)  */
a218d0fdc5f90 (Al Viro             2011-11-21 14:59:34 -0500 1279) SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1280) {
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1281) 	int flags = O_CREAT | O_WRONLY | O_TRUNC;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1282) 
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1283) 	if (force_o_largefile())
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1284) 		flags |= O_LARGEFILE;
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1285) 	return do_sys_open(AT_FDCWD, pathname, flags, mode);
166e07c37c641 (Christoph Hellwig   2020-06-06 15:03:21 +0200 1286) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1287) #endif
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1288) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1289) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1290)  * "id" is the POSIX thread ID. We use the
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1291)  * files pointer for this..
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1292)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1293) int filp_close(struct file *filp, fl_owner_t id)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1294) {
45778ca819acc (Christoph Lameter   2005-06-23 00:10:17 -0700 1295) 	int retval = 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1296) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1297) 	if (!file_count(filp)) {
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1298) 		printk(KERN_ERR "VFS: Close: file count is 0\n");
45778ca819acc (Christoph Lameter   2005-06-23 00:10:17 -0700 1299) 		return 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1300) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1301) 
72c2d53192004 (Al Viro             2013-09-22 16:27:52 -0400 1302) 	if (filp->f_op->flush)
75e1fcc0b18df (Miklos Szeredi      2006-06-23 02:05:12 -0700 1303) 		retval = filp->f_op->flush(filp, id);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1304) 
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1305) 	if (likely(!(filp->f_mode & FMODE_PATH))) {
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1306) 		dnotify_flush(filp, id);
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1307) 		locks_remove_posix(filp, id);
1abf0c718f15a (Al Viro             2011-03-13 03:51:11 -0400 1308) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1309) 	fput(filp);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1310) 	return retval;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1311) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1312) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1313) EXPORT_SYMBOL(filp_close);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1314) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1315) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1316)  * Careful here! We test whether the file pointer is NULL before
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1317)  * releasing the fd. This ensures that one clone task can't release
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1318)  * an fd while another clone is opening it.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1319)  */
ca013e945b1ba (Heiko Carstens      2009-01-14 14:14:19 +0100 1320) SYSCALL_DEFINE1(close, unsigned int, fd)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1321) {
8760c909f54a8 (Eric W. Biederman   2020-11-20 17:14:38 -0600 1322) 	int retval = close_fd(fd);
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1323) 
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1324) 	/* can't restart close syscall because file table entry was cleared */
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1325) 	if (unlikely(retval == -ERESTARTSYS ||
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1326) 		     retval == -ERESTARTNOINTR ||
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1327) 		     retval == -ERESTARTNOHAND ||
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1328) 		     retval == -ERESTART_RESTARTBLOCK))
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1329) 		retval = -EINTR;
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1330) 
ee731f4f7880b (Ernie Petrides      2006-09-29 02:00:13 -0700 1331) 	return retval;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1332) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1333) 
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1334) /**
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1335)  * close_range() - Close all file descriptors in a given range.
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1336)  *
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1337)  * @fd:     starting file descriptor to close
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1338)  * @max_fd: last file descriptor to close
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1339)  * @flags:  reserved for future extensions
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1340)  *
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1341)  * This closes a range of file descriptors. All file descriptors
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1342)  * from @fd up to and including @max_fd are closed.
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1343)  * Currently, errors to close a given file descriptor are ignored.
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1344)  */
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1345) SYSCALL_DEFINE3(close_range, unsigned int, fd, unsigned int, max_fd,
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1346) 		unsigned int, flags)
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1347) {
60997c3d45d9a (Christian Brauner   2020-06-03 21:48:55 +0200 1348) 	return __close_range(fd, max_fd, flags);
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1349) }
278a5fbaed89d (Christian Brauner   2019-05-24 11:30:34 +0200 1350) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1351) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1352)  * This routine simulates a hangup on the tty, to arrange that users
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1353)  * are given clean terminals at login time.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1354)  */
ca013e945b1ba (Heiko Carstens      2009-01-14 14:14:19 +0100 1355) SYSCALL_DEFINE0(vhangup)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1356) {
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1357) 	if (capable(CAP_SYS_TTY_CONFIG)) {
2cb5998b5f0cc (Alan Cox            2008-10-13 10:40:30 +0100 1358) 		tty_vhangup_self();
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1359) 		return 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1360) 	}
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1361) 	return -EPERM;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1362) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1363) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1364) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1365)  * Called when an inode is about to be open.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1366)  * We use this to disallow opening large files on 32bit systems if
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1367)  * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1368)  * on this flag in sys_open.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1369)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1370) int generic_file_open(struct inode * inode, struct file * filp)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1371) {
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1372) 	if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
a9c62a18a2914 (Alan Cox            2007-10-16 23:30:22 -0700 1373) 		return -EOVERFLOW;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1374) 	return 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1375) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1376) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1377) EXPORT_SYMBOL(generic_file_open);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1378) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1379) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1380)  * This is used by subsystems that don't want seekable
06b1e104b7ea1 (Dmitry Torokhov     2010-08-10 18:01:33 -0700 1381)  * file descriptors. The function is not supposed to ever fail, the only
06b1e104b7ea1 (Dmitry Torokhov     2010-08-10 18:01:33 -0700 1382)  * reason it returns an 'int' and not 'void' is so that it can be plugged
06b1e104b7ea1 (Dmitry Torokhov     2010-08-10 18:01:33 -0700 1383)  * directly into file_operations structure.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1384)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1385) int nonseekable_open(struct inode *inode, struct file *filp)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1386) {
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1387) 	filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1388) 	return 0;
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1389) }
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1390) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 1391) EXPORT_SYMBOL(nonseekable_open);
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1392) 
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1393) /*
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1394)  * stream_open is used by subsystems that want stream-like file descriptors.
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1395)  * Such file descriptors are not seekable and don't have notion of position
438ab720c675a (Kirill Smelkov      2019-04-12 12:31:57 +0300 1396)  * (file.f_pos is always 0 and ppos passed to .read()/.write() is always NULL).
438ab720c675a (Kirill Smelkov      2019-04-12 12:31:57 +0300 1397)  * Contrary to file descriptors of other regular files, .read() and .write()
438ab720c675a (Kirill Smelkov      2019-04-12 12:31:57 +0300 1398)  * can run simultaneously.
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1399)  *
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1400)  * stream_open never fails and is marked to return int so that it could be
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1401)  * directly used as file_operations.open .
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1402)  */
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1403) int stream_open(struct inode *inode, struct file *filp)
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1404) {
2be7d348fe924 (Linus Torvalds      2019-11-26 11:34:06 -0800 1405) 	filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE | FMODE_ATOMIC_POS);
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1406) 	filp->f_mode |= FMODE_STREAM;
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1407) 	return 0;
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1408) }
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1409) 
10dce8af34226 (Kirill Smelkov      2019-03-26 22:20:43 +0000 1410) EXPORT_SYMBOL(stream_open);