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,off_t,length)20383635924SArnd Bergmann SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, 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_off_t,length)20983635924SArnd Bergmann COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_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
116535931eb3SMatthew 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;
1464*f421a3b1SAleksa Sarai if (unlikely(usize > PAGE_SIZE))
1465*f421a3b1SAleksa Sarai return -E2BIG;
1466fddb5d43SAleksa Sarai
1467fddb5d43SAleksa Sarai err = copy_struct_from_user(&tmp, sizeof(tmp), how, usize);
1468fddb5d43SAleksa Sarai if (err)
1469fddb5d43SAleksa Sarai return err;
1470fddb5d43SAleksa Sarai
1471571e5c0eSRichard Guy Briggs audit_openat2_how(&tmp);
1472571e5c0eSRichard Guy Briggs
1473fddb5d43SAleksa Sarai /* O_LARGEFILE is only allowed for non-O_PATH. */
1474fddb5d43SAleksa Sarai if (!(tmp.flags & O_PATH) && force_o_largefile())
1475fddb5d43SAleksa Sarai tmp.flags |= O_LARGEFILE;
1476fddb5d43SAleksa Sarai
1477fddb5d43SAleksa Sarai return do_sys_openat2(dfd, filename, &tmp);
1478fddb5d43SAleksa Sarai }
1479fddb5d43SAleksa Sarai
1480e35d49f6SAl Viro #ifdef CONFIG_COMPAT
1481e35d49f6SAl Viro /*
1482e35d49f6SAl Viro * Exactly like sys_open(), except that it doesn't set the
1483e35d49f6SAl Viro * O_LARGEFILE flag.
1484e35d49f6SAl Viro */
COMPAT_SYSCALL_DEFINE3(open,const char __user *,filename,int,flags,umode_t,mode)1485e35d49f6SAl Viro COMPAT_SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
1486e35d49f6SAl Viro {
1487e35d49f6SAl Viro return do_sys_open(AT_FDCWD, filename, flags, mode);
1488e35d49f6SAl Viro }
1489e35d49f6SAl Viro
1490e35d49f6SAl Viro /*
1491e35d49f6SAl Viro * Exactly like sys_openat(), except that it doesn't set the
1492e35d49f6SAl Viro * O_LARGEFILE flag.
1493e35d49f6SAl Viro */
COMPAT_SYSCALL_DEFINE4(openat,int,dfd,const char __user *,filename,int,flags,umode_t,mode)1494e35d49f6SAl Viro COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode)
1495e35d49f6SAl Viro {
1496e35d49f6SAl Viro return do_sys_open(dfd, filename, flags, mode);
1497e35d49f6SAl Viro }
1498e35d49f6SAl Viro #endif
1499e35d49f6SAl Viro
15001da177e4SLinus Torvalds #ifndef __alpha__
15011da177e4SLinus Torvalds
15021da177e4SLinus Torvalds /*
15031da177e4SLinus Torvalds * For backward compatibility? Maybe this should be moved
15041da177e4SLinus Torvalds * into arch/i386 instead?
15051da177e4SLinus Torvalds */
SYSCALL_DEFINE2(creat,const char __user *,pathname,umode_t,mode)1506a218d0fdSAl Viro SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
15071da177e4SLinus Torvalds {
1508166e07c3SChristoph Hellwig int flags = O_CREAT | O_WRONLY | O_TRUNC;
15091da177e4SLinus Torvalds
1510166e07c3SChristoph Hellwig if (force_o_largefile())
1511166e07c3SChristoph Hellwig flags |= O_LARGEFILE;
1512166e07c3SChristoph Hellwig return do_sys_open(AT_FDCWD, pathname, flags, mode);
1513166e07c3SChristoph Hellwig }
15141da177e4SLinus Torvalds #endif
15151da177e4SLinus Torvalds
15161da177e4SLinus Torvalds /*
15171da177e4SLinus Torvalds * "id" is the POSIX thread ID. We use the
15181da177e4SLinus Torvalds * files pointer for this..
15191da177e4SLinus Torvalds */
filp_flush(struct file * filp,fl_owner_t id)1520021a160aSLinus Torvalds static int filp_flush(struct file *filp, fl_owner_t id)
15211da177e4SLinus Torvalds {
152245778ca8SChristoph Lameter int retval = 0;
15231da177e4SLinus Torvalds
152447d58691SJann Horn if (CHECK_DATA_CORRUPTION(file_count(filp) == 0,
152547d58691SJann Horn "VFS: Close: file count is 0 (f_op=%ps)",
152647d58691SJann Horn filp->f_op)) {
152745778ca8SChristoph Lameter return 0;
15281da177e4SLinus Torvalds }
15291da177e4SLinus Torvalds
153072c2d531SAl Viro if (filp->f_op->flush)
153175e1fcc0SMiklos Szeredi retval = filp->f_op->flush(filp, id);
15321da177e4SLinus Torvalds
15331abf0c71SAl Viro if (likely(!(filp->f_mode & FMODE_PATH))) {
15341da177e4SLinus Torvalds dnotify_flush(filp, id);
15351da177e4SLinus Torvalds locks_remove_posix(filp, id);
15361abf0c71SAl Viro }
15371da177e4SLinus Torvalds return retval;
15381da177e4SLinus Torvalds }
15391da177e4SLinus Torvalds
filp_close(struct file * filp,fl_owner_t id)1540021a160aSLinus Torvalds int filp_close(struct file *filp, fl_owner_t id)
1541021a160aSLinus Torvalds {
1542021a160aSLinus Torvalds int retval;
1543021a160aSLinus Torvalds
1544021a160aSLinus Torvalds retval = filp_flush(filp, id);
1545021a160aSLinus Torvalds fput(filp);
1546021a160aSLinus Torvalds
1547021a160aSLinus Torvalds return retval;
1548021a160aSLinus Torvalds }
15491da177e4SLinus Torvalds EXPORT_SYMBOL(filp_close);
15501da177e4SLinus Torvalds
15511da177e4SLinus Torvalds /*
15521da177e4SLinus Torvalds * Careful here! We test whether the file pointer is NULL before
15531da177e4SLinus Torvalds * releasing the fd. This ensures that one clone task can't release
15541da177e4SLinus Torvalds * an fd while another clone is opening it.
15551da177e4SLinus Torvalds */
SYSCALL_DEFINE1(close,unsigned int,fd)1556ca013e94SHeiko Carstens SYSCALL_DEFINE1(close, unsigned int, fd)
15571da177e4SLinus Torvalds {
1558021a160aSLinus Torvalds int retval;
1559021a160aSLinus Torvalds struct file *file;
1560021a160aSLinus Torvalds
1561021a160aSLinus Torvalds file = close_fd_get_file(fd);
1562021a160aSLinus Torvalds if (!file)
1563021a160aSLinus Torvalds return -EBADF;
1564021a160aSLinus Torvalds
1565021a160aSLinus Torvalds retval = filp_flush(file, current->files);
1566021a160aSLinus Torvalds
1567021a160aSLinus Torvalds /*
1568021a160aSLinus Torvalds * We're returning to user space. Don't bother
1569021a160aSLinus Torvalds * with any delayed fput() cases.
1570021a160aSLinus Torvalds */
1571021a160aSLinus Torvalds __fput_sync(file);
1572ee731f4fSErnie Petrides
1573ee731f4fSErnie Petrides /* can't restart close syscall because file table entry was cleared */
1574ee731f4fSErnie Petrides if (unlikely(retval == -ERESTARTSYS ||
1575ee731f4fSErnie Petrides retval == -ERESTARTNOINTR ||
1576ee731f4fSErnie Petrides retval == -ERESTARTNOHAND ||
1577ee731f4fSErnie Petrides retval == -ERESTART_RESTARTBLOCK))
1578ee731f4fSErnie Petrides retval = -EINTR;
1579ee731f4fSErnie Petrides
1580ee731f4fSErnie Petrides return retval;
15811da177e4SLinus Torvalds }
15821da177e4SLinus Torvalds
1583278a5fbaSChristian Brauner /**
158435931eb3SMatthew Wilcox (Oracle) * sys_close_range() - Close all file descriptors in a given range.
1585278a5fbaSChristian Brauner *
1586278a5fbaSChristian Brauner * @fd: starting file descriptor to close
1587278a5fbaSChristian Brauner * @max_fd: last file descriptor to close
1588278a5fbaSChristian Brauner * @flags: reserved for future extensions
1589278a5fbaSChristian Brauner *
1590278a5fbaSChristian Brauner * This closes a range of file descriptors. All file descriptors
1591278a5fbaSChristian Brauner * from @fd up to and including @max_fd are closed.
1592278a5fbaSChristian Brauner * Currently, errors to close a given file descriptor are ignored.
1593278a5fbaSChristian Brauner */
SYSCALL_DEFINE3(close_range,unsigned int,fd,unsigned int,max_fd,unsigned int,flags)1594278a5fbaSChristian Brauner SYSCALL_DEFINE3(close_range, unsigned int, fd, unsigned int, max_fd,
1595278a5fbaSChristian Brauner unsigned int, flags)
1596278a5fbaSChristian Brauner {
159760997c3dSChristian Brauner return __close_range(fd, max_fd, flags);
1598278a5fbaSChristian Brauner }
1599278a5fbaSChristian Brauner
16001da177e4SLinus Torvalds /*
16011da177e4SLinus Torvalds * This routine simulates a hangup on the tty, to arrange that users
16021da177e4SLinus Torvalds * are given clean terminals at login time.
16031da177e4SLinus Torvalds */
SYSCALL_DEFINE0(vhangup)1604ca013e94SHeiko Carstens SYSCALL_DEFINE0(vhangup)
16051da177e4SLinus Torvalds {
16061da177e4SLinus Torvalds if (capable(CAP_SYS_TTY_CONFIG)) {
16072cb5998bSAlan Cox tty_vhangup_self();
16081da177e4SLinus Torvalds return 0;
16091da177e4SLinus Torvalds }
16101da177e4SLinus Torvalds return -EPERM;
16111da177e4SLinus Torvalds }
16121da177e4SLinus Torvalds
16131da177e4SLinus Torvalds /*
16141da177e4SLinus Torvalds * Called when an inode is about to be open.
16151da177e4SLinus Torvalds * We use this to disallow opening large files on 32bit systems if
16161da177e4SLinus Torvalds * the caller didn't specify O_LARGEFILE. On 64bit systems we force
16171da177e4SLinus Torvalds * on this flag in sys_open.
16181da177e4SLinus Torvalds */
generic_file_open(struct inode * inode,struct file * filp)16191da177e4SLinus Torvalds int generic_file_open(struct inode * inode, struct file * filp)
16201da177e4SLinus Torvalds {
16211da177e4SLinus Torvalds if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
1622a9c62a18SAlan Cox return -EOVERFLOW;
16231da177e4SLinus Torvalds return 0;
16241da177e4SLinus Torvalds }
16251da177e4SLinus Torvalds
16261da177e4SLinus Torvalds EXPORT_SYMBOL(generic_file_open);
16271da177e4SLinus Torvalds
16281da177e4SLinus Torvalds /*
16291da177e4SLinus Torvalds * This is used by subsystems that don't want seekable
163006b1e104SDmitry Torokhov * file descriptors. The function is not supposed to ever fail, the only
163106b1e104SDmitry Torokhov * reason it returns an 'int' and not 'void' is so that it can be plugged
163206b1e104SDmitry Torokhov * directly into file_operations structure.
16331da177e4SLinus Torvalds */
nonseekable_open(struct inode * inode,struct file * filp)16341da177e4SLinus Torvalds int nonseekable_open(struct inode *inode, struct file *filp)
16351da177e4SLinus Torvalds {
16361da177e4SLinus Torvalds filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
16371da177e4SLinus Torvalds return 0;
16381da177e4SLinus Torvalds }
16391da177e4SLinus Torvalds
16401da177e4SLinus Torvalds EXPORT_SYMBOL(nonseekable_open);
164110dce8afSKirill Smelkov
164210dce8afSKirill Smelkov /*
164310dce8afSKirill Smelkov * stream_open is used by subsystems that want stream-like file descriptors.
164410dce8afSKirill Smelkov * Such file descriptors are not seekable and don't have notion of position
1645438ab720SKirill Smelkov * (file.f_pos is always 0 and ppos passed to .read()/.write() is always NULL).
1646438ab720SKirill Smelkov * Contrary to file descriptors of other regular files, .read() and .write()
1647438ab720SKirill Smelkov * can run simultaneously.
164810dce8afSKirill Smelkov *
164910dce8afSKirill Smelkov * stream_open never fails and is marked to return int so that it could be
165010dce8afSKirill Smelkov * directly used as file_operations.open .
165110dce8afSKirill Smelkov */
stream_open(struct inode * inode,struct file * filp)165210dce8afSKirill Smelkov int stream_open(struct inode *inode, struct file *filp)
165310dce8afSKirill Smelkov {
16542be7d348SLinus Torvalds filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE | FMODE_ATOMIC_POS);
165510dce8afSKirill Smelkov filp->f_mode |= FMODE_STREAM;
165610dce8afSKirill Smelkov return 0;
165710dce8afSKirill Smelkov }
165810dce8afSKirill Smelkov
165910dce8afSKirill Smelkov EXPORT_SYMBOL(stream_open);
1660