xref: /openbmc/linux/fs/open.c (revision 207f135d)
1457c8996SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *  linux/fs/open.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *  Copyright (C) 1991, 1992  Linus Torvalds
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #include <linux/string.h>
91da177e4SLinus Torvalds #include <linux/mm.h>
101da177e4SLinus Torvalds #include <linux/file.h>
119f3acc31SAl Viro #include <linux/fdtable.h>
120eeca283SRobert Love #include <linux/fsnotify.h>
131da177e4SLinus Torvalds #include <linux/module.h>
141da177e4SLinus Torvalds #include <linux/tty.h>
151da177e4SLinus Torvalds #include <linux/namei.h>
161da177e4SLinus Torvalds #include <linux/backing-dev.h>
1716f7e0feSRandy Dunlap #include <linux/capability.h>
18086f7316SAndrew G. Morgan #include <linux/securebits.h>
191da177e4SLinus Torvalds #include <linux/security.h>
201da177e4SLinus Torvalds #include <linux/mount.h>
215590ff0dSUlrich Drepper #include <linux/fcntl.h>
225a0e3ad6STejun Heo #include <linux/slab.h>
237c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
241da177e4SLinus Torvalds #include <linux/fs.h>
25ef3daedaSYoav Zach #include <linux/personality.h>
261da177e4SLinus Torvalds #include <linux/pagemap.h>
271da177e4SLinus Torvalds #include <linux/syscalls.h>
28ab2af1f5SDipankar Sarma #include <linux/rcupdate.h>
2973241cccSAmy Griffis #include <linux/audit.h>
3097ac7350SAmit Arora #include <linux/falloc.h>
315ad4e53bSAl Viro #include <linux/fs_struct.h>
32b65a9cfcSAl Viro #include <linux/ima.h>
332dfc1caeSEric Paris #include <linux/dnotify.h>
343f6d078dSAl Viro #include <linux/compat.h>
35a793d79eSChristian Brauner #include <linux/mnt_idmapping.h>
365970e15dSJeff Layton #include <linux/filelock.h>
371da177e4SLinus Torvalds 
38e81e3f4dSEric Paris #include "internal.h"
39e81e3f4dSEric Paris 
do_truncate(struct mnt_idmap * idmap,struct dentry * dentry,loff_t length,unsigned int time_attrs,struct file * filp)40abf08576SChristian Brauner int do_truncate(struct mnt_idmap *idmap, struct dentry *dentry,
41643fe55aSChristian Brauner 		loff_t length, unsigned int time_attrs, struct file *filp)
421da177e4SLinus Torvalds {
43939a9421SAmerigo Wang 	int ret;
441da177e4SLinus Torvalds 	struct iattr newattrs;
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds 	/* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
471da177e4SLinus Torvalds 	if (length < 0)
481da177e4SLinus Torvalds 		return -EINVAL;
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds 	newattrs.ia_size = length;
514a30131eSNeilBrown 	newattrs.ia_valid = ATTR_SIZE | time_attrs;
52cc4e69deSMiklos Szeredi 	if (filp) {
53cc4e69deSMiklos Szeredi 		newattrs.ia_file = filp;
54cc4e69deSMiklos Szeredi 		newattrs.ia_valid |= ATTR_FILE;
55cc4e69deSMiklos Szeredi 	}
561da177e4SLinus Torvalds 
5745f147a1SJan Kara 	/* Remove suid, sgid, and file capabilities on truncate too */
589452e93eSChristian Brauner 	ret = dentry_needs_remove_privs(idmap, dentry);
5945f147a1SJan Kara 	if (ret < 0)
6045f147a1SJan Kara 		return ret;
61939a9421SAmerigo Wang 	if (ret)
62939a9421SAmerigo Wang 		newattrs.ia_valid |= ret | ATTR_FORCE;
637b82dc0eSLinus Torvalds 
645955102cSAl Viro 	inode_lock(dentry->d_inode);
6527ac0ffeSJ. Bruce Fields 	/* Note any delegations or leases have already been broken: */
66abf08576SChristian Brauner 	ret = notify_change(idmap, dentry, &newattrs, NULL);
675955102cSAl Viro 	inode_unlock(dentry->d_inode);
68939a9421SAmerigo Wang 	return ret;
691da177e4SLinus Torvalds }
701da177e4SLinus Torvalds 
vfs_truncate(const struct path * path,loff_t length)717df818b2SAl Viro long vfs_truncate(const struct path *path, loff_t length)
721da177e4SLinus Torvalds {
73abf08576SChristian Brauner 	struct mnt_idmap *idmap;
741da177e4SLinus Torvalds 	struct inode *inode;
75a02de960SDavid Howells 	long error;
761da177e4SLinus Torvalds 
77a02de960SDavid Howells 	inode = path->dentry->d_inode;
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds 	/* For directories it's -EISDIR, for other non-regulars - -EINVAL */
801da177e4SLinus Torvalds 	if (S_ISDIR(inode->i_mode))
81a02de960SDavid Howells 		return -EISDIR;
821da177e4SLinus Torvalds 	if (!S_ISREG(inode->i_mode))
83a02de960SDavid Howells 		return -EINVAL;
841da177e4SLinus Torvalds 
85a02de960SDavid Howells 	error = mnt_want_write(path->mnt);
861da177e4SLinus Torvalds 	if (error)
87a02de960SDavid Howells 		goto out;
881da177e4SLinus Torvalds 
89abf08576SChristian Brauner 	idmap = mnt_idmap(path->mnt);
904609e1f1SChristian Brauner 	error = inode_permission(idmap, inode, MAY_WRITE);
919ac9b847SDave Hansen 	if (error)
929ac9b847SDave Hansen 		goto mnt_drop_write_and_out;
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds 	error = -EPERM;
95c82e42daSMiklos Szeredi 	if (IS_APPEND(inode))
969ac9b847SDave Hansen 		goto mnt_drop_write_and_out;
971da177e4SLinus Torvalds 
988cf9ee50SMiklos Szeredi 	error = get_write_access(inode);
991da177e4SLinus Torvalds 	if (error)
1009ac9b847SDave Hansen 		goto mnt_drop_write_and_out;
1011da177e4SLinus Torvalds 
1029700382cSdavid m. richter 	/*
1039700382cSdavid m. richter 	 * Make sure that there are no leases.  get_write_access() protects
1049700382cSdavid m. richter 	 * against the truncate racing with a lease-granting setlease().
1059700382cSdavid m. richter 	 */
1068737c930SAl Viro 	error = break_lease(inode, O_WRONLY);
1079700382cSdavid m. richter 	if (error)
1089700382cSdavid m. richter 		goto put_write_and_out;
1099700382cSdavid m. richter 
110a02de960SDavid Howells 	error = security_path_truncate(path);
111907f4554SChristoph Hellwig 	if (!error)
112abf08576SChristian Brauner 		error = do_truncate(idmap, path->dentry, length, 0, NULL);
1131da177e4SLinus Torvalds 
1149700382cSdavid m. richter put_write_and_out:
1158cf9ee50SMiklos Szeredi 	put_write_access(inode);
1169ac9b847SDave Hansen mnt_drop_write_and_out:
117a02de960SDavid Howells 	mnt_drop_write(path->mnt);
1181da177e4SLinus Torvalds out:
1191da177e4SLinus Torvalds 	return error;
1201da177e4SLinus Torvalds }
121a02de960SDavid Howells EXPORT_SYMBOL_GPL(vfs_truncate);
122a02de960SDavid Howells 
do_sys_truncate(const char __user * pathname,loff_t length)123df260e21SDominik Brodowski long do_sys_truncate(const char __user *pathname, loff_t length)
124a02de960SDavid Howells {
12548f7530dSJeff Layton 	unsigned int lookup_flags = LOOKUP_FOLLOW;
126a02de960SDavid Howells 	struct path path;
127a02de960SDavid Howells 	int error;
128a02de960SDavid Howells 
129a02de960SDavid Howells 	if (length < 0)	/* sorry, but loff_t says... */
130a02de960SDavid Howells 		return -EINVAL;
131a02de960SDavid Howells 
13248f7530dSJeff Layton retry:
13348f7530dSJeff Layton 	error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
134a02de960SDavid Howells 	if (!error) {
135a02de960SDavid Howells 		error = vfs_truncate(&path, length);
136a02de960SDavid Howells 		path_put(&path);
137a02de960SDavid Howells 	}
13848f7530dSJeff Layton 	if (retry_estale(error, lookup_flags)) {
13948f7530dSJeff Layton 		lookup_flags |= LOOKUP_REVAL;
14048f7530dSJeff Layton 		goto retry;
14148f7530dSJeff Layton 	}
142a02de960SDavid Howells 	return error;
143a02de960SDavid Howells }
1441da177e4SLinus Torvalds 
SYSCALL_DEFINE2(truncate,const char __user *,path,long,length)1454fd8da8dSHeiko Carstens SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
1461da177e4SLinus Torvalds {
1474fd8da8dSHeiko Carstens 	return do_sys_truncate(path, length);
1481da177e4SLinus Torvalds }
1491da177e4SLinus Torvalds 
1503f6d078dSAl Viro #ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE2(truncate,const char __user *,path,compat_off_t,length)1513f6d078dSAl Viro COMPAT_SYSCALL_DEFINE2(truncate, const char __user *, path, compat_off_t, length)
1523f6d078dSAl Viro {
1533f6d078dSAl Viro 	return do_sys_truncate(path, length);
1543f6d078dSAl Viro }
1553f6d078dSAl Viro #endif
1563f6d078dSAl Viro 
do_sys_ftruncate(unsigned int fd,loff_t length,int small)157411d9475SDominik Brodowski long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
1581da177e4SLinus Torvalds {
1591da177e4SLinus Torvalds 	struct inode *inode;
1601da177e4SLinus Torvalds 	struct dentry *dentry;
1612903ff01SAl Viro 	struct fd f;
1621da177e4SLinus Torvalds 	int error;
1631da177e4SLinus Torvalds 
1641da177e4SLinus Torvalds 	error = -EINVAL;
1651da177e4SLinus Torvalds 	if (length < 0)
1661da177e4SLinus Torvalds 		goto out;
1671da177e4SLinus Torvalds 	error = -EBADF;
1682903ff01SAl Viro 	f = fdget(fd);
1692903ff01SAl Viro 	if (!f.file)
1701da177e4SLinus Torvalds 		goto out;
1711da177e4SLinus Torvalds 
1721da177e4SLinus Torvalds 	/* explicitly opened as large or we are on 64-bit box */
1732903ff01SAl Viro 	if (f.file->f_flags & O_LARGEFILE)
1741da177e4SLinus Torvalds 		small = 0;
1751da177e4SLinus Torvalds 
1762903ff01SAl Viro 	dentry = f.file->f_path.dentry;
1771da177e4SLinus Torvalds 	inode = dentry->d_inode;
1781da177e4SLinus Torvalds 	error = -EINVAL;
1792903ff01SAl Viro 	if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE))
1801da177e4SLinus Torvalds 		goto out_putf;
1811da177e4SLinus Torvalds 
1821da177e4SLinus Torvalds 	error = -EINVAL;
1831da177e4SLinus Torvalds 	/* Cannot ftruncate over 2^31 bytes without large file support */
1841da177e4SLinus Torvalds 	if (small && length > MAX_NON_LFS)
1851da177e4SLinus Torvalds 		goto out_putf;
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds 	error = -EPERM;
18878757af6SAmir Goldstein 	/* Check IS_APPEND on real upper inode */
18978757af6SAmir Goldstein 	if (IS_APPEND(file_inode(f.file)))
1901da177e4SLinus Torvalds 		goto out_putf;
19114da9200SJan Kara 	sb_start_write(inode->i_sb);
1923350607dSGünther Noack 	error = security_file_truncate(f.file);
193be6d3e56SKentaro Takeda 	if (!error)
194abf08576SChristian Brauner 		error = do_truncate(file_mnt_idmap(f.file), dentry, length,
195643fe55aSChristian Brauner 				    ATTR_MTIME | ATTR_CTIME, f.file);
19614da9200SJan Kara 	sb_end_write(inode->i_sb);
1971da177e4SLinus Torvalds out_putf:
1982903ff01SAl Viro 	fdput(f);
1991da177e4SLinus Torvalds out:
2001da177e4SLinus Torvalds 	return error;
2011da177e4SLinus Torvalds }
2021da177e4SLinus Torvalds 
SYSCALL_DEFINE2(ftruncate,unsigned int,fd,unsigned long,length)203bdc480e3SHeiko Carstens SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length)
2041da177e4SLinus Torvalds {
2052cf09666SAl Viro 	return do_sys_ftruncate(fd, length, 1);
2061da177e4SLinus Torvalds }
2071da177e4SLinus Torvalds 
2083f6d078dSAl Viro #ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE2(ftruncate,unsigned int,fd,compat_ulong_t,length)2093f6d078dSAl Viro COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length)
2103f6d078dSAl Viro {
2113f6d078dSAl Viro 	return do_sys_ftruncate(fd, length, 1);
2123f6d078dSAl Viro }
2133f6d078dSAl Viro #endif
2143f6d078dSAl Viro 
2151da177e4SLinus Torvalds /* LFS versions of truncate are only needed on 32 bit machines */
2161da177e4SLinus Torvalds #if BITS_PER_LONG == 32
SYSCALL_DEFINE2(truncate64,const char __user *,path,loff_t,length)2174a0fd5bfSAl Viro SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length)
2181da177e4SLinus Torvalds {
2191da177e4SLinus Torvalds 	return do_sys_truncate(path, length);
2201da177e4SLinus Torvalds }
2211da177e4SLinus Torvalds 
SYSCALL_DEFINE2(ftruncate64,unsigned int,fd,loff_t,length)2224a0fd5bfSAl Viro SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
2231da177e4SLinus Torvalds {
2242cf09666SAl Viro 	return do_sys_ftruncate(fd, length, 0);
2251da177e4SLinus Torvalds }
2266673e0c3SHeiko Carstens #endif /* BITS_PER_LONG == 32 */
2271da177e4SLinus Torvalds 
22859c10c52SGuo Ren #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_TRUNCATE64)
COMPAT_SYSCALL_DEFINE3(truncate64,const char __user *,pathname,compat_arg_u64_dual (length))22959c10c52SGuo Ren COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
23059c10c52SGuo Ren 		       compat_arg_u64_dual(length))
23159c10c52SGuo Ren {
23259c10c52SGuo Ren 	return ksys_truncate(pathname, compat_arg_u64_glue(length));
23359c10c52SGuo Ren }
23459c10c52SGuo Ren #endif
23559c10c52SGuo Ren 
23659c10c52SGuo Ren #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FTRUNCATE64)
COMPAT_SYSCALL_DEFINE3(ftruncate64,unsigned int,fd,compat_arg_u64_dual (length))23759c10c52SGuo Ren COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd,
23859c10c52SGuo Ren 		       compat_arg_u64_dual(length))
23959c10c52SGuo Ren {
24059c10c52SGuo Ren 	return ksys_ftruncate(fd, compat_arg_u64_glue(length));
24159c10c52SGuo Ren }
24259c10c52SGuo Ren #endif
2433e63cbb1SAnkit Jain 
vfs_fallocate(struct file * file,int mode,loff_t offset,loff_t len)24472c72bdfSAnna Schumaker int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
24597ac7350SAmit Arora {
246496ad9aaSAl Viro 	struct inode *inode = file_inode(file);
2473e63cbb1SAnkit Jain 	long ret;
24897ac7350SAmit Arora 
24997ac7350SAmit Arora 	if (offset < 0 || len <= 0)
2503e63cbb1SAnkit Jain 		return -EINVAL;
25197ac7350SAmit Arora 
25297ac7350SAmit Arora 	/* Return error if mode is not supported */
253dd46c787SNamjae Jeon 	if (mode & ~FALLOC_FL_SUPPORTED_MASK)
254409332b6SLukas Czerner 		return -EOPNOTSUPP;
255409332b6SLukas Czerner 
256409332b6SLukas Czerner 	/* Punch hole and zero range are mutually exclusive */
257409332b6SLukas Czerner 	if ((mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) ==
258409332b6SLukas Czerner 	    (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE))
25979124f18SJosef Bacik 		return -EOPNOTSUPP;
26079124f18SJosef Bacik 
26179124f18SJosef Bacik 	/* Punch hole must have keep size set */
26279124f18SJosef Bacik 	if ((mode & FALLOC_FL_PUNCH_HOLE) &&
26379124f18SJosef Bacik 	    !(mode & FALLOC_FL_KEEP_SIZE))
2643e63cbb1SAnkit Jain 		return -EOPNOTSUPP;
26597ac7350SAmit Arora 
26600f5e619SNamjae Jeon 	/* Collapse range should only be used exclusively. */
26700f5e619SNamjae Jeon 	if ((mode & FALLOC_FL_COLLAPSE_RANGE) &&
26800f5e619SNamjae Jeon 	    (mode & ~FALLOC_FL_COLLAPSE_RANGE))
26900f5e619SNamjae Jeon 		return -EINVAL;
27000f5e619SNamjae Jeon 
271dd46c787SNamjae Jeon 	/* Insert range should only be used exclusively. */
272dd46c787SNamjae Jeon 	if ((mode & FALLOC_FL_INSERT_RANGE) &&
273dd46c787SNamjae Jeon 	    (mode & ~FALLOC_FL_INSERT_RANGE))
274dd46c787SNamjae Jeon 		return -EINVAL;
275dd46c787SNamjae Jeon 
27671be6b49SDarrick J. Wong 	/* Unshare range should only be used with allocate mode. */
27771be6b49SDarrick J. Wong 	if ((mode & FALLOC_FL_UNSHARE_RANGE) &&
27871be6b49SDarrick J. Wong 	    (mode & ~(FALLOC_FL_UNSHARE_RANGE | FALLOC_FL_KEEP_SIZE)))
27971be6b49SDarrick J. Wong 		return -EINVAL;
28071be6b49SDarrick J. Wong 
28197ac7350SAmit Arora 	if (!(file->f_mode & FMODE_WRITE))
2823e63cbb1SAnkit Jain 		return -EBADF;
2831ca551c6SMarco Stornelli 
28400f5e619SNamjae Jeon 	/*
2858fc61d92SLukas Czerner 	 * We can only allow pure fallocate on append only files
28600f5e619SNamjae Jeon 	 */
2878fc61d92SLukas Czerner 	if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode))
2881ca551c6SMarco Stornelli 		return -EPERM;
2891ca551c6SMarco Stornelli 
2901ca551c6SMarco Stornelli 	if (IS_IMMUTABLE(inode))
2911ca551c6SMarco Stornelli 		return -EPERM;
2921ca551c6SMarco Stornelli 
29397ac7350SAmit Arora 	/*
2946d2b6170SEric Biggers 	 * We cannot allow any fallocate operation on an active swapfile
2950790b31bSLukas Czerner 	 */
2960790b31bSLukas Czerner 	if (IS_SWAPFILE(inode))
2976d2b6170SEric Biggers 		return -ETXTBSY;
2980790b31bSLukas Czerner 
2990790b31bSLukas Czerner 	/*
30097ac7350SAmit Arora 	 * Revalidate the write permissions, in case security policy has
30197ac7350SAmit Arora 	 * changed since the files were opened.
30297ac7350SAmit Arora 	 */
30397ac7350SAmit Arora 	ret = security_file_permission(file, MAY_WRITE);
30497ac7350SAmit Arora 	if (ret)
3053e63cbb1SAnkit Jain 		return ret;
30697ac7350SAmit Arora 
30797ac7350SAmit Arora 	if (S_ISFIFO(inode->i_mode))
3083e63cbb1SAnkit Jain 		return -ESPIPE;
30997ac7350SAmit Arora 
3109e79b132SAmir Goldstein 	if (S_ISDIR(inode->i_mode))
3119e79b132SAmir Goldstein 		return -EISDIR;
3129e79b132SAmir Goldstein 
3139e79b132SAmir Goldstein 	if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))
3143e63cbb1SAnkit Jain 		return -ENODEV;
31597ac7350SAmit Arora 
31697ac7350SAmit Arora 	/* Check for wrap through zero too */
31797ac7350SAmit Arora 	if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
3183e63cbb1SAnkit Jain 		return -EFBIG;
31997ac7350SAmit Arora 
3202fe17c10SChristoph Hellwig 	if (!file->f_op->fallocate)
3213e63cbb1SAnkit Jain 		return -EOPNOTSUPP;
32297ac7350SAmit Arora 
323bfe219d3SAmir Goldstein 	file_start_write(file);
32414da9200SJan Kara 	ret = file->f_op->fallocate(file, mode, offset, len);
325820c12d5SHeinrich Schuchardt 
326820c12d5SHeinrich Schuchardt 	/*
327820c12d5SHeinrich Schuchardt 	 * Create inotify and fanotify events.
328820c12d5SHeinrich Schuchardt 	 *
329820c12d5SHeinrich Schuchardt 	 * To keep the logic simple always create events if fallocate succeeds.
330820c12d5SHeinrich Schuchardt 	 * This implies that events are even created if the file size remains
331820c12d5SHeinrich Schuchardt 	 * unchanged, e.g. when using flag FALLOC_FL_KEEP_SIZE.
332820c12d5SHeinrich Schuchardt 	 */
333820c12d5SHeinrich Schuchardt 	if (ret == 0)
334820c12d5SHeinrich Schuchardt 		fsnotify_modify(file);
335820c12d5SHeinrich Schuchardt 
336bfe219d3SAmir Goldstein 	file_end_write(file);
33714da9200SJan Kara 	return ret;
33897ac7350SAmit Arora }
33972c72bdfSAnna Schumaker EXPORT_SYMBOL_GPL(vfs_fallocate);
3403e63cbb1SAnkit Jain 
ksys_fallocate(int fd,int mode,loff_t offset,loff_t len)341edf292c7SDominik Brodowski int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len)
3423e63cbb1SAnkit Jain {
3432903ff01SAl Viro 	struct fd f = fdget(fd);
3443e63cbb1SAnkit Jain 	int error = -EBADF;
3453e63cbb1SAnkit Jain 
3462903ff01SAl Viro 	if (f.file) {
34772c72bdfSAnna Schumaker 		error = vfs_fallocate(f.file, mode, offset, len);
3482903ff01SAl Viro 		fdput(f);
3493e63cbb1SAnkit Jain 	}
3503e63cbb1SAnkit Jain 	return error;
3513e63cbb1SAnkit Jain }
3523e63cbb1SAnkit Jain 
SYSCALL_DEFINE4(fallocate,int,fd,int,mode,loff_t,offset,loff_t,len)353edf292c7SDominik Brodowski SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
354edf292c7SDominik Brodowski {
355edf292c7SDominik Brodowski 	return ksys_fallocate(fd, mode, offset, len);
356edf292c7SDominik Brodowski }
357edf292c7SDominik Brodowski 
35859c10c52SGuo Ren #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FALLOCATE)
COMPAT_SYSCALL_DEFINE6(fallocate,int,fd,int,mode,compat_arg_u64_dual (offset),compat_arg_u64_dual (len))35959c10c52SGuo Ren COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode, compat_arg_u64_dual(offset),
36059c10c52SGuo Ren 		       compat_arg_u64_dual(len))
36159c10c52SGuo Ren {
36259c10c52SGuo Ren 	return ksys_fallocate(fd, mode, compat_arg_u64_glue(offset),
36359c10c52SGuo Ren 			      compat_arg_u64_glue(len));
36459c10c52SGuo Ren }
36559c10c52SGuo Ren #endif
36659c10c52SGuo Ren 
3671da177e4SLinus Torvalds /*
3681da177e4SLinus Torvalds  * access() needs to use the real uid/gid, not the effective uid/gid.
3691da177e4SLinus Torvalds  * We do this by temporarily clearing all FS-related capabilities and
3701da177e4SLinus Torvalds  * switching the fsuid/fsgid around to the real ones.
371981ee95cSMateusz Guzik  *
372981ee95cSMateusz Guzik  * Creating new credentials is expensive, so we try to skip doing it,
373981ee95cSMateusz Guzik  * which we can if the result would match what we already got.
3741da177e4SLinus Torvalds  */
access_need_override_creds(int flags)375981ee95cSMateusz Guzik static bool access_need_override_creds(int flags)
376981ee95cSMateusz Guzik {
377981ee95cSMateusz Guzik 	const struct cred *cred;
378981ee95cSMateusz Guzik 
379981ee95cSMateusz Guzik 	if (flags & AT_EACCESS)
380981ee95cSMateusz Guzik 		return false;
381981ee95cSMateusz Guzik 
382981ee95cSMateusz Guzik 	cred = current_cred();
383981ee95cSMateusz Guzik 	if (!uid_eq(cred->fsuid, cred->uid) ||
384981ee95cSMateusz Guzik 	    !gid_eq(cred->fsgid, cred->gid))
385981ee95cSMateusz Guzik 		return true;
386981ee95cSMateusz Guzik 
387981ee95cSMateusz Guzik 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
388981ee95cSMateusz Guzik 		kuid_t root_uid = make_kuid(cred->user_ns, 0);
389981ee95cSMateusz Guzik 		if (!uid_eq(cred->uid, root_uid)) {
390981ee95cSMateusz Guzik 			if (!cap_isclear(cred->cap_effective))
391981ee95cSMateusz Guzik 				return true;
392981ee95cSMateusz Guzik 		} else {
393981ee95cSMateusz Guzik 			if (!cap_isidentical(cred->cap_effective,
394981ee95cSMateusz Guzik 			    cred->cap_permitted))
395981ee95cSMateusz Guzik 				return true;
396981ee95cSMateusz Guzik 		}
397981ee95cSMateusz Guzik 	}
398981ee95cSMateusz Guzik 
399981ee95cSMateusz Guzik 	return false;
400981ee95cSMateusz Guzik }
401981ee95cSMateusz Guzik 
access_override_creds(void)40294704515SMiklos Szeredi static const struct cred *access_override_creds(void)
4031da177e4SLinus Torvalds {
404d84f4f99SDavid Howells 	const struct cred *old_cred;
405d84f4f99SDavid Howells 	struct cred *override_cred;
4061da177e4SLinus Torvalds 
407d84f4f99SDavid Howells 	override_cred = prepare_creds();
408d84f4f99SDavid Howells 	if (!override_cred)
40994704515SMiklos Szeredi 		return NULL;
4101da177e4SLinus Torvalds 
411981ee95cSMateusz Guzik 	/*
412981ee95cSMateusz Guzik 	 * XXX access_need_override_creds performs checks in hopes of skipping
413981ee95cSMateusz Guzik 	 * this work. Make sure it stays in sync if making any changes in this
414981ee95cSMateusz Guzik 	 * routine.
415981ee95cSMateusz Guzik 	 */
416981ee95cSMateusz Guzik 
417d84f4f99SDavid Howells 	override_cred->fsuid = override_cred->uid;
418d84f4f99SDavid Howells 	override_cred->fsgid = override_cred->gid;
4191da177e4SLinus Torvalds 
420086f7316SAndrew G. Morgan 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
4211cdcbec1SDavid Howells 		/* Clear the capabilities if we switch to a non-root user */
42218815a18SEric W. Biederman 		kuid_t root_uid = make_kuid(override_cred->user_ns, 0);
42318815a18SEric W. Biederman 		if (!uid_eq(override_cred->uid, root_uid))
424d84f4f99SDavid Howells 			cap_clear(override_cred->cap_effective);
4251da177e4SLinus Torvalds 		else
426d84f4f99SDavid Howells 			override_cred->cap_effective =
427d84f4f99SDavid Howells 				override_cred->cap_permitted;
428086f7316SAndrew G. Morgan 	}
4291da177e4SLinus Torvalds 
430d7852fbdSLinus Torvalds 	/*
431d7852fbdSLinus Torvalds 	 * The new set of credentials can *only* be used in
432d7852fbdSLinus Torvalds 	 * task-synchronous circumstances, and does not need
433d7852fbdSLinus Torvalds 	 * RCU freeing, unless somebody then takes a separate
434d7852fbdSLinus Torvalds 	 * reference to it.
435d7852fbdSLinus Torvalds 	 *
436d7852fbdSLinus Torvalds 	 * NOTE! This is _only_ true because this credential
437d7852fbdSLinus Torvalds 	 * is used purely for override_creds() that installs
438d7852fbdSLinus Torvalds 	 * it as the subjective cred. Other threads will be
439d7852fbdSLinus Torvalds 	 * accessing ->real_cred, not the subjective cred.
440d7852fbdSLinus Torvalds 	 *
441d7852fbdSLinus Torvalds 	 * If somebody _does_ make a copy of this (using the
442d7852fbdSLinus Torvalds 	 * 'get_current_cred()' function), that will clear the
443d7852fbdSLinus Torvalds 	 * non_rcu field, because now that other user may be
444d7852fbdSLinus Torvalds 	 * expecting RCU freeing. But normal thread-synchronous
445d7852fbdSLinus Torvalds 	 * cred accesses will keep things non-RCY.
446d7852fbdSLinus Torvalds 	 */
447d7852fbdSLinus Torvalds 	override_cred->non_rcu = 1;
448d7852fbdSLinus Torvalds 
449d84f4f99SDavid Howells 	old_cred = override_creds(override_cred);
45094704515SMiklos Szeredi 
45194704515SMiklos Szeredi 	/* override_cred() gets its own ref */
45294704515SMiklos Szeredi 	put_cred(override_cred);
45394704515SMiklos Szeredi 
45494704515SMiklos Szeredi 	return old_cred;
45594704515SMiklos Szeredi }
45694704515SMiklos Szeredi 
do_faccessat(int dfd,const char __user * filename,int mode,int flags)457eb9d7d39SChristoph Hellwig static long do_faccessat(int dfd, const char __user *filename, int mode, int flags)
45894704515SMiklos Szeredi {
45994704515SMiklos Szeredi 	struct path path;
46094704515SMiklos Szeredi 	struct inode *inode;
46194704515SMiklos Szeredi 	int res;
46294704515SMiklos Szeredi 	unsigned int lookup_flags = LOOKUP_FOLLOW;
463c8ffd8bcSMiklos Szeredi 	const struct cred *old_cred = NULL;
46494704515SMiklos Szeredi 
46594704515SMiklos Szeredi 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
46694704515SMiklos Szeredi 		return -EINVAL;
46794704515SMiklos Szeredi 
468c8ffd8bcSMiklos Szeredi 	if (flags & ~(AT_EACCESS | AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH))
469c8ffd8bcSMiklos Szeredi 		return -EINVAL;
470c8ffd8bcSMiklos Szeredi 
471c8ffd8bcSMiklos Szeredi 	if (flags & AT_SYMLINK_NOFOLLOW)
472c8ffd8bcSMiklos Szeredi 		lookup_flags &= ~LOOKUP_FOLLOW;
473c8ffd8bcSMiklos Szeredi 	if (flags & AT_EMPTY_PATH)
474c8ffd8bcSMiklos Szeredi 		lookup_flags |= LOOKUP_EMPTY;
475c8ffd8bcSMiklos Szeredi 
476981ee95cSMateusz Guzik 	if (access_need_override_creds(flags)) {
47794704515SMiklos Szeredi 		old_cred = access_override_creds();
47894704515SMiklos Szeredi 		if (!old_cred)
47994704515SMiklos Szeredi 			return -ENOMEM;
480c8ffd8bcSMiklos Szeredi 	}
48194704515SMiklos Szeredi 
48287fa5595SJeff Layton retry:
48387fa5595SJeff Layton 	res = user_path_at(dfd, filename, lookup_flags, &path);
4846902d925SDave Hansen 	if (res)
4856902d925SDave Hansen 		goto out;
4866902d925SDave Hansen 
48763afdfc7SDavid Howells 	inode = d_backing_inode(path.dentry);
488256984a8SAl Viro 
489256984a8SAl Viro 	if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) {
49030524472SAl Viro 		/*
49130524472SAl Viro 		 * MAY_EXEC on regular files is denied if the fs is mounted
49230524472SAl Viro 		 * with the "noexec" flag.
49330524472SAl Viro 		 */
49430524472SAl Viro 		res = -EACCES;
49590f8572bSEric W. Biederman 		if (path_noexec(&path))
49630524472SAl Viro 			goto out_path_release;
49730524472SAl Viro 	}
49830524472SAl Viro 
4994609e1f1SChristian Brauner 	res = inode_permission(mnt_idmap(path.mnt), inode, mode | MAY_ACCESS);
5001da177e4SLinus Torvalds 	/* SuS v2 requires we report a read only fs too */
501256984a8SAl Viro 	if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
5026902d925SDave Hansen 		goto out_path_release;
5032f676cbcSDave Hansen 	/*
5042f676cbcSDave Hansen 	 * This is a rare case where using __mnt_is_readonly()
5052f676cbcSDave Hansen 	 * is OK without a mnt_want/drop_write() pair.  Since
5062f676cbcSDave Hansen 	 * no actual write to the fs is performed here, we do
5072f676cbcSDave Hansen 	 * not need to telegraph to that to anyone.
5082f676cbcSDave Hansen 	 *
5092f676cbcSDave Hansen 	 * By doing this, we accept that this access is
5102f676cbcSDave Hansen 	 * inherently racy and know that the fs may change
5112f676cbcSDave Hansen 	 * state before we even see this result.
5122f676cbcSDave Hansen 	 */
5132d8f3038SAl Viro 	if (__mnt_is_readonly(path.mnt))
5146902d925SDave Hansen 		res = -EROFS;
5156902d925SDave Hansen 
5166902d925SDave Hansen out_path_release:
5172d8f3038SAl Viro 	path_put(&path);
51887fa5595SJeff Layton 	if (retry_estale(res, lookup_flags)) {
51987fa5595SJeff Layton 		lookup_flags |= LOOKUP_REVAL;
52087fa5595SJeff Layton 		goto retry;
52187fa5595SJeff Layton 	}
5226902d925SDave Hansen out:
523c8ffd8bcSMiklos Szeredi 	if (old_cred)
524d84f4f99SDavid Howells 		revert_creds(old_cred);
525c8ffd8bcSMiklos Szeredi 
5261da177e4SLinus Torvalds 	return res;
5271da177e4SLinus Torvalds }
5281da177e4SLinus Torvalds 
SYSCALL_DEFINE3(faccessat,int,dfd,const char __user *,filename,int,mode)529cbfe20f5SDominik Brodowski SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
530cbfe20f5SDominik Brodowski {
531c8ffd8bcSMiklos Szeredi 	return do_faccessat(dfd, filename, mode, 0);
532c8ffd8bcSMiklos Szeredi }
533c8ffd8bcSMiklos Szeredi 
SYSCALL_DEFINE4(faccessat2,int,dfd,const char __user *,filename,int,mode,int,flags)534c8ffd8bcSMiklos Szeredi SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode,
535c8ffd8bcSMiklos Szeredi 		int, flags)
536c8ffd8bcSMiklos Szeredi {
537c8ffd8bcSMiklos Szeredi 	return do_faccessat(dfd, filename, mode, flags);
538cbfe20f5SDominik Brodowski }
539cbfe20f5SDominik Brodowski 
SYSCALL_DEFINE2(access,const char __user *,filename,int,mode)540ca013e94SHeiko Carstens SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
5415590ff0dSUlrich Drepper {
542c8ffd8bcSMiklos Szeredi 	return do_faccessat(AT_FDCWD, filename, mode, 0);
5435590ff0dSUlrich Drepper }
5445590ff0dSUlrich Drepper 
SYSCALL_DEFINE1(chdir,const char __user *,filename)545db63f1e3SChristoph Hellwig SYSCALL_DEFINE1(chdir, const char __user *, filename)
5461da177e4SLinus Torvalds {
5472d8f3038SAl Viro 	struct path path;
5481da177e4SLinus Torvalds 	int error;
5490291c0a5SJeff Layton 	unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
5500291c0a5SJeff Layton retry:
5510291c0a5SJeff Layton 	error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
5521da177e4SLinus Torvalds 	if (error)
5531da177e4SLinus Torvalds 		goto out;
5541da177e4SLinus Torvalds 
55502f92b38SChristian Brauner 	error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
5561da177e4SLinus Torvalds 	if (error)
5571da177e4SLinus Torvalds 		goto dput_and_out;
5581da177e4SLinus Torvalds 
5592d8f3038SAl Viro 	set_fs_pwd(current->fs, &path);
5601da177e4SLinus Torvalds 
5611da177e4SLinus Torvalds dput_and_out:
5622d8f3038SAl Viro 	path_put(&path);
5630291c0a5SJeff Layton 	if (retry_estale(error, lookup_flags)) {
5640291c0a5SJeff Layton 		lookup_flags |= LOOKUP_REVAL;
5650291c0a5SJeff Layton 		goto retry;
5660291c0a5SJeff Layton 	}
5671da177e4SLinus Torvalds out:
5681da177e4SLinus Torvalds 	return error;
5691da177e4SLinus Torvalds }
5701da177e4SLinus Torvalds 
SYSCALL_DEFINE1(fchdir,unsigned int,fd)5713cdad428SHeiko Carstens SYSCALL_DEFINE1(fchdir, unsigned int, fd)
5721da177e4SLinus Torvalds {
5732903ff01SAl Viro 	struct fd f = fdget_raw(fd);
574159b0956SAl Viro 	int error;
5751da177e4SLinus Torvalds 
5761da177e4SLinus Torvalds 	error = -EBADF;
5772903ff01SAl Viro 	if (!f.file)
5781da177e4SLinus Torvalds 		goto out;
5791da177e4SLinus Torvalds 
5801da177e4SLinus Torvalds 	error = -ENOTDIR;
581159b0956SAl Viro 	if (!d_can_lookup(f.file->f_path.dentry))
5821da177e4SLinus Torvalds 		goto out_putf;
5831da177e4SLinus Torvalds 
58402f92b38SChristian Brauner 	error = file_permission(f.file, MAY_EXEC | MAY_CHDIR);
5851da177e4SLinus Torvalds 	if (!error)
5862903ff01SAl Viro 		set_fs_pwd(current->fs, &f.file->f_path);
5871da177e4SLinus Torvalds out_putf:
5882903ff01SAl Viro 	fdput(f);
5891da177e4SLinus Torvalds out:
5901da177e4SLinus Torvalds 	return error;
5911da177e4SLinus Torvalds }
5921da177e4SLinus Torvalds 
SYSCALL_DEFINE1(chroot,const char __user *,filename)5934b7ca501SChristoph Hellwig SYSCALL_DEFINE1(chroot, const char __user *, filename)
5941da177e4SLinus Torvalds {
5952d8f3038SAl Viro 	struct path path;
5961da177e4SLinus Torvalds 	int error;
5972771261eSJeff Layton 	unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
5982771261eSJeff Layton retry:
5992771261eSJeff Layton 	error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
6001da177e4SLinus Torvalds 	if (error)
6011da177e4SLinus Torvalds 		goto out;
6021da177e4SLinus Torvalds 
60302f92b38SChristian Brauner 	error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
6041da177e4SLinus Torvalds 	if (error)
6051da177e4SLinus Torvalds 		goto dput_and_out;
6061da177e4SLinus Torvalds 
6071da177e4SLinus Torvalds 	error = -EPERM;
608c7b96acfSEric W. Biederman 	if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
6091da177e4SLinus Torvalds 		goto dput_and_out;
6108b8efb44STetsuo Handa 	error = security_path_chroot(&path);
6118b8efb44STetsuo Handa 	if (error)
6128b8efb44STetsuo Handa 		goto dput_and_out;
6131da177e4SLinus Torvalds 
6142d8f3038SAl Viro 	set_fs_root(current->fs, &path);
6151da177e4SLinus Torvalds 	error = 0;
6161da177e4SLinus Torvalds dput_and_out:
6172d8f3038SAl Viro 	path_put(&path);
6182771261eSJeff Layton 	if (retry_estale(error, lookup_flags)) {
6192771261eSJeff Layton 		lookup_flags |= LOOKUP_REVAL;
6202771261eSJeff Layton 		goto retry;
6212771261eSJeff Layton 	}
6221da177e4SLinus Torvalds out:
6231da177e4SLinus Torvalds 	return error;
6241da177e4SLinus Torvalds }
6251da177e4SLinus Torvalds 
chmod_common(const struct path * path,umode_t mode)6261097742eSChristoph Hellwig int chmod_common(const struct path *path, umode_t mode)
6271da177e4SLinus Torvalds {
628e57712ebSAl Viro 	struct inode *inode = path->dentry->d_inode;
62927ac0ffeSJ. Bruce Fields 	struct inode *delegated_inode = NULL;
6301da177e4SLinus Torvalds 	struct iattr newattrs;
631e57712ebSAl Viro 	int error;
6321da177e4SLinus Torvalds 
633e57712ebSAl Viro 	error = mnt_want_write(path->mnt);
634e57712ebSAl Viro 	if (error)
635e57712ebSAl Viro 		return error;
63627ac0ffeSJ. Bruce Fields retry_deleg:
6375955102cSAl Viro 	inode_lock(inode);
638cdcf116dSAl Viro 	error = security_path_chmod(path, mode);
639e57712ebSAl Viro 	if (error)
640fe542cf5STetsuo Handa 		goto out_unlock;
6411da177e4SLinus Torvalds 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
6421da177e4SLinus Torvalds 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
643abf08576SChristian Brauner 	error = notify_change(mnt_idmap(path->mnt), path->dentry,
644b8b546a0SChristian Brauner 			      &newattrs, &delegated_inode);
645fe542cf5STetsuo Handa out_unlock:
6465955102cSAl Viro 	inode_unlock(inode);
64727ac0ffeSJ. Bruce Fields 	if (delegated_inode) {
64827ac0ffeSJ. Bruce Fields 		error = break_deleg_wait(&delegated_inode);
64927ac0ffeSJ. Bruce Fields 		if (!error)
65027ac0ffeSJ. Bruce Fields 			goto retry_deleg;
65127ac0ffeSJ. Bruce Fields 	}
652e57712ebSAl Viro 	mnt_drop_write(path->mnt);
653e57712ebSAl Viro 	return error;
654e57712ebSAl Viro }
655e57712ebSAl Viro 
vfs_fchmod(struct file * file,umode_t mode)6569e96c8c0SChristoph Hellwig int vfs_fchmod(struct file *file, umode_t mode)
6579e96c8c0SChristoph Hellwig {
6589e96c8c0SChristoph Hellwig 	audit_file(file);
6599e96c8c0SChristoph Hellwig 	return chmod_common(&file->f_path, mode);
6609e96c8c0SChristoph Hellwig }
6619e96c8c0SChristoph Hellwig 
SYSCALL_DEFINE2(fchmod,unsigned int,fd,umode_t,mode)662b25ba7c3SChristoph Hellwig SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
663e57712ebSAl Viro {
664173c8401SAl Viro 	struct fd f = fdget(fd);
665e57712ebSAl Viro 	int err = -EBADF;
666e57712ebSAl Viro 
667173c8401SAl Viro 	if (f.file) {
6689e96c8c0SChristoph Hellwig 		err = vfs_fchmod(f.file, mode);
669173c8401SAl Viro 		fdput(f);
670e57712ebSAl Viro 	}
6711da177e4SLinus Torvalds 	return err;
6721da177e4SLinus Torvalds }
6731da177e4SLinus Torvalds 
do_fchmodat(int dfd,const char __user * filename,umode_t mode,unsigned int flags)67409da082bSAlexey Gladkov static int do_fchmodat(int dfd, const char __user *filename, umode_t mode,
67509da082bSAlexey Gladkov 		       unsigned int flags)
6761da177e4SLinus Torvalds {
6772d8f3038SAl Viro 	struct path path;
6781da177e4SLinus Torvalds 	int error;
67909da082bSAlexey Gladkov 	unsigned int lookup_flags;
68009da082bSAlexey Gladkov 
6815daeb41aSAleksa Sarai 	if (unlikely(flags & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)))
68209da082bSAlexey Gladkov 		return -EINVAL;
68309da082bSAlexey Gladkov 
68409da082bSAlexey Gladkov 	lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
6855daeb41aSAleksa Sarai 	if (flags & AT_EMPTY_PATH)
6865daeb41aSAleksa Sarai 		lookup_flags |= LOOKUP_EMPTY;
68709da082bSAlexey Gladkov 
68814ff690cSJeff Layton retry:
68914ff690cSJeff Layton 	error = user_path_at(dfd, filename, lookup_flags, &path);
690e57712ebSAl Viro 	if (!error) {
691e57712ebSAl Viro 		error = chmod_common(&path, mode);
6922d8f3038SAl Viro 		path_put(&path);
69314ff690cSJeff Layton 		if (retry_estale(error, lookup_flags)) {
69414ff690cSJeff Layton 			lookup_flags |= LOOKUP_REVAL;
69514ff690cSJeff Layton 			goto retry;
69614ff690cSJeff Layton 		}
697e57712ebSAl Viro 	}
6981da177e4SLinus Torvalds 	return error;
6991da177e4SLinus Torvalds }
7001da177e4SLinus Torvalds 
SYSCALL_DEFINE4(fchmodat2,int,dfd,const char __user *,filename,umode_t,mode,unsigned int,flags)70109da082bSAlexey Gladkov SYSCALL_DEFINE4(fchmodat2, int, dfd, const char __user *, filename,
70209da082bSAlexey Gladkov 		umode_t, mode, unsigned int, flags)
70309da082bSAlexey Gladkov {
70409da082bSAlexey Gladkov 	return do_fchmodat(dfd, filename, mode, flags);
70509da082bSAlexey Gladkov }
70609da082bSAlexey Gladkov 
SYSCALL_DEFINE3(fchmodat,int,dfd,const char __user *,filename,umode_t,mode)70703450e27SDominik Brodowski SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename,
70803450e27SDominik Brodowski 		umode_t, mode)
70903450e27SDominik Brodowski {
71009da082bSAlexey Gladkov 	return do_fchmodat(dfd, filename, mode, 0);
71103450e27SDominik Brodowski }
71203450e27SDominik Brodowski 
SYSCALL_DEFINE2(chmod,const char __user *,filename,umode_t,mode)71349f0a076SAl Viro SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
7145590ff0dSUlrich Drepper {
71509da082bSAlexey Gladkov 	return do_fchmodat(AT_FDCWD, filename, mode, 0);
7165590ff0dSUlrich Drepper }
7175590ff0dSUlrich Drepper 
71855650b2fSAnuradha Weeraman /*
719b27c82e1SChristian Brauner  * Check whether @kuid is valid and if so generate and set vfsuid_t in
720b27c82e1SChristian Brauner  * ia_vfsuid.
721b27c82e1SChristian Brauner  *
722b27c82e1SChristian Brauner  * Return: true if @kuid is valid, false if not.
723b27c82e1SChristian Brauner  */
setattr_vfsuid(struct iattr * attr,kuid_t kuid)724b27c82e1SChristian Brauner static inline bool setattr_vfsuid(struct iattr *attr, kuid_t kuid)
725b27c82e1SChristian Brauner {
726b27c82e1SChristian Brauner 	if (!uid_valid(kuid))
727b27c82e1SChristian Brauner 		return false;
728b27c82e1SChristian Brauner 	attr->ia_valid |= ATTR_UID;
729b27c82e1SChristian Brauner 	attr->ia_vfsuid = VFSUIDT_INIT(kuid);
730b27c82e1SChristian Brauner 	return true;
731b27c82e1SChristian Brauner }
732b27c82e1SChristian Brauner 
73355650b2fSAnuradha Weeraman /*
734b27c82e1SChristian Brauner  * Check whether @kgid is valid and if so generate and set vfsgid_t in
735b27c82e1SChristian Brauner  * ia_vfsgid.
736b27c82e1SChristian Brauner  *
737b27c82e1SChristian Brauner  * Return: true if @kgid is valid, false if not.
738b27c82e1SChristian Brauner  */
setattr_vfsgid(struct iattr * attr,kgid_t kgid)739b27c82e1SChristian Brauner static inline bool setattr_vfsgid(struct iattr *attr, kgid_t kgid)
740b27c82e1SChristian Brauner {
741b27c82e1SChristian Brauner 	if (!gid_valid(kgid))
742b27c82e1SChristian Brauner 		return false;
743b27c82e1SChristian Brauner 	attr->ia_valid |= ATTR_GID;
744b27c82e1SChristian Brauner 	attr->ia_vfsgid = VFSGIDT_INIT(kgid);
745b27c82e1SChristian Brauner 	return true;
746b27c82e1SChristian Brauner }
747b27c82e1SChristian Brauner 
chown_common(const struct path * path,uid_t user,gid_t group)748b873498fSChristoph Hellwig int chown_common(const struct path *path, uid_t user, gid_t group)
7491da177e4SLinus Torvalds {
750abf08576SChristian Brauner 	struct mnt_idmap *idmap;
7514d7ca409SChristian Brauner 	struct user_namespace *fs_userns;
752fe542cf5STetsuo Handa 	struct inode *inode = path->dentry->d_inode;
75327ac0ffeSJ. Bruce Fields 	struct inode *delegated_inode = NULL;
7541da177e4SLinus Torvalds 	int error;
7551da177e4SLinus Torvalds 	struct iattr newattrs;
75652137abeSEric W. Biederman 	kuid_t uid;
75752137abeSEric W. Biederman 	kgid_t gid;
75852137abeSEric W. Biederman 
75952137abeSEric W. Biederman 	uid = make_kuid(current_user_ns(), user);
76052137abeSEric W. Biederman 	gid = make_kgid(current_user_ns(), group);
7611da177e4SLinus Torvalds 
762abf08576SChristian Brauner 	idmap = mnt_idmap(path->mnt);
763bd303368SChristian Brauner 	fs_userns = i_user_ns(inode);
764b8b546a0SChristian Brauner 
765c1b8940bSAndrew Elble retry_deleg:
766f52d74b1STetsuo Handa 	newattrs.ia_vfsuid = INVALID_VFSUID;
767f52d74b1STetsuo Handa 	newattrs.ia_vfsgid = INVALID_VFSGID;
7681da177e4SLinus Torvalds 	newattrs.ia_valid =  ATTR_CTIME;
769b27c82e1SChristian Brauner 	if ((user != (uid_t)-1) && !setattr_vfsuid(&newattrs, uid))
77052137abeSEric W. Biederman 		return -EINVAL;
771b27c82e1SChristian Brauner 	if ((group != (gid_t)-1) && !setattr_vfsgid(&newattrs, gid))
77252137abeSEric W. Biederman 		return -EINVAL;
7735955102cSAl Viro 	inode_lock(inode);
774ed5a7047SChristian Brauner 	if (!S_ISDIR(inode->i_mode))
775ed5a7047SChristian Brauner 		newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV |
7769452e93eSChristian Brauner 				     setattr_should_drop_sgid(idmap, inode);
777b27c82e1SChristian Brauner 	/* Continue to send actual fs values, not the mount values. */
778b27c82e1SChristian Brauner 	error = security_path_chown(
779b27c82e1SChristian Brauner 		path,
7804d7ca409SChristian Brauner 		from_vfsuid(idmap, fs_userns, newattrs.ia_vfsuid),
7814d7ca409SChristian Brauner 		from_vfsgid(idmap, fs_userns, newattrs.ia_vfsgid));
782fe542cf5STetsuo Handa 	if (!error)
783abf08576SChristian Brauner 		error = notify_change(idmap, path->dentry, &newattrs,
7842f221d6fSChristian Brauner 				      &delegated_inode);
7855955102cSAl Viro 	inode_unlock(inode);
78627ac0ffeSJ. Bruce Fields 	if (delegated_inode) {
78727ac0ffeSJ. Bruce Fields 		error = break_deleg_wait(&delegated_inode);
78827ac0ffeSJ. Bruce Fields 		if (!error)
78927ac0ffeSJ. Bruce Fields 			goto retry_deleg;
79027ac0ffeSJ. Bruce Fields 	}
7911da177e4SLinus Torvalds 	return error;
7921da177e4SLinus Torvalds }
7931da177e4SLinus Torvalds 
do_fchownat(int dfd,const char __user * filename,uid_t user,gid_t group,int flag)79455731b3cSDominik Brodowski int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
79555731b3cSDominik Brodowski 		int flag)
7965590ff0dSUlrich Drepper {
7972d8f3038SAl Viro 	struct path path;
7985590ff0dSUlrich Drepper 	int error = -EINVAL;
79965cfc672SAl Viro 	int lookup_flags;
8005590ff0dSUlrich Drepper 
80165cfc672SAl Viro 	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
8025590ff0dSUlrich Drepper 		goto out;
8035590ff0dSUlrich Drepper 
80465cfc672SAl Viro 	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
80565cfc672SAl Viro 	if (flag & AT_EMPTY_PATH)
80665cfc672SAl Viro 		lookup_flags |= LOOKUP_EMPTY;
80799a5df37SJeff Layton retry:
80865cfc672SAl Viro 	error = user_path_at(dfd, filename, lookup_flags, &path);
8096902d925SDave Hansen 	if (error)
8106902d925SDave Hansen 		goto out;
8112d8f3038SAl Viro 	error = mnt_want_write(path.mnt);
8122af482a7SDave Hansen 	if (error)
8132af482a7SDave Hansen 		goto out_release;
814fe542cf5STetsuo Handa 	error = chown_common(&path, user, group);
8152d8f3038SAl Viro 	mnt_drop_write(path.mnt);
8162af482a7SDave Hansen out_release:
8172d8f3038SAl Viro 	path_put(&path);
81899a5df37SJeff Layton 	if (retry_estale(error, lookup_flags)) {
81999a5df37SJeff Layton 		lookup_flags |= LOOKUP_REVAL;
82099a5df37SJeff Layton 		goto retry;
82199a5df37SJeff Layton 	}
8225590ff0dSUlrich Drepper out:
8235590ff0dSUlrich Drepper 	return error;
8245590ff0dSUlrich Drepper }
8255590ff0dSUlrich Drepper 
SYSCALL_DEFINE5(fchownat,int,dfd,const char __user *,filename,uid_t,user,gid_t,group,int,flag)82655731b3cSDominik Brodowski SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
82755731b3cSDominik Brodowski 		gid_t, group, int, flag)
82855731b3cSDominik Brodowski {
82955731b3cSDominik Brodowski 	return do_fchownat(dfd, filename, user, group, flag);
83055731b3cSDominik Brodowski }
83155731b3cSDominik Brodowski 
SYSCALL_DEFINE3(chown,const char __user *,filename,uid_t,user,gid_t,group)83255e4def0SDavid Howells SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
83355e4def0SDavid Howells {
83455731b3cSDominik Brodowski 	return do_fchownat(AT_FDCWD, filename, user, group, 0);
83555e4def0SDavid Howells }
83655e4def0SDavid Howells 
SYSCALL_DEFINE3(lchown,const char __user *,filename,uid_t,user,gid_t,group)837ca013e94SHeiko Carstens SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
8381da177e4SLinus Torvalds {
83955731b3cSDominik Brodowski 	return do_fchownat(AT_FDCWD, filename, user, group,
84055e4def0SDavid Howells 			   AT_SYMLINK_NOFOLLOW);
8411da177e4SLinus Torvalds }
8421da177e4SLinus Torvalds 
vfs_fchown(struct file * file,uid_t user,gid_t group)843c04011feSChristoph Hellwig int vfs_fchown(struct file *file, uid_t user, gid_t group)
844c04011feSChristoph Hellwig {
845c04011feSChristoph Hellwig 	int error;
846c04011feSChristoph Hellwig 
847c04011feSChristoph Hellwig 	error = mnt_want_write_file(file);
848c04011feSChristoph Hellwig 	if (error)
849c04011feSChristoph Hellwig 		return error;
850c04011feSChristoph Hellwig 	audit_file(file);
851c04011feSChristoph Hellwig 	error = chown_common(&file->f_path, user, group);
852c04011feSChristoph Hellwig 	mnt_drop_write_file(file);
853c04011feSChristoph Hellwig 	return error;
854c04011feSChristoph Hellwig }
855c04011feSChristoph Hellwig 
ksys_fchown(unsigned int fd,uid_t user,gid_t group)85655731b3cSDominik Brodowski int ksys_fchown(unsigned int fd, uid_t user, gid_t group)
8571da177e4SLinus Torvalds {
8582903ff01SAl Viro 	struct fd f = fdget(fd);
8591da177e4SLinus Torvalds 	int error = -EBADF;
8601da177e4SLinus Torvalds 
861c04011feSChristoph Hellwig 	if (f.file) {
862c04011feSChristoph Hellwig 		error = vfs_fchown(f.file, user, group);
8632903ff01SAl Viro 		fdput(f);
864c04011feSChristoph Hellwig 	}
8651da177e4SLinus Torvalds 	return error;
8661da177e4SLinus Torvalds }
8671da177e4SLinus Torvalds 
SYSCALL_DEFINE3(fchown,unsigned int,fd,uid_t,user,gid_t,group)86855731b3cSDominik Brodowski SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
86955731b3cSDominik Brodowski {
87055731b3cSDominik Brodowski 	return ksys_fchown(fd, user, group);
87155731b3cSDominik Brodowski }
87255731b3cSDominik Brodowski 
do_dentry_open(struct file * f,struct inode * inode,int (* open)(struct inode *,struct file *))87302e5180dSAl Viro static int do_dentry_open(struct file *f,
8744bacc9c9SDavid Howells 			  struct inode *inode,
875ae2bb293SAl Viro 			  int (*open)(struct inode *, struct file *))
8761da177e4SLinus Torvalds {
8771abf0c71SAl Viro 	static const struct file_operations empty_fops = {};
8781da177e4SLinus Torvalds 	int error;
8791da177e4SLinus Torvalds 
880b5bcdda3SAl Viro 	path_get(&f->f_path);
8814bacc9c9SDavid Howells 	f->f_inode = inode;
8821da177e4SLinus Torvalds 	f->f_mapping = inode->i_mapping;
8835660e13dSJeff Layton 	f->f_wb_err = filemap_sample_wb_err(f->f_mapping);
884735e4ae5SJeff Layton 	f->f_sb_err = file_sample_sb_err(f);
8855660e13dSJeff Layton 
8863f4d5a00SAl Viro 	if (unlikely(f->f_flags & O_PATH)) {
887f5d11409SAl Viro 		f->f_mode = FMODE_PATH | FMODE_OPENED;
8881abf0c71SAl Viro 		f->f_op = &empty_fops;
889af04fadcSAl Viro 		return 0;
8901abf0c71SAl Viro 	}
8911abf0c71SAl Viro 
892d6da19c9SAmir Goldstein 	if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
893d6da19c9SAmir Goldstein 		i_readcount_inc(inode);
894d6da19c9SAmir Goldstein 	} else if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
8950ccb2863SAl Viro 		error = get_write_access(inode);
8963f4d5a00SAl Viro 		if (unlikely(error))
8971da177e4SLinus Torvalds 			goto cleanup_file;
8980ccb2863SAl Viro 		error = __mnt_want_write(f->f_path.mnt);
8993f4d5a00SAl Viro 		if (unlikely(error)) {
9000ccb2863SAl Viro 			put_write_access(inode);
9010ccb2863SAl Viro 			goto cleanup_file;
9020ccb2863SAl Viro 		}
90383f936c7SAl Viro 		f->f_mode |= FMODE_WRITER;
9040f7fc9e4SJosef "Jeff" Sipek 	}
9051da177e4SLinus Torvalds 
9062be7d348SLinus Torvalds 	/* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */
9072be7d348SLinus Torvalds 	if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))
9082be7d348SLinus Torvalds 		f->f_mode |= FMODE_ATOMIC_POS;
9092be7d348SLinus Torvalds 
9101abf0c71SAl Viro 	f->f_op = fops_get(inode->i_fop);
9117159d544SDenis Efremov 	if (WARN_ON(!f->f_op)) {
91272c2d531SAl Viro 		error = -ENODEV;
91372c2d531SAl Viro 		goto cleanup_all;
91472c2d531SAl Viro 	}
9151abf0c71SAl Viro 
916e3f20ae2SAl Viro 	error = security_file_open(f);
917788e7dd4SYuichi Nakamura 	if (error)
918788e7dd4SYuichi Nakamura 		goto cleanup_all;
919788e7dd4SYuichi Nakamura 
920c65454a9SJeff Layton 	error = break_lease(file_inode(f), f->f_flags);
921f3c7691eSJ. Bruce Fields 	if (error)
922f3c7691eSJ. Bruce Fields 		goto cleanup_all;
923f3c7691eSJ. Bruce Fields 
924ea73ea72SAl Viro 	/* normally all 3 are set; ->open() can clear them if needed */
925ea73ea72SAl Viro 	f->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
92672c2d531SAl Viro 	if (!open)
927834f2a4aSTrond Myklebust 		open = f->f_op->open;
928834f2a4aSTrond Myklebust 	if (open) {
929834f2a4aSTrond Myklebust 		error = open(inode, f);
9301da177e4SLinus Torvalds 		if (error)
9311da177e4SLinus Torvalds 			goto cleanup_all;
9321da177e4SLinus Torvalds 	}
933f5d11409SAl Viro 	f->f_mode |= FMODE_OPENED;
934293bc982SAl Viro 	if ((f->f_mode & FMODE_READ) &&
93584363182SAl Viro 	     likely(f->f_op->read || f->f_op->read_iter))
9367f7f25e8SAl Viro 		f->f_mode |= FMODE_CAN_READ;
937293bc982SAl Viro 	if ((f->f_mode & FMODE_WRITE) &&
93884363182SAl Viro 	     likely(f->f_op->write || f->f_op->write_iter))
9397f7f25e8SAl Viro 		f->f_mode |= FMODE_CAN_WRITE;
940e7478158SJason A. Donenfeld 	if ((f->f_mode & FMODE_LSEEK) && !f->f_op->llseek)
941e7478158SJason A. Donenfeld 		f->f_mode &= ~FMODE_LSEEK;
942a2ad63daSNeilBrown 	if (f->f_mapping->a_ops && f->f_mapping->a_ops->direct_IO)
943a2ad63daSNeilBrown 		f->f_mode |= FMODE_CAN_ODIRECT;
944834f2a4aSTrond Myklebust 
9451da177e4SLinus Torvalds 	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
946164f4064SAl Viro 	f->f_iocb_flags = iocb_flags(f);
9471da177e4SLinus Torvalds 
9481da177e4SLinus Torvalds 	file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
949af04fadcSAl Viro 
950a2ad63daSNeilBrown 	if ((f->f_flags & O_DIRECT) && !(f->f_mode & FMODE_CAN_ODIRECT))
95169527c55SAl Viro 		return -EINVAL;
95209d91cdaSSong Liu 
95309d91cdaSSong Liu 	/*
95409d91cdaSSong Liu 	 * XXX: Huge page cache doesn't support writing yet. Drop all page
95509d91cdaSSong Liu 	 * cache for this file before processing writes.
95609d91cdaSSong Liu 	 */
957eb6ecbedSCollin Fijalkovich 	if (f->f_mode & FMODE_WRITE) {
958eb6ecbedSCollin Fijalkovich 		/*
959eb6ecbedSCollin Fijalkovich 		 * Paired with smp_mb() in collapse_file() to ensure nr_thps
960eb6ecbedSCollin Fijalkovich 		 * is up to date and the update to i_writecount by
961eb6ecbedSCollin Fijalkovich 		 * get_write_access() is visible. Ensures subsequent insertion
962eb6ecbedSCollin Fijalkovich 		 * of THPs into the page cache will fail.
963eb6ecbedSCollin Fijalkovich 		 */
964eb6ecbedSCollin Fijalkovich 		smp_mb();
96555fc0d91SRongwei Wang 		if (filemap_nr_thps(inode->i_mapping)) {
9668468e937SRongwei Wang 			struct address_space *mapping = inode->i_mapping;
9678468e937SRongwei Wang 
96855fc0d91SRongwei Wang 			filemap_invalidate_lock(inode->i_mapping);
9698468e937SRongwei Wang 			/*
9708468e937SRongwei Wang 			 * unmap_mapping_range just need to be called once
9718468e937SRongwei Wang 			 * here, because the private pages is not need to be
9728468e937SRongwei Wang 			 * unmapped mapping (e.g. data segment of dynamic
9738468e937SRongwei Wang 			 * shared libraries here).
9748468e937SRongwei Wang 			 */
9758468e937SRongwei Wang 			unmap_mapping_range(mapping, 0, 0, 0);
9768468e937SRongwei Wang 			truncate_inode_pages(mapping, 0);
97755fc0d91SRongwei Wang 			filemap_invalidate_unlock(inode->i_mapping);
97855fc0d91SRongwei Wang 		}
979eb6ecbedSCollin Fijalkovich 	}
98009d91cdaSSong Liu 
9817b8c9d7bSAmir Goldstein 	/*
9827b8c9d7bSAmir Goldstein 	 * Once we return a file with FMODE_OPENED, __fput() will call
9837b8c9d7bSAmir Goldstein 	 * fsnotify_close(), so we need fsnotify_open() here for symmetry.
9847b8c9d7bSAmir Goldstein 	 */
9857b8c9d7bSAmir Goldstein 	fsnotify_open(f);
98696b7e579SAl Viro 	return 0;
9871da177e4SLinus Torvalds 
9881da177e4SLinus Torvalds cleanup_all:
9896b4e8085SAl Viro 	if (WARN_ON_ONCE(error > 0))
9906b4e8085SAl Viro 		error = -EINVAL;
9911da177e4SLinus Torvalds 	fops_put(f->f_op);
992d6da19c9SAmir Goldstein 	put_file_access(f);
9931da177e4SLinus Torvalds cleanup_file:
99402e5180dSAl Viro 	path_put(&f->f_path);
99502e5180dSAl Viro 	f->f_path.mnt = NULL;
99602e5180dSAl Viro 	f->f_path.dentry = NULL;
997dd37978cSAl Viro 	f->f_inode = NULL;
99896b7e579SAl Viro 	return error;
9991da177e4SLinus Torvalds }
10001da177e4SLinus Torvalds 
1001834f2a4aSTrond Myklebust /**
1002d18e9008SMiklos Szeredi  * finish_open - finish opening a file
10030854d450SMiklos Szeredi  * @file: file pointer
1004d18e9008SMiklos Szeredi  * @dentry: pointer to dentry
1005d18e9008SMiklos Szeredi  * @open: open callback
1006d18e9008SMiklos Szeredi  *
1007d18e9008SMiklos Szeredi  * This can be used to finish opening a file passed to i_op->atomic_open().
1008d18e9008SMiklos Szeredi  *
1009d18e9008SMiklos Szeredi  * If the open callback is set to NULL, then the standard f_op->open()
1010d18e9008SMiklos Szeredi  * filesystem callback is substituted.
10110854d450SMiklos Szeredi  *
10120854d450SMiklos Szeredi  * NB: the dentry reference is _not_ consumed.  If, for example, the dentry is
10130854d450SMiklos Szeredi  * the return value of d_splice_alias(), then the caller needs to perform dput()
10140854d450SMiklos Szeredi  * on it after finish_open().
10150854d450SMiklos Szeredi  *
10160854d450SMiklos Szeredi  * Returns zero on success or -errno if the open failed.
1017d18e9008SMiklos Szeredi  */
finish_open(struct file * file,struct dentry * dentry,int (* open)(struct inode *,struct file *))101830d90494SAl Viro int finish_open(struct file *file, struct dentry *dentry,
1019be12af3eSAl Viro 		int (*open)(struct inode *, struct file *))
1020d18e9008SMiklos Szeredi {
1021aad888f8SAl Viro 	BUG_ON(file->f_mode & FMODE_OPENED); /* once it's opened, it's opened */
1022d18e9008SMiklos Szeredi 
1023b5bcdda3SAl Viro 	file->f_path.dentry = dentry;
1024aad888f8SAl Viro 	return do_dentry_open(file, d_backing_inode(dentry), open);
1025d18e9008SMiklos Szeredi }
1026d18e9008SMiklos Szeredi EXPORT_SYMBOL(finish_open);
1027d18e9008SMiklos Szeredi 
1028d18e9008SMiklos Szeredi /**
1029d18e9008SMiklos Szeredi  * finish_no_open - finish ->atomic_open() without opening the file
1030d18e9008SMiklos Szeredi  *
10310854d450SMiklos Szeredi  * @file: file pointer
1032d18e9008SMiklos Szeredi  * @dentry: dentry or NULL (as returned from ->lookup())
1033d18e9008SMiklos Szeredi  *
1034d18e9008SMiklos Szeredi  * This can be used to set the result of a successful lookup in ->atomic_open().
10350854d450SMiklos Szeredi  *
10360854d450SMiklos Szeredi  * NB: unlike finish_open() this function does consume the dentry reference and
10370854d450SMiklos Szeredi  * the caller need not dput() it.
10380854d450SMiklos Szeredi  *
103964e1ac4dSAl Viro  * Returns "0" which must be the return value of ->atomic_open() after having
10400854d450SMiklos Szeredi  * called this function.
1041d18e9008SMiklos Szeredi  */
finish_no_open(struct file * file,struct dentry * dentry)1042e45198a6SAl Viro int finish_no_open(struct file *file, struct dentry *dentry)
1043d18e9008SMiklos Szeredi {
104430d90494SAl Viro 	file->f_path.dentry = dentry;
104564e1ac4dSAl Viro 	return 0;
1046d18e9008SMiklos Szeredi }
1047d18e9008SMiklos Szeredi EXPORT_SYMBOL(finish_no_open);
1048d18e9008SMiklos Szeredi 
file_path(struct file * filp,char * buf,int buflen)10499bf39ab2SMiklos Szeredi char *file_path(struct file *filp, char *buf, int buflen)
10509bf39ab2SMiklos Szeredi {
10519bf39ab2SMiklos Szeredi 	return d_path(&filp->f_path, buf, buflen);
10529bf39ab2SMiklos Szeredi }
10539bf39ab2SMiklos Szeredi EXPORT_SYMBOL(file_path);
10549bf39ab2SMiklos Szeredi 
10554bacc9c9SDavid Howells /**
10564bacc9c9SDavid Howells  * vfs_open - open the file at the given path
10574bacc9c9SDavid Howells  * @path: path to open
10584bacc9c9SDavid Howells  * @file: newly allocated file with f_flag initialized
10594bacc9c9SDavid Howells  */
vfs_open(const struct path * path,struct file * file)1060ae2bb293SAl Viro int vfs_open(const struct path *path, struct file *file)
10614bacc9c9SDavid Howells {
106254d5ca87SMiklos Szeredi 	file->f_path = *path;
1063a6518f73SMiklos Szeredi 	return do_dentry_open(file, d_backing_inode(path->dentry), NULL);
10644bacc9c9SDavid Howells }
10654bacc9c9SDavid Howells 
dentry_open(const struct path * path,int flags,const struct cred * cred)1066765927b2SAl Viro struct file *dentry_open(const struct path *path, int flags,
1067745ca247SDavid Howells 			 const struct cred *cred)
1068a1a5b3d9SPeter Staubach {
1069a1a5b3d9SPeter Staubach 	int error;
1070a1a5b3d9SPeter Staubach 	struct file *f;
1071a1a5b3d9SPeter Staubach 
1072c212f9aaSTetsuo Handa 	/* We must always pass in a valid mount pointer. */
1073765927b2SAl Viro 	BUG_ON(!path->mnt);
1074322ee5b3SChristoph Hellwig 
1075ea73ea72SAl Viro 	f = alloc_empty_file(flags, cred);
1076af04fadcSAl Viro 	if (!IS_ERR(f)) {
1077ae2bb293SAl Viro 		error = vfs_open(path, f);
10782a027e7aSAl Viro 		if (error) {
1079af04fadcSAl Viro 			fput(f);
1080af04fadcSAl Viro 			f = ERR_PTR(error);
1081af04fadcSAl Viro 		}
10821afc99beSAl Viro 	}
10832a027e7aSAl Viro 	return f;
1084a1a5b3d9SPeter Staubach }
10851da177e4SLinus Torvalds EXPORT_SYMBOL(dentry_open);
10861da177e4SLinus Torvalds 
1087fb70bf12SChuck Lever /**
1088fb70bf12SChuck Lever  * dentry_create - Create and open a file
1089fb70bf12SChuck Lever  * @path: path to create
1090fb70bf12SChuck Lever  * @flags: O_ flags
1091fb70bf12SChuck Lever  * @mode: mode bits for new file
1092fb70bf12SChuck Lever  * @cred: credentials to use
1093fb70bf12SChuck Lever  *
1094fb70bf12SChuck Lever  * Caller must hold the parent directory's lock, and have prepared
1095fb70bf12SChuck Lever  * a negative dentry, placed in @path->dentry, for the new file.
1096fb70bf12SChuck Lever  *
1097fb70bf12SChuck Lever  * Caller sets @path->mnt to the vfsmount of the filesystem where
1098fb70bf12SChuck Lever  * the new file is to be created. The parent directory and the
1099fb70bf12SChuck Lever  * negative dentry must reside on the same filesystem instance.
1100fb70bf12SChuck Lever  *
1101fb70bf12SChuck Lever  * On success, returns a "struct file *". Otherwise a ERR_PTR
1102fb70bf12SChuck Lever  * is returned.
1103fb70bf12SChuck Lever  */
dentry_create(const struct path * path,int flags,umode_t mode,const struct cred * cred)1104fb70bf12SChuck Lever struct file *dentry_create(const struct path *path, int flags, umode_t mode,
1105fb70bf12SChuck Lever 			   const struct cred *cred)
1106fb70bf12SChuck Lever {
1107fb70bf12SChuck Lever 	struct file *f;
1108fb70bf12SChuck Lever 	int error;
1109fb70bf12SChuck Lever 
1110fb70bf12SChuck Lever 	f = alloc_empty_file(flags, cred);
1111fb70bf12SChuck Lever 	if (IS_ERR(f))
1112fb70bf12SChuck Lever 		return f;
1113fb70bf12SChuck Lever 
1114abf08576SChristian Brauner 	error = vfs_create(mnt_idmap(path->mnt),
1115fb70bf12SChuck Lever 			   d_inode(path->dentry->d_parent),
1116fb70bf12SChuck Lever 			   path->dentry, mode, true);
1117fb70bf12SChuck Lever 	if (!error)
1118fb70bf12SChuck Lever 		error = vfs_open(path, f);
1119fb70bf12SChuck Lever 
1120fb70bf12SChuck Lever 	if (unlikely(error)) {
1121fb70bf12SChuck Lever 		fput(f);
1122fb70bf12SChuck Lever 		return ERR_PTR(error);
1123fb70bf12SChuck Lever 	}
1124fb70bf12SChuck Lever 	return f;
1125fb70bf12SChuck Lever }
1126fb70bf12SChuck Lever EXPORT_SYMBOL(dentry_create);
1127fb70bf12SChuck Lever 
1128cbb0b9d4SAmir Goldstein /**
1129cbb0b9d4SAmir Goldstein  * kernel_file_open - open a file for kernel internal use
1130cbb0b9d4SAmir Goldstein  * @path:	path of the file to open
1131cbb0b9d4SAmir Goldstein  * @flags:	open flags
1132cbb0b9d4SAmir Goldstein  * @inode:	the inode
1133cbb0b9d4SAmir Goldstein  * @cred:	credentials for open
1134cbb0b9d4SAmir Goldstein  *
1135cbb0b9d4SAmir Goldstein  * Open a file for use by in-kernel consumers. The file is not accounted
1136cbb0b9d4SAmir Goldstein  * against nr_files and must not be installed into the file descriptor
1137cbb0b9d4SAmir Goldstein  * table.
1138cbb0b9d4SAmir Goldstein  *
1139cbb0b9d4SAmir Goldstein  * Return: Opened file on success, an error pointer on failure.
1140cbb0b9d4SAmir Goldstein  */
kernel_file_open(const struct path * path,int flags,struct inode * inode,const struct cred * cred)1141cbb0b9d4SAmir Goldstein struct file *kernel_file_open(const struct path *path, int flags,
11422abc77afSAl Viro 				struct inode *inode, const struct cred *cred)
11432abc77afSAl Viro {
1144cbb0b9d4SAmir Goldstein 	struct file *f;
11452abc77afSAl Viro 	int error;
11462abc77afSAl Viro 
1147cbb0b9d4SAmir Goldstein 	f = alloc_empty_file_noaccount(flags, cred);
1148cbb0b9d4SAmir Goldstein 	if (IS_ERR(f))
1149cbb0b9d4SAmir Goldstein 		return f;
1150cbb0b9d4SAmir Goldstein 
11512abc77afSAl Viro 	f->f_path = *path;
11522abc77afSAl Viro 	error = do_dentry_open(f, inode, NULL);
11532abc77afSAl Viro 	if (error) {
11542abc77afSAl Viro 		fput(f);
11552abc77afSAl Viro 		f = ERR_PTR(error);
11562abc77afSAl Viro 	}
11572abc77afSAl Viro 	return f;
11582abc77afSAl Viro }
1159cbb0b9d4SAmir Goldstein EXPORT_SYMBOL_GPL(kernel_file_open);
1160cbb0b9d4SAmir Goldstein 
116162d53c4aSAmir Goldstein /**
116262d53c4aSAmir Goldstein  * backing_file_open - open a backing file for kernel internal use
116362d53c4aSAmir Goldstein  * @path:	path of the file to open
116462d53c4aSAmir Goldstein  * @flags:	open flags
1165*35931eb3SMatthew Wilcox (Oracle)  * @real_path:	path of the backing file
116662d53c4aSAmir Goldstein  * @cred:	credentials for open
116762d53c4aSAmir Goldstein  *
116862d53c4aSAmir Goldstein  * Open a backing file for a stackable filesystem (e.g., overlayfs).
116962d53c4aSAmir Goldstein  * @path may be on the stackable filesystem and backing inode on the
117062d53c4aSAmir Goldstein  * underlying filesystem. In this case, we want to be able to return
117162d53c4aSAmir Goldstein  * the @real_path of the backing inode. This is done by embedding the
117262d53c4aSAmir Goldstein  * returned file into a container structure that also stores the path of
117362d53c4aSAmir Goldstein  * the backing inode on the underlying filesystem, which can be
117462d53c4aSAmir Goldstein  * retrieved using backing_file_real_path().
117562d53c4aSAmir Goldstein  */
backing_file_open(const struct path * path,int flags,const struct path * real_path,const struct cred * cred)117662d53c4aSAmir Goldstein struct file *backing_file_open(const struct path *path, int flags,
117762d53c4aSAmir Goldstein 			       const struct path *real_path,
117862d53c4aSAmir Goldstein 			       const struct cred *cred)
11792abc77afSAl Viro {
118062d53c4aSAmir Goldstein 	struct file *f;
11812abc77afSAl Viro 	int error;
11822abc77afSAl Viro 
118362d53c4aSAmir Goldstein 	f = alloc_empty_backing_file(flags, cred);
118462d53c4aSAmir Goldstein 	if (IS_ERR(f))
118562d53c4aSAmir Goldstein 		return f;
118662d53c4aSAmir Goldstein 
11872abc77afSAl Viro 	f->f_path = *path;
118862d53c4aSAmir Goldstein 	path_get(real_path);
118962d53c4aSAmir Goldstein 	*backing_file_real_path(f) = *real_path;
119062d53c4aSAmir Goldstein 	error = do_dentry_open(f, d_inode(real_path->dentry), NULL);
11912abc77afSAl Viro 	if (error) {
11922abc77afSAl Viro 		fput(f);
11932abc77afSAl Viro 		f = ERR_PTR(error);
11942abc77afSAl Viro 	}
119562d53c4aSAmir Goldstein 
11962abc77afSAl Viro 	return f;
11972abc77afSAl Viro }
119862d53c4aSAmir Goldstein EXPORT_SYMBOL_GPL(backing_file_open);
11992abc77afSAl Viro 
1200fddb5d43SAleksa Sarai #define WILL_CREATE(flags)	(flags & (O_CREAT | __O_TMPFILE))
1201fddb5d43SAleksa Sarai #define O_PATH_FLAGS		(O_DIRECTORY | O_NOFOLLOW | O_PATH | O_CLOEXEC)
1202fddb5d43SAleksa Sarai 
build_open_how(int flags,umode_t mode)120335cb6d54SJens Axboe inline struct open_how build_open_how(int flags, umode_t mode)
120447c805dcSAl Viro {
1205fddb5d43SAleksa Sarai 	struct open_how how = {
1206fddb5d43SAleksa Sarai 		.flags = flags & VALID_OPEN_FLAGS,
1207fddb5d43SAleksa Sarai 		.mode = mode & S_IALLUGO,
1208fddb5d43SAleksa Sarai 	};
1209fddb5d43SAleksa Sarai 
1210fddb5d43SAleksa Sarai 	/* O_PATH beats everything else. */
1211fddb5d43SAleksa Sarai 	if (how.flags & O_PATH)
1212fddb5d43SAleksa Sarai 		how.flags &= O_PATH_FLAGS;
1213fddb5d43SAleksa Sarai 	/* Modes should only be set for create-like flags. */
1214fddb5d43SAleksa Sarai 	if (!WILL_CREATE(how.flags))
1215fddb5d43SAleksa Sarai 		how.mode = 0;
1216fddb5d43SAleksa Sarai 	return how;
1217fddb5d43SAleksa Sarai }
1218fddb5d43SAleksa Sarai 
build_open_flags(const struct open_how * how,struct open_flags * op)121935cb6d54SJens Axboe inline int build_open_flags(const struct open_how *how, struct open_flags *op)
1220fddb5d43SAleksa Sarai {
1221cfe80306SChristian Brauner 	u64 flags = how->flags;
1222cedd0bdcSMin-Hua Chen 	u64 strip = __FMODE_NONOTIFY | O_CLOEXEC;
122347c805dcSAl Viro 	int lookup_flags = 0;
122462fb4a15SAl Viro 	int acc_mode = ACC_MODE(flags);
122547c805dcSAl Viro 
1226cfe80306SChristian Brauner 	BUILD_BUG_ON_MSG(upper_32_bits(VALID_OPEN_FLAGS),
1227cfe80306SChristian Brauner 			 "struct open_flags doesn't yet handle flags > 32 bits");
1228cfe80306SChristian Brauner 
1229cfe80306SChristian Brauner 	/*
1230cfe80306SChristian Brauner 	 * Strip flags that either shouldn't be set by userspace like
1231cfe80306SChristian Brauner 	 * FMODE_NONOTIFY or that aren't relevant in determining struct
1232cfe80306SChristian Brauner 	 * open_flags like O_CLOEXEC.
1233cfe80306SChristian Brauner 	 */
1234cfe80306SChristian Brauner 	flags &= ~strip;
1235fddb5d43SAleksa Sarai 
1236fddb5d43SAleksa Sarai 	/*
1237fddb5d43SAleksa Sarai 	 * Older syscalls implicitly clear all of the invalid flags or argument
1238fddb5d43SAleksa Sarai 	 * values before calling build_open_flags(), but openat2(2) checks all
1239fddb5d43SAleksa Sarai 	 * of its arguments.
1240fddb5d43SAleksa Sarai 	 */
1241fddb5d43SAleksa Sarai 	if (flags & ~VALID_OPEN_FLAGS)
1242fddb5d43SAleksa Sarai 		return -EINVAL;
1243fddb5d43SAleksa Sarai 	if (how->resolve & ~VALID_RESOLVE_FLAGS)
1244fddb5d43SAleksa Sarai 		return -EINVAL;
1245fddb5d43SAleksa Sarai 
1246398840f8SAleksa Sarai 	/* Scoping flags are mutually exclusive. */
1247398840f8SAleksa Sarai 	if ((how->resolve & RESOLVE_BENEATH) && (how->resolve & RESOLVE_IN_ROOT))
1248398840f8SAleksa Sarai 		return -EINVAL;
1249398840f8SAleksa Sarai 
1250fddb5d43SAleksa Sarai 	/* Deal with the mode. */
1251fddb5d43SAleksa Sarai 	if (WILL_CREATE(flags)) {
1252fddb5d43SAleksa Sarai 		if (how->mode & ~S_IALLUGO)
1253fddb5d43SAleksa Sarai 			return -EINVAL;
1254fddb5d43SAleksa Sarai 		op->mode = how->mode | S_IFREG;
1255fddb5d43SAleksa Sarai 	} else {
1256fddb5d43SAleksa Sarai 		if (how->mode != 0)
1257fddb5d43SAleksa Sarai 			return -EINVAL;
1258fddb5d43SAleksa Sarai 		op->mode = 0;
1259fddb5d43SAleksa Sarai 	}
1260fddb5d43SAleksa Sarai 
1261fddb5d43SAleksa Sarai 	/*
126243b45063SChristian Brauner 	 * Block bugs where O_DIRECTORY | O_CREAT created regular files.
126343b45063SChristian Brauner 	 * Note, that blocking O_DIRECTORY | O_CREAT here also protects
126443b45063SChristian Brauner 	 * O_TMPFILE below which requires O_DIRECTORY being raised.
1265fddb5d43SAleksa Sarai 	 */
126643b45063SChristian Brauner 	if ((flags & (O_DIRECTORY | O_CREAT)) == (O_DIRECTORY | O_CREAT))
126743b45063SChristian Brauner 		return -EINVAL;
126843b45063SChristian Brauner 
126943b45063SChristian Brauner 	/* Now handle the creative implementation of O_TMPFILE. */
1270fddb5d43SAleksa Sarai 	if (flags & __O_TMPFILE) {
127143b45063SChristian Brauner 		/*
127243b45063SChristian Brauner 		 * In order to ensure programs get explicit errors when trying
127343b45063SChristian Brauner 		 * to use O_TMPFILE on old kernels we enforce that O_DIRECTORY
127443b45063SChristian Brauner 		 * is raised alongside __O_TMPFILE.
127543b45063SChristian Brauner 		 */
127643b45063SChristian Brauner 		if (!(flags & O_DIRECTORY))
1277fddb5d43SAleksa Sarai 			return -EINVAL;
1278fddb5d43SAleksa Sarai 		if (!(acc_mode & MAY_WRITE))
1279fddb5d43SAleksa Sarai 			return -EINVAL;
1280fddb5d43SAleksa Sarai 	}
1281fddb5d43SAleksa Sarai 	if (flags & O_PATH) {
1282fddb5d43SAleksa Sarai 		/* O_PATH only permits certain other flags to be set. */
1283fddb5d43SAleksa Sarai 		if (flags & ~O_PATH_FLAGS)
1284fddb5d43SAleksa Sarai 			return -EINVAL;
1285fddb5d43SAleksa Sarai 		acc_mode = 0;
1286fddb5d43SAleksa Sarai 	}
128747c805dcSAl Viro 
128847c805dcSAl Viro 	/*
128947c805dcSAl Viro 	 * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
129047c805dcSAl Viro 	 * check for O_DSYNC if the need any syncing at all we enforce it's
129147c805dcSAl Viro 	 * always set instead of having to deal with possibly weird behaviour
129247c805dcSAl Viro 	 * for malicious applications setting only __O_SYNC.
129347c805dcSAl Viro 	 */
129447c805dcSAl Viro 	if (flags & __O_SYNC)
129547c805dcSAl Viro 		flags |= O_DSYNC;
129647c805dcSAl Viro 
12971abf0c71SAl Viro 	op->open_flag = flags;
129847c805dcSAl Viro 
129947c805dcSAl Viro 	/* O_TRUNC implies we need access checks for write permissions */
130047c805dcSAl Viro 	if (flags & O_TRUNC)
130147c805dcSAl Viro 		acc_mode |= MAY_WRITE;
130247c805dcSAl Viro 
130347c805dcSAl Viro 	/* Allow the LSM permission hook to distinguish append
130447c805dcSAl Viro 	   access from general write access. */
130547c805dcSAl Viro 	if (flags & O_APPEND)
130647c805dcSAl Viro 		acc_mode |= MAY_APPEND;
130747c805dcSAl Viro 
130847c805dcSAl Viro 	op->acc_mode = acc_mode;
130947c805dcSAl Viro 
13101abf0c71SAl Viro 	op->intent = flags & O_PATH ? 0 : LOOKUP_OPEN;
13111abf0c71SAl Viro 
131247c805dcSAl Viro 	if (flags & O_CREAT) {
131347c805dcSAl Viro 		op->intent |= LOOKUP_CREATE;
131431d1726dSAl Viro 		if (flags & O_EXCL) {
131547c805dcSAl Viro 			op->intent |= LOOKUP_EXCL;
131631d1726dSAl Viro 			flags |= O_NOFOLLOW;
131731d1726dSAl Viro 		}
131847c805dcSAl Viro 	}
131947c805dcSAl Viro 
132047c805dcSAl Viro 	if (flags & O_DIRECTORY)
132147c805dcSAl Viro 		lookup_flags |= LOOKUP_DIRECTORY;
132247c805dcSAl Viro 	if (!(flags & O_NOFOLLOW))
132347c805dcSAl Viro 		lookup_flags |= LOOKUP_FOLLOW;
1324fddb5d43SAleksa Sarai 
1325fddb5d43SAleksa Sarai 	if (how->resolve & RESOLVE_NO_XDEV)
1326fddb5d43SAleksa Sarai 		lookup_flags |= LOOKUP_NO_XDEV;
1327fddb5d43SAleksa Sarai 	if (how->resolve & RESOLVE_NO_MAGICLINKS)
1328fddb5d43SAleksa Sarai 		lookup_flags |= LOOKUP_NO_MAGICLINKS;
1329fddb5d43SAleksa Sarai 	if (how->resolve & RESOLVE_NO_SYMLINKS)
1330fddb5d43SAleksa Sarai 		lookup_flags |= LOOKUP_NO_SYMLINKS;
1331fddb5d43SAleksa Sarai 	if (how->resolve & RESOLVE_BENEATH)
1332fddb5d43SAleksa Sarai 		lookup_flags |= LOOKUP_BENEATH;
1333fddb5d43SAleksa Sarai 	if (how->resolve & RESOLVE_IN_ROOT)
1334fddb5d43SAleksa Sarai 		lookup_flags |= LOOKUP_IN_ROOT;
133599668f61SJens Axboe 	if (how->resolve & RESOLVE_CACHED) {
133699668f61SJens Axboe 		/* Don't bother even trying for create/truncate/tmpfile open */
1337a0fc452aSAleksa Sarai 		if (flags & (O_TRUNC | O_CREAT | __O_TMPFILE))
133899668f61SJens Axboe 			return -EAGAIN;
133999668f61SJens Axboe 		lookup_flags |= LOOKUP_CACHED;
134099668f61SJens Axboe 	}
1341fddb5d43SAleksa Sarai 
1342f9652e10SAl Viro 	op->lookup_flags = lookup_flags;
1343f9652e10SAl Viro 	return 0;
134447c805dcSAl Viro }
134547c805dcSAl Viro 
134647c805dcSAl Viro /**
1347669abf4eSJeff Layton  * file_open_name - open file and return file pointer
1348669abf4eSJeff Layton  *
1349669abf4eSJeff Layton  * @name:	struct filename containing path to open
1350669abf4eSJeff Layton  * @flags:	open flags as per the open(2) second argument
1351669abf4eSJeff Layton  * @mode:	mode for the new file if O_CREAT is set, else ignored
1352669abf4eSJeff Layton  *
1353669abf4eSJeff Layton  * This is the helper to open a file from kernelspace if you really
1354669abf4eSJeff Layton  * have to.  But in generally you should not do this, so please move
1355669abf4eSJeff Layton  * along, nothing to see here..
1356669abf4eSJeff Layton  */
file_open_name(struct filename * name,int flags,umode_t mode)1357669abf4eSJeff Layton struct file *file_open_name(struct filename *name, int flags, umode_t mode)
1358669abf4eSJeff Layton {
1359669abf4eSJeff Layton 	struct open_flags op;
1360fddb5d43SAleksa Sarai 	struct open_how how = build_open_how(flags, mode);
1361fddb5d43SAleksa Sarai 	int err = build_open_flags(&how, &op);
1362fddb5d43SAleksa Sarai 	if (err)
1363fddb5d43SAleksa Sarai 		return ERR_PTR(err);
1364fddb5d43SAleksa Sarai 	return do_filp_open(AT_FDCWD, name, &op);
1365669abf4eSJeff Layton }
1366669abf4eSJeff Layton 
1367669abf4eSJeff Layton /**
136847c805dcSAl Viro  * filp_open - open file and return file pointer
136947c805dcSAl Viro  *
137047c805dcSAl Viro  * @filename:	path to open
137147c805dcSAl Viro  * @flags:	open flags as per the open(2) second argument
137247c805dcSAl Viro  * @mode:	mode for the new file if O_CREAT is set, else ignored
137347c805dcSAl Viro  *
137447c805dcSAl Viro  * This is the helper to open a file from kernelspace if you really
137547c805dcSAl Viro  * have to.  But in generally you should not do this, so please move
137647c805dcSAl Viro  * along, nothing to see here..
137747c805dcSAl Viro  */
filp_open(const char * filename,int flags,umode_t mode)1378a218d0fdSAl Viro struct file *filp_open(const char *filename, int flags, umode_t mode)
137947c805dcSAl Viro {
138051689104SPaul Moore 	struct filename *name = getname_kernel(filename);
138151689104SPaul Moore 	struct file *file = ERR_CAST(name);
138251689104SPaul Moore 
138351689104SPaul Moore 	if (!IS_ERR(name)) {
138451689104SPaul Moore 		file = file_open_name(name, flags, mode);
138551689104SPaul Moore 		putname(name);
138651689104SPaul Moore 	}
138751689104SPaul Moore 	return file;
138847c805dcSAl Viro }
138947c805dcSAl Viro EXPORT_SYMBOL(filp_open);
139047c805dcSAl Viro 
file_open_root(const struct path * root,const char * filename,int flags,umode_t mode)1391ffb37ca3SAl Viro struct file *file_open_root(const struct path *root,
1392378c6520SJann Horn 			    const char *filename, int flags, umode_t mode)
139373d049a4SAl Viro {
139473d049a4SAl Viro 	struct open_flags op;
1395fddb5d43SAleksa Sarai 	struct open_how how = build_open_how(flags, mode);
1396fddb5d43SAleksa Sarai 	int err = build_open_flags(&how, &op);
1397f9652e10SAl Viro 	if (err)
1398f9652e10SAl Viro 		return ERR_PTR(err);
1399ffb37ca3SAl Viro 	return do_file_open_root(root, filename, &op);
140073d049a4SAl Viro }
140173d049a4SAl Viro EXPORT_SYMBOL(file_open_root);
140273d049a4SAl Viro 
do_sys_openat2(int dfd,const char __user * filename,struct open_how * how)1403fddb5d43SAleksa Sarai static long do_sys_openat2(int dfd, const char __user *filename,
1404fddb5d43SAleksa Sarai 			   struct open_how *how)
14051da177e4SLinus Torvalds {
140647c805dcSAl Viro 	struct open_flags op;
1407fddb5d43SAleksa Sarai 	int fd = build_open_flags(how, &op);
1408f9652e10SAl Viro 	struct filename *tmp;
14091da177e4SLinus Torvalds 
1410f9652e10SAl Viro 	if (fd)
1411f9652e10SAl Viro 		return fd;
1412f9652e10SAl Viro 
1413f9652e10SAl Viro 	tmp = getname(filename);
1414f9652e10SAl Viro 	if (IS_ERR(tmp))
1415f9652e10SAl Viro 		return PTR_ERR(tmp);
1416f9652e10SAl Viro 
1417fddb5d43SAleksa Sarai 	fd = get_unused_fd_flags(how->flags);
14181da177e4SLinus Torvalds 	if (fd >= 0) {
1419f9652e10SAl Viro 		struct file *f = do_filp_open(dfd, tmp, &op);
1420fed2fc18STelemaque Ndizihiwe 		if (IS_ERR(f)) {
1421fed2fc18STelemaque Ndizihiwe 			put_unused_fd(fd);
1422fed2fc18STelemaque Ndizihiwe 			fd = PTR_ERR(f);
1423fed2fc18STelemaque Ndizihiwe 		} else {
14241da177e4SLinus Torvalds 			fd_install(fd, f);
14251da177e4SLinus Torvalds 		}
1426fed2fc18STelemaque Ndizihiwe 	}
14271da177e4SLinus Torvalds 	putname(tmp);
14281da177e4SLinus Torvalds 	return fd;
14291da177e4SLinus Torvalds }
1430e922efc3SMiklos Szeredi 
do_sys_open(int dfd,const char __user * filename,int flags,umode_t mode)1431fddb5d43SAleksa Sarai long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
1432fddb5d43SAleksa Sarai {
1433fddb5d43SAleksa Sarai 	struct open_how how = build_open_how(flags, mode);
1434fddb5d43SAleksa Sarai 	return do_sys_openat2(dfd, filename, &how);
1435fddb5d43SAleksa Sarai }
1436fddb5d43SAleksa Sarai 
1437fddb5d43SAleksa Sarai 
SYSCALL_DEFINE3(open,const char __user *,filename,int,flags,umode_t,mode)1438a218d0fdSAl Viro SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
1439e922efc3SMiklos Szeredi {
1440166e07c3SChristoph Hellwig 	if (force_o_largefile())
1441166e07c3SChristoph Hellwig 		flags |= O_LARGEFILE;
1442166e07c3SChristoph Hellwig 	return do_sys_open(AT_FDCWD, filename, flags, mode);
1443e922efc3SMiklos Szeredi }
14441da177e4SLinus Torvalds 
SYSCALL_DEFINE4(openat,int,dfd,const char __user *,filename,int,flags,umode_t,mode)14456559eed8SHeiko Carstens SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags,
1446a218d0fdSAl Viro 		umode_t, mode)
14475590ff0dSUlrich Drepper {
14485590ff0dSUlrich Drepper 	if (force_o_largefile())
14495590ff0dSUlrich Drepper 		flags |= O_LARGEFILE;
14502cf09666SAl Viro 	return do_sys_open(dfd, filename, flags, mode);
14515590ff0dSUlrich Drepper }
14525590ff0dSUlrich Drepper 
SYSCALL_DEFINE4(openat2,int,dfd,const char __user *,filename,struct open_how __user *,how,size_t,usize)1453fddb5d43SAleksa Sarai SYSCALL_DEFINE4(openat2, int, dfd, const char __user *, filename,
1454fddb5d43SAleksa Sarai 		struct open_how __user *, how, size_t, usize)
1455fddb5d43SAleksa Sarai {
1456fddb5d43SAleksa Sarai 	int err;
1457fddb5d43SAleksa Sarai 	struct open_how tmp;
1458fddb5d43SAleksa Sarai 
1459fddb5d43SAleksa Sarai 	BUILD_BUG_ON(sizeof(struct open_how) < OPEN_HOW_SIZE_VER0);
1460fddb5d43SAleksa Sarai 	BUILD_BUG_ON(sizeof(struct open_how) != OPEN_HOW_SIZE_LATEST);
1461fddb5d43SAleksa Sarai 
1462fddb5d43SAleksa Sarai 	if (unlikely(usize < OPEN_HOW_SIZE_VER0))
1463fddb5d43SAleksa Sarai 		return -EINVAL;
1464fddb5d43SAleksa Sarai 
1465fddb5d43SAleksa Sarai 	err = copy_struct_from_user(&tmp, sizeof(tmp), how, usize);
1466fddb5d43SAleksa Sarai 	if (err)
1467fddb5d43SAleksa Sarai 		return err;
1468fddb5d43SAleksa Sarai 
1469571e5c0eSRichard Guy Briggs 	audit_openat2_how(&tmp);
1470571e5c0eSRichard Guy Briggs 
1471fddb5d43SAleksa Sarai 	/* O_LARGEFILE is only allowed for non-O_PATH. */
1472fddb5d43SAleksa Sarai 	if (!(tmp.flags & O_PATH) && force_o_largefile())
1473fddb5d43SAleksa Sarai 		tmp.flags |= O_LARGEFILE;
1474fddb5d43SAleksa Sarai 
1475fddb5d43SAleksa Sarai 	return do_sys_openat2(dfd, filename, &tmp);
1476fddb5d43SAleksa Sarai }
1477fddb5d43SAleksa Sarai 
1478e35d49f6SAl Viro #ifdef CONFIG_COMPAT
1479e35d49f6SAl Viro /*
1480e35d49f6SAl Viro  * Exactly like sys_open(), except that it doesn't set the
1481e35d49f6SAl Viro  * O_LARGEFILE flag.
1482e35d49f6SAl Viro  */
COMPAT_SYSCALL_DEFINE3(open,const char __user *,filename,int,flags,umode_t,mode)1483e35d49f6SAl Viro COMPAT_SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
1484e35d49f6SAl Viro {
1485e35d49f6SAl Viro 	return do_sys_open(AT_FDCWD, filename, flags, mode);
1486e35d49f6SAl Viro }
1487e35d49f6SAl Viro 
1488e35d49f6SAl Viro /*
1489e35d49f6SAl Viro  * Exactly like sys_openat(), except that it doesn't set the
1490e35d49f6SAl Viro  * O_LARGEFILE flag.
1491e35d49f6SAl Viro  */
COMPAT_SYSCALL_DEFINE4(openat,int,dfd,const char __user *,filename,int,flags,umode_t,mode)1492e35d49f6SAl Viro COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
1493e35d49f6SAl Viro {
1494e35d49f6SAl Viro 	return do_sys_open(dfd, filename, flags, mode);
1495e35d49f6SAl Viro }
1496e35d49f6SAl Viro #endif
1497e35d49f6SAl Viro 
14981da177e4SLinus Torvalds #ifndef __alpha__
14991da177e4SLinus Torvalds 
15001da177e4SLinus Torvalds /*
15011da177e4SLinus Torvalds  * For backward compatibility?  Maybe this should be moved
15021da177e4SLinus Torvalds  * into arch/i386 instead?
15031da177e4SLinus Torvalds  */
SYSCALL_DEFINE2(creat,const char __user *,pathname,umode_t,mode)1504a218d0fdSAl Viro SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
15051da177e4SLinus Torvalds {
1506166e07c3SChristoph Hellwig 	int flags = O_CREAT | O_WRONLY | O_TRUNC;
15071da177e4SLinus Torvalds 
1508166e07c3SChristoph Hellwig 	if (force_o_largefile())
1509166e07c3SChristoph Hellwig 		flags |= O_LARGEFILE;
1510166e07c3SChristoph Hellwig 	return do_sys_open(AT_FDCWD, pathname, flags, mode);
1511166e07c3SChristoph Hellwig }
15121da177e4SLinus Torvalds #endif
15131da177e4SLinus Torvalds 
15141da177e4SLinus Torvalds /*
15151da177e4SLinus Torvalds  * "id" is the POSIX thread ID. We use the
15161da177e4SLinus Torvalds  * files pointer for this..
15171da177e4SLinus Torvalds  */
filp_flush(struct file * filp,fl_owner_t id)1518021a160aSLinus Torvalds static int filp_flush(struct file *filp, fl_owner_t id)
15191da177e4SLinus Torvalds {
152045778ca8SChristoph Lameter 	int retval = 0;
15211da177e4SLinus Torvalds 
152247d58691SJann Horn 	if (CHECK_DATA_CORRUPTION(file_count(filp) == 0,
152347d58691SJann Horn 			"VFS: Close: file count is 0 (f_op=%ps)",
152447d58691SJann Horn 			filp->f_op)) {
152545778ca8SChristoph Lameter 		return 0;
15261da177e4SLinus Torvalds 	}
15271da177e4SLinus Torvalds 
152872c2d531SAl Viro 	if (filp->f_op->flush)
152975e1fcc0SMiklos Szeredi 		retval = filp->f_op->flush(filp, id);
15301da177e4SLinus Torvalds 
15311abf0c71SAl Viro 	if (likely(!(filp->f_mode & FMODE_PATH))) {
15321da177e4SLinus Torvalds 		dnotify_flush(filp, id);
15331da177e4SLinus Torvalds 		locks_remove_posix(filp, id);
15341abf0c71SAl Viro 	}
15351da177e4SLinus Torvalds 	return retval;
15361da177e4SLinus Torvalds }
15371da177e4SLinus Torvalds 
filp_close(struct file * filp,fl_owner_t id)1538021a160aSLinus Torvalds int filp_close(struct file *filp, fl_owner_t id)
1539021a160aSLinus Torvalds {
1540021a160aSLinus Torvalds 	int retval;
1541021a160aSLinus Torvalds 
1542021a160aSLinus Torvalds 	retval = filp_flush(filp, id);
1543021a160aSLinus Torvalds 	fput(filp);
1544021a160aSLinus Torvalds 
1545021a160aSLinus Torvalds 	return retval;
1546021a160aSLinus Torvalds }
15471da177e4SLinus Torvalds EXPORT_SYMBOL(filp_close);
15481da177e4SLinus Torvalds 
15491da177e4SLinus Torvalds /*
15501da177e4SLinus Torvalds  * Careful here! We test whether the file pointer is NULL before
15511da177e4SLinus Torvalds  * releasing the fd. This ensures that one clone task can't release
15521da177e4SLinus Torvalds  * an fd while another clone is opening it.
15531da177e4SLinus Torvalds  */
SYSCALL_DEFINE1(close,unsigned int,fd)1554ca013e94SHeiko Carstens SYSCALL_DEFINE1(close, unsigned int, fd)
15551da177e4SLinus Torvalds {
1556021a160aSLinus Torvalds 	int retval;
1557021a160aSLinus Torvalds 	struct file *file;
1558021a160aSLinus Torvalds 
1559021a160aSLinus Torvalds 	file = close_fd_get_file(fd);
1560021a160aSLinus Torvalds 	if (!file)
1561021a160aSLinus Torvalds 		return -EBADF;
1562021a160aSLinus Torvalds 
1563021a160aSLinus Torvalds 	retval = filp_flush(file, current->files);
1564021a160aSLinus Torvalds 
1565021a160aSLinus Torvalds 	/*
1566021a160aSLinus Torvalds 	 * We're returning to user space. Don't bother
1567021a160aSLinus Torvalds 	 * with any delayed fput() cases.
1568021a160aSLinus Torvalds 	 */
1569021a160aSLinus Torvalds 	__fput_sync(file);
1570ee731f4fSErnie Petrides 
1571ee731f4fSErnie Petrides 	/* can't restart close syscall because file table entry was cleared */
1572ee731f4fSErnie Petrides 	if (unlikely(retval == -ERESTARTSYS ||
1573ee731f4fSErnie Petrides 		     retval == -ERESTARTNOINTR ||
1574ee731f4fSErnie Petrides 		     retval == -ERESTARTNOHAND ||
1575ee731f4fSErnie Petrides 		     retval == -ERESTART_RESTARTBLOCK))
1576ee731f4fSErnie Petrides 		retval = -EINTR;
1577ee731f4fSErnie Petrides 
1578ee731f4fSErnie Petrides 	return retval;
15791da177e4SLinus Torvalds }
15801da177e4SLinus Torvalds 
1581278a5fbaSChristian Brauner /**
1582*35931eb3SMatthew Wilcox (Oracle)  * sys_close_range() - Close all file descriptors in a given range.
1583278a5fbaSChristian Brauner  *
1584278a5fbaSChristian Brauner  * @fd:     starting file descriptor to close
1585278a5fbaSChristian Brauner  * @max_fd: last file descriptor to close
1586278a5fbaSChristian Brauner  * @flags:  reserved for future extensions
1587278a5fbaSChristian Brauner  *
1588278a5fbaSChristian Brauner  * This closes a range of file descriptors. All file descriptors
1589278a5fbaSChristian Brauner  * from @fd up to and including @max_fd are closed.
1590278a5fbaSChristian Brauner  * Currently, errors to close a given file descriptor are ignored.
1591278a5fbaSChristian Brauner  */
SYSCALL_DEFINE3(close_range,unsigned int,fd,unsigned int,max_fd,unsigned int,flags)1592278a5fbaSChristian Brauner SYSCALL_DEFINE3(close_range, unsigned int, fd, unsigned int, max_fd,
1593278a5fbaSChristian Brauner 		unsigned int, flags)
1594278a5fbaSChristian Brauner {
159560997c3dSChristian Brauner 	return __close_range(fd, max_fd, flags);
1596278a5fbaSChristian Brauner }
1597278a5fbaSChristian Brauner 
15981da177e4SLinus Torvalds /*
15991da177e4SLinus Torvalds  * This routine simulates a hangup on the tty, to arrange that users
16001da177e4SLinus Torvalds  * are given clean terminals at login time.
16011da177e4SLinus Torvalds  */
SYSCALL_DEFINE0(vhangup)1602ca013e94SHeiko Carstens SYSCALL_DEFINE0(vhangup)
16031da177e4SLinus Torvalds {
16041da177e4SLinus Torvalds 	if (capable(CAP_SYS_TTY_CONFIG)) {
16052cb5998bSAlan Cox 		tty_vhangup_self();
16061da177e4SLinus Torvalds 		return 0;
16071da177e4SLinus Torvalds 	}
16081da177e4SLinus Torvalds 	return -EPERM;
16091da177e4SLinus Torvalds }
16101da177e4SLinus Torvalds 
16111da177e4SLinus Torvalds /*
16121da177e4SLinus Torvalds  * Called when an inode is about to be open.
16131da177e4SLinus Torvalds  * We use this to disallow opening large files on 32bit systems if
16141da177e4SLinus Torvalds  * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
16151da177e4SLinus Torvalds  * on this flag in sys_open.
16161da177e4SLinus Torvalds  */
generic_file_open(struct inode * inode,struct file * filp)16171da177e4SLinus Torvalds int generic_file_open(struct inode * inode, struct file * filp)
16181da177e4SLinus Torvalds {
16191da177e4SLinus Torvalds 	if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
1620a9c62a18SAlan Cox 		return -EOVERFLOW;
16211da177e4SLinus Torvalds 	return 0;
16221da177e4SLinus Torvalds }
16231da177e4SLinus Torvalds 
16241da177e4SLinus Torvalds EXPORT_SYMBOL(generic_file_open);
16251da177e4SLinus Torvalds 
16261da177e4SLinus Torvalds /*
16271da177e4SLinus Torvalds  * This is used by subsystems that don't want seekable
162806b1e104SDmitry Torokhov  * file descriptors. The function is not supposed to ever fail, the only
162906b1e104SDmitry Torokhov  * reason it returns an 'int' and not 'void' is so that it can be plugged
163006b1e104SDmitry Torokhov  * directly into file_operations structure.
16311da177e4SLinus Torvalds  */
nonseekable_open(struct inode * inode,struct file * filp)16321da177e4SLinus Torvalds int nonseekable_open(struct inode *inode, struct file *filp)
16331da177e4SLinus Torvalds {
16341da177e4SLinus Torvalds 	filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
16351da177e4SLinus Torvalds 	return 0;
16361da177e4SLinus Torvalds }
16371da177e4SLinus Torvalds 
16381da177e4SLinus Torvalds EXPORT_SYMBOL(nonseekable_open);
163910dce8afSKirill Smelkov 
164010dce8afSKirill Smelkov /*
164110dce8afSKirill Smelkov  * stream_open is used by subsystems that want stream-like file descriptors.
164210dce8afSKirill Smelkov  * Such file descriptors are not seekable and don't have notion of position
1643438ab720SKirill Smelkov  * (file.f_pos is always 0 and ppos passed to .read()/.write() is always NULL).
1644438ab720SKirill Smelkov  * Contrary to file descriptors of other regular files, .read() and .write()
1645438ab720SKirill Smelkov  * can run simultaneously.
164610dce8afSKirill Smelkov  *
164710dce8afSKirill Smelkov  * stream_open never fails and is marked to return int so that it could be
164810dce8afSKirill Smelkov  * directly used as file_operations.open .
164910dce8afSKirill Smelkov  */
stream_open(struct inode * inode,struct file * filp)165010dce8afSKirill Smelkov int stream_open(struct inode *inode, struct file *filp)
165110dce8afSKirill Smelkov {
16522be7d348SLinus Torvalds 	filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE | FMODE_ATOMIC_POS);
165310dce8afSKirill Smelkov 	filp->f_mode |= FMODE_STREAM;
165410dce8afSKirill Smelkov 	return 0;
165510dce8afSKirill Smelkov }
165610dce8afSKirill Smelkov 
165710dce8afSKirill Smelkov EXPORT_SYMBOL(stream_open);
1658