Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/fs/ioctl.c
0004  *
0005  *  Copyright (C) 1991, 1992  Linus Torvalds
0006  */
0007 
0008 #include <linux/syscalls.h>
0009 #include <linux/mm.h>
0010 #include <linux/capability.h>
0011 #include <linux/compat.h>
0012 #include <linux/file.h>
0013 #include <linux/fs.h>
0014 #include <linux/security.h>
0015 #include <linux/export.h>
0016 #include <linux/uaccess.h>
0017 #include <linux/writeback.h>
0018 #include <linux/buffer_head.h>
0019 #include <linux/falloc.h>
0020 #include <linux/sched/signal.h>
0021 #include <linux/fiemap.h>
0022 #include <linux/mount.h>
0023 #include <linux/fscrypt.h>
0024 #include <linux/fileattr.h>
0025 
0026 #include "internal.h"
0027 
0028 #include <asm/ioctls.h>
0029 
0030 /* So that the fiemap access checks can't overflow on 32 bit machines. */
0031 #define FIEMAP_MAX_EXTENTS  (UINT_MAX / sizeof(struct fiemap_extent))
0032 
0033 /**
0034  * vfs_ioctl - call filesystem specific ioctl methods
0035  * @filp:   open file to invoke ioctl method on
0036  * @cmd:    ioctl command to execute
0037  * @arg:    command-specific argument for ioctl
0038  *
0039  * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
0040  * returns -ENOTTY.
0041  *
0042  * Returns 0 on success, -errno on error.
0043  */
0044 long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
0045 {
0046     int error = -ENOTTY;
0047 
0048     if (!filp->f_op->unlocked_ioctl)
0049         goto out;
0050 
0051     error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
0052     if (error == -ENOIOCTLCMD)
0053         error = -ENOTTY;
0054  out:
0055     return error;
0056 }
0057 EXPORT_SYMBOL(vfs_ioctl);
0058 
0059 static int ioctl_fibmap(struct file *filp, int __user *p)
0060 {
0061     struct inode *inode = file_inode(filp);
0062     struct super_block *sb = inode->i_sb;
0063     int error, ur_block;
0064     sector_t block;
0065 
0066     if (!capable(CAP_SYS_RAWIO))
0067         return -EPERM;
0068 
0069     error = get_user(ur_block, p);
0070     if (error)
0071         return error;
0072 
0073     if (ur_block < 0)
0074         return -EINVAL;
0075 
0076     block = ur_block;
0077     error = bmap(inode, &block);
0078 
0079     if (block > INT_MAX) {
0080         error = -ERANGE;
0081         pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n",
0082                     current->comm, task_pid_nr(current),
0083                     sb->s_id, filp);
0084     }
0085 
0086     if (error)
0087         ur_block = 0;
0088     else
0089         ur_block = block;
0090 
0091     if (put_user(ur_block, p))
0092         error = -EFAULT;
0093 
0094     return error;
0095 }
0096 
0097 /**
0098  * fiemap_fill_next_extent - Fiemap helper function
0099  * @fieinfo:    Fiemap context passed into ->fiemap
0100  * @logical:    Extent logical start offset, in bytes
0101  * @phys:   Extent physical start offset, in bytes
0102  * @len:    Extent length, in bytes
0103  * @flags:  FIEMAP_EXTENT flags that describe this extent
0104  *
0105  * Called from file system ->fiemap callback. Will populate extent
0106  * info as passed in via arguments and copy to user memory. On
0107  * success, extent count on fieinfo is incremented.
0108  *
0109  * Returns 0 on success, -errno on error, 1 if this was the last
0110  * extent that will fit in user array.
0111  */
0112 #define SET_UNKNOWN_FLAGS   (FIEMAP_EXTENT_DELALLOC)
0113 #define SET_NO_UNMOUNTED_IO_FLAGS   (FIEMAP_EXTENT_DATA_ENCRYPTED)
0114 #define SET_NOT_ALIGNED_FLAGS   (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
0115 int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
0116                 u64 phys, u64 len, u32 flags)
0117 {
0118     struct fiemap_extent extent;
0119     struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
0120 
0121     /* only count the extents */
0122     if (fieinfo->fi_extents_max == 0) {
0123         fieinfo->fi_extents_mapped++;
0124         return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
0125     }
0126 
0127     if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
0128         return 1;
0129 
0130     if (flags & SET_UNKNOWN_FLAGS)
0131         flags |= FIEMAP_EXTENT_UNKNOWN;
0132     if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
0133         flags |= FIEMAP_EXTENT_ENCODED;
0134     if (flags & SET_NOT_ALIGNED_FLAGS)
0135         flags |= FIEMAP_EXTENT_NOT_ALIGNED;
0136 
0137     memset(&extent, 0, sizeof(extent));
0138     extent.fe_logical = logical;
0139     extent.fe_physical = phys;
0140     extent.fe_length = len;
0141     extent.fe_flags = flags;
0142 
0143     dest += fieinfo->fi_extents_mapped;
0144     if (copy_to_user(dest, &extent, sizeof(extent)))
0145         return -EFAULT;
0146 
0147     fieinfo->fi_extents_mapped++;
0148     if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
0149         return 1;
0150     return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
0151 }
0152 EXPORT_SYMBOL(fiemap_fill_next_extent);
0153 
0154 /**
0155  * fiemap_prep - check validity of requested flags for fiemap
0156  * @inode:  Inode to operate on
0157  * @fieinfo:    Fiemap context passed into ->fiemap
0158  * @start:  Start of the mapped range
0159  * @len:    Length of the mapped range, can be truncated by this function.
0160  * @supported_flags:    Set of fiemap flags that the file system understands
0161  *
0162  * This function must be called from each ->fiemap instance to validate the
0163  * fiemap request against the file system parameters.
0164  *
0165  * Returns 0 on success, or a negative error on failure.
0166  */
0167 int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
0168         u64 start, u64 *len, u32 supported_flags)
0169 {
0170     u64 maxbytes = inode->i_sb->s_maxbytes;
0171     u32 incompat_flags;
0172     int ret = 0;
0173 
0174     if (*len == 0)
0175         return -EINVAL;
0176     if (start >= maxbytes)
0177         return -EFBIG;
0178 
0179     /*
0180      * Shrink request scope to what the fs can actually handle.
0181      */
0182     if (*len > maxbytes || (maxbytes - *len) < start)
0183         *len = maxbytes - start;
0184 
0185     supported_flags |= FIEMAP_FLAG_SYNC;
0186     supported_flags &= FIEMAP_FLAGS_COMPAT;
0187     incompat_flags = fieinfo->fi_flags & ~supported_flags;
0188     if (incompat_flags) {
0189         fieinfo->fi_flags = incompat_flags;
0190         return -EBADR;
0191     }
0192 
0193     if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
0194         ret = filemap_write_and_wait(inode->i_mapping);
0195     return ret;
0196 }
0197 EXPORT_SYMBOL(fiemap_prep);
0198 
0199 static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap)
0200 {
0201     struct fiemap fiemap;
0202     struct fiemap_extent_info fieinfo = { 0, };
0203     struct inode *inode = file_inode(filp);
0204     int error;
0205 
0206     if (!inode->i_op->fiemap)
0207         return -EOPNOTSUPP;
0208 
0209     if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
0210         return -EFAULT;
0211 
0212     if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
0213         return -EINVAL;
0214 
0215     fieinfo.fi_flags = fiemap.fm_flags;
0216     fieinfo.fi_extents_max = fiemap.fm_extent_count;
0217     fieinfo.fi_extents_start = ufiemap->fm_extents;
0218 
0219     error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start,
0220             fiemap.fm_length);
0221 
0222     fiemap.fm_flags = fieinfo.fi_flags;
0223     fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
0224     if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
0225         error = -EFAULT;
0226 
0227     return error;
0228 }
0229 
0230 static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
0231                  u64 off, u64 olen, u64 destoff)
0232 {
0233     struct fd src_file = fdget(srcfd);
0234     loff_t cloned;
0235     int ret;
0236 
0237     if (!src_file.file)
0238         return -EBADF;
0239     cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
0240                       olen, 0);
0241     if (cloned < 0)
0242         ret = cloned;
0243     else if (olen && cloned != olen)
0244         ret = -EINVAL;
0245     else
0246         ret = 0;
0247     fdput(src_file);
0248     return ret;
0249 }
0250 
0251 static long ioctl_file_clone_range(struct file *file,
0252                    struct file_clone_range __user *argp)
0253 {
0254     struct file_clone_range args;
0255 
0256     if (copy_from_user(&args, argp, sizeof(args)))
0257         return -EFAULT;
0258     return ioctl_file_clone(file, args.src_fd, args.src_offset,
0259                 args.src_length, args.dest_offset);
0260 }
0261 
0262 /*
0263  * This provides compatibility with legacy XFS pre-allocation ioctls
0264  * which predate the fallocate syscall.
0265  *
0266  * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
0267  * are used here, rest are ignored.
0268  */
0269 static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
0270 {
0271     struct inode *inode = file_inode(filp);
0272     struct space_resv sr;
0273 
0274     if (copy_from_user(&sr, argp, sizeof(sr)))
0275         return -EFAULT;
0276 
0277     switch (sr.l_whence) {
0278     case SEEK_SET:
0279         break;
0280     case SEEK_CUR:
0281         sr.l_start += filp->f_pos;
0282         break;
0283     case SEEK_END:
0284         sr.l_start += i_size_read(inode);
0285         break;
0286     default:
0287         return -EINVAL;
0288     }
0289 
0290     return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
0291             sr.l_len);
0292 }
0293 
0294 /* on ia32 l_start is on a 32-bit boundary */
0295 #if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
0296 /* just account for different alignment */
0297 static int compat_ioctl_preallocate(struct file *file, int mode,
0298                     struct space_resv_32 __user *argp)
0299 {
0300     struct inode *inode = file_inode(file);
0301     struct space_resv_32 sr;
0302 
0303     if (copy_from_user(&sr, argp, sizeof(sr)))
0304         return -EFAULT;
0305 
0306     switch (sr.l_whence) {
0307     case SEEK_SET:
0308         break;
0309     case SEEK_CUR:
0310         sr.l_start += file->f_pos;
0311         break;
0312     case SEEK_END:
0313         sr.l_start += i_size_read(inode);
0314         break;
0315     default:
0316         return -EINVAL;
0317     }
0318 
0319     return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
0320 }
0321 #endif
0322 
0323 static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
0324 {
0325     switch (cmd) {
0326     case FIBMAP:
0327         return ioctl_fibmap(filp, p);
0328     case FS_IOC_RESVSP:
0329     case FS_IOC_RESVSP64:
0330         return ioctl_preallocate(filp, 0, p);
0331     case FS_IOC_UNRESVSP:
0332     case FS_IOC_UNRESVSP64:
0333         return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
0334     case FS_IOC_ZERO_RANGE:
0335         return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
0336     }
0337 
0338     return -ENOIOCTLCMD;
0339 }
0340 
0341 static int ioctl_fionbio(struct file *filp, int __user *argp)
0342 {
0343     unsigned int flag;
0344     int on, error;
0345 
0346     error = get_user(on, argp);
0347     if (error)
0348         return error;
0349     flag = O_NONBLOCK;
0350 #ifdef __sparc__
0351     /* SunOS compatibility item. */
0352     if (O_NONBLOCK != O_NDELAY)
0353         flag |= O_NDELAY;
0354 #endif
0355     spin_lock(&filp->f_lock);
0356     if (on)
0357         filp->f_flags |= flag;
0358     else
0359         filp->f_flags &= ~flag;
0360     spin_unlock(&filp->f_lock);
0361     return error;
0362 }
0363 
0364 static int ioctl_fioasync(unsigned int fd, struct file *filp,
0365               int __user *argp)
0366 {
0367     unsigned int flag;
0368     int on, error;
0369 
0370     error = get_user(on, argp);
0371     if (error)
0372         return error;
0373     flag = on ? FASYNC : 0;
0374 
0375     /* Did FASYNC state change ? */
0376     if ((flag ^ filp->f_flags) & FASYNC) {
0377         if (filp->f_op->fasync)
0378             /* fasync() adjusts filp->f_flags */
0379             error = filp->f_op->fasync(fd, filp, on);
0380         else
0381             error = -ENOTTY;
0382     }
0383     return error < 0 ? error : 0;
0384 }
0385 
0386 static int ioctl_fsfreeze(struct file *filp)
0387 {
0388     struct super_block *sb = file_inode(filp)->i_sb;
0389 
0390     if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
0391         return -EPERM;
0392 
0393     /* If filesystem doesn't support freeze feature, return. */
0394     if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL)
0395         return -EOPNOTSUPP;
0396 
0397     /* Freeze */
0398     if (sb->s_op->freeze_super)
0399         return sb->s_op->freeze_super(sb);
0400     return freeze_super(sb);
0401 }
0402 
0403 static int ioctl_fsthaw(struct file *filp)
0404 {
0405     struct super_block *sb = file_inode(filp)->i_sb;
0406 
0407     if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
0408         return -EPERM;
0409 
0410     /* Thaw */
0411     if (sb->s_op->thaw_super)
0412         return sb->s_op->thaw_super(sb);
0413     return thaw_super(sb);
0414 }
0415 
0416 static int ioctl_file_dedupe_range(struct file *file,
0417                    struct file_dedupe_range __user *argp)
0418 {
0419     struct file_dedupe_range *same = NULL;
0420     int ret;
0421     unsigned long size;
0422     u16 count;
0423 
0424     if (get_user(count, &argp->dest_count)) {
0425         ret = -EFAULT;
0426         goto out;
0427     }
0428 
0429     size = offsetof(struct file_dedupe_range, info[count]);
0430     if (size > PAGE_SIZE) {
0431         ret = -ENOMEM;
0432         goto out;
0433     }
0434 
0435     same = memdup_user(argp, size);
0436     if (IS_ERR(same)) {
0437         ret = PTR_ERR(same);
0438         same = NULL;
0439         goto out;
0440     }
0441 
0442     same->dest_count = count;
0443     ret = vfs_dedupe_file_range(file, same);
0444     if (ret)
0445         goto out;
0446 
0447     ret = copy_to_user(argp, same, size);
0448     if (ret)
0449         ret = -EFAULT;
0450 
0451 out:
0452     kfree(same);
0453     return ret;
0454 }
0455 
0456 /**
0457  * fileattr_fill_xflags - initialize fileattr with xflags
0458  * @fa:     fileattr pointer
0459  * @xflags: FS_XFLAG_* flags
0460  *
0461  * Set ->fsx_xflags, ->fsx_valid and ->flags (translated xflags).  All
0462  * other fields are zeroed.
0463  */
0464 void fileattr_fill_xflags(struct fileattr *fa, u32 xflags)
0465 {
0466     memset(fa, 0, sizeof(*fa));
0467     fa->fsx_valid = true;
0468     fa->fsx_xflags = xflags;
0469     if (fa->fsx_xflags & FS_XFLAG_IMMUTABLE)
0470         fa->flags |= FS_IMMUTABLE_FL;
0471     if (fa->fsx_xflags & FS_XFLAG_APPEND)
0472         fa->flags |= FS_APPEND_FL;
0473     if (fa->fsx_xflags & FS_XFLAG_SYNC)
0474         fa->flags |= FS_SYNC_FL;
0475     if (fa->fsx_xflags & FS_XFLAG_NOATIME)
0476         fa->flags |= FS_NOATIME_FL;
0477     if (fa->fsx_xflags & FS_XFLAG_NODUMP)
0478         fa->flags |= FS_NODUMP_FL;
0479     if (fa->fsx_xflags & FS_XFLAG_DAX)
0480         fa->flags |= FS_DAX_FL;
0481     if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT)
0482         fa->flags |= FS_PROJINHERIT_FL;
0483 }
0484 EXPORT_SYMBOL(fileattr_fill_xflags);
0485 
0486 /**
0487  * fileattr_fill_flags - initialize fileattr with flags
0488  * @fa:     fileattr pointer
0489  * @flags:  FS_*_FL flags
0490  *
0491  * Set ->flags, ->flags_valid and ->fsx_xflags (translated flags).
0492  * All other fields are zeroed.
0493  */
0494 void fileattr_fill_flags(struct fileattr *fa, u32 flags)
0495 {
0496     memset(fa, 0, sizeof(*fa));
0497     fa->flags_valid = true;
0498     fa->flags = flags;
0499     if (fa->flags & FS_SYNC_FL)
0500         fa->fsx_xflags |= FS_XFLAG_SYNC;
0501     if (fa->flags & FS_IMMUTABLE_FL)
0502         fa->fsx_xflags |= FS_XFLAG_IMMUTABLE;
0503     if (fa->flags & FS_APPEND_FL)
0504         fa->fsx_xflags |= FS_XFLAG_APPEND;
0505     if (fa->flags & FS_NODUMP_FL)
0506         fa->fsx_xflags |= FS_XFLAG_NODUMP;
0507     if (fa->flags & FS_NOATIME_FL)
0508         fa->fsx_xflags |= FS_XFLAG_NOATIME;
0509     if (fa->flags & FS_DAX_FL)
0510         fa->fsx_xflags |= FS_XFLAG_DAX;
0511     if (fa->flags & FS_PROJINHERIT_FL)
0512         fa->fsx_xflags |= FS_XFLAG_PROJINHERIT;
0513 }
0514 EXPORT_SYMBOL(fileattr_fill_flags);
0515 
0516 /**
0517  * vfs_fileattr_get - retrieve miscellaneous file attributes
0518  * @dentry: the object to retrieve from
0519  * @fa:     fileattr pointer
0520  *
0521  * Call i_op->fileattr_get() callback, if exists.
0522  *
0523  * Return: 0 on success, or a negative error on failure.
0524  */
0525 int vfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
0526 {
0527     struct inode *inode = d_inode(dentry);
0528 
0529     if (!inode->i_op->fileattr_get)
0530         return -ENOIOCTLCMD;
0531 
0532     return inode->i_op->fileattr_get(dentry, fa);
0533 }
0534 EXPORT_SYMBOL(vfs_fileattr_get);
0535 
0536 /**
0537  * copy_fsxattr_to_user - copy fsxattr to userspace.
0538  * @fa:     fileattr pointer
0539  * @ufa:    fsxattr user pointer
0540  *
0541  * Return: 0 on success, or -EFAULT on failure.
0542  */
0543 int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
0544 {
0545     struct fsxattr xfa;
0546 
0547     memset(&xfa, 0, sizeof(xfa));
0548     xfa.fsx_xflags = fa->fsx_xflags;
0549     xfa.fsx_extsize = fa->fsx_extsize;
0550     xfa.fsx_nextents = fa->fsx_nextents;
0551     xfa.fsx_projid = fa->fsx_projid;
0552     xfa.fsx_cowextsize = fa->fsx_cowextsize;
0553 
0554     if (copy_to_user(ufa, &xfa, sizeof(xfa)))
0555         return -EFAULT;
0556 
0557     return 0;
0558 }
0559 EXPORT_SYMBOL(copy_fsxattr_to_user);
0560 
0561 static int copy_fsxattr_from_user(struct fileattr *fa,
0562                   struct fsxattr __user *ufa)
0563 {
0564     struct fsxattr xfa;
0565 
0566     if (copy_from_user(&xfa, ufa, sizeof(xfa)))
0567         return -EFAULT;
0568 
0569     fileattr_fill_xflags(fa, xfa.fsx_xflags);
0570     fa->fsx_extsize = xfa.fsx_extsize;
0571     fa->fsx_nextents = xfa.fsx_nextents;
0572     fa->fsx_projid = xfa.fsx_projid;
0573     fa->fsx_cowextsize = xfa.fsx_cowextsize;
0574 
0575     return 0;
0576 }
0577 
0578 /*
0579  * Generic function to check FS_IOC_FSSETXATTR/FS_IOC_SETFLAGS values and reject
0580  * any invalid configurations.
0581  *
0582  * Note: must be called with inode lock held.
0583  */
0584 static int fileattr_set_prepare(struct inode *inode,
0585                   const struct fileattr *old_ma,
0586                   struct fileattr *fa)
0587 {
0588     int err;
0589 
0590     /*
0591      * The IMMUTABLE and APPEND_ONLY flags can only be changed by
0592      * the relevant capability.
0593      */
0594     if ((fa->flags ^ old_ma->flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) &&
0595         !capable(CAP_LINUX_IMMUTABLE))
0596         return -EPERM;
0597 
0598     err = fscrypt_prepare_setflags(inode, old_ma->flags, fa->flags);
0599     if (err)
0600         return err;
0601 
0602     /*
0603      * Project Quota ID state is only allowed to change from within the init
0604      * namespace. Enforce that restriction only if we are trying to change
0605      * the quota ID state. Everything else is allowed in user namespaces.
0606      */
0607     if (current_user_ns() != &init_user_ns) {
0608         if (old_ma->fsx_projid != fa->fsx_projid)
0609             return -EINVAL;
0610         if ((old_ma->fsx_xflags ^ fa->fsx_xflags) &
0611                 FS_XFLAG_PROJINHERIT)
0612             return -EINVAL;
0613     } else {
0614         /*
0615          * Caller is allowed to change the project ID. If it is being
0616          * changed, make sure that the new value is valid.
0617          */
0618         if (old_ma->fsx_projid != fa->fsx_projid &&
0619             !projid_valid(make_kprojid(&init_user_ns, fa->fsx_projid)))
0620             return -EINVAL;
0621     }
0622 
0623     /* Check extent size hints. */
0624     if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode))
0625         return -EINVAL;
0626 
0627     if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
0628             !S_ISDIR(inode->i_mode))
0629         return -EINVAL;
0630 
0631     if ((fa->fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
0632         !S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
0633         return -EINVAL;
0634 
0635     /*
0636      * It is only valid to set the DAX flag on regular files and
0637      * directories on filesystems.
0638      */
0639     if ((fa->fsx_xflags & FS_XFLAG_DAX) &&
0640         !(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
0641         return -EINVAL;
0642 
0643     /* Extent size hints of zero turn off the flags. */
0644     if (fa->fsx_extsize == 0)
0645         fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
0646     if (fa->fsx_cowextsize == 0)
0647         fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
0648 
0649     return 0;
0650 }
0651 
0652 /**
0653  * vfs_fileattr_set - change miscellaneous file attributes
0654  * @mnt_userns: user namespace of the mount
0655  * @dentry: the object to change
0656  * @fa:     fileattr pointer
0657  *
0658  * After verifying permissions, call i_op->fileattr_set() callback, if
0659  * exists.
0660  *
0661  * Verifying attributes involves retrieving current attributes with
0662  * i_op->fileattr_get(), this also allows initializing attributes that have
0663  * not been set by the caller to current values.  Inode lock is held
0664  * thoughout to prevent racing with another instance.
0665  *
0666  * Return: 0 on success, or a negative error on failure.
0667  */
0668 int vfs_fileattr_set(struct user_namespace *mnt_userns, struct dentry *dentry,
0669              struct fileattr *fa)
0670 {
0671     struct inode *inode = d_inode(dentry);
0672     struct fileattr old_ma = {};
0673     int err;
0674 
0675     if (!inode->i_op->fileattr_set)
0676         return -ENOIOCTLCMD;
0677 
0678     if (!inode_owner_or_capable(mnt_userns, inode))
0679         return -EPERM;
0680 
0681     inode_lock(inode);
0682     err = vfs_fileattr_get(dentry, &old_ma);
0683     if (!err) {
0684         /* initialize missing bits from old_ma */
0685         if (fa->flags_valid) {
0686             fa->fsx_xflags |= old_ma.fsx_xflags & ~FS_XFLAG_COMMON;
0687             fa->fsx_extsize = old_ma.fsx_extsize;
0688             fa->fsx_nextents = old_ma.fsx_nextents;
0689             fa->fsx_projid = old_ma.fsx_projid;
0690             fa->fsx_cowextsize = old_ma.fsx_cowextsize;
0691         } else {
0692             fa->flags |= old_ma.flags & ~FS_COMMON_FL;
0693         }
0694         err = fileattr_set_prepare(inode, &old_ma, fa);
0695         if (!err)
0696             err = inode->i_op->fileattr_set(mnt_userns, dentry, fa);
0697     }
0698     inode_unlock(inode);
0699 
0700     return err;
0701 }
0702 EXPORT_SYMBOL(vfs_fileattr_set);
0703 
0704 static int ioctl_getflags(struct file *file, unsigned int __user *argp)
0705 {
0706     struct fileattr fa = { .flags_valid = true }; /* hint only */
0707     int err;
0708 
0709     err = vfs_fileattr_get(file->f_path.dentry, &fa);
0710     if (!err)
0711         err = put_user(fa.flags, argp);
0712     return err;
0713 }
0714 
0715 static int ioctl_setflags(struct file *file, unsigned int __user *argp)
0716 {
0717     struct user_namespace *mnt_userns = file_mnt_user_ns(file);
0718     struct dentry *dentry = file->f_path.dentry;
0719     struct fileattr fa;
0720     unsigned int flags;
0721     int err;
0722 
0723     err = get_user(flags, argp);
0724     if (!err) {
0725         err = mnt_want_write_file(file);
0726         if (!err) {
0727             fileattr_fill_flags(&fa, flags);
0728             err = vfs_fileattr_set(mnt_userns, dentry, &fa);
0729             mnt_drop_write_file(file);
0730         }
0731     }
0732     return err;
0733 }
0734 
0735 static int ioctl_fsgetxattr(struct file *file, void __user *argp)
0736 {
0737     struct fileattr fa = { .fsx_valid = true }; /* hint only */
0738     int err;
0739 
0740     err = vfs_fileattr_get(file->f_path.dentry, &fa);
0741     if (!err)
0742         err = copy_fsxattr_to_user(&fa, argp);
0743 
0744     return err;
0745 }
0746 
0747 static int ioctl_fssetxattr(struct file *file, void __user *argp)
0748 {
0749     struct user_namespace *mnt_userns = file_mnt_user_ns(file);
0750     struct dentry *dentry = file->f_path.dentry;
0751     struct fileattr fa;
0752     int err;
0753 
0754     err = copy_fsxattr_from_user(&fa, argp);
0755     if (!err) {
0756         err = mnt_want_write_file(file);
0757         if (!err) {
0758             err = vfs_fileattr_set(mnt_userns, dentry, &fa);
0759             mnt_drop_write_file(file);
0760         }
0761     }
0762     return err;
0763 }
0764 
0765 /*
0766  * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
0767  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
0768  *
0769  * When you add any new common ioctls to the switches above and below,
0770  * please ensure they have compatible arguments in compat mode.
0771  */
0772 static int do_vfs_ioctl(struct file *filp, unsigned int fd,
0773             unsigned int cmd, unsigned long arg)
0774 {
0775     void __user *argp = (void __user *)arg;
0776     struct inode *inode = file_inode(filp);
0777 
0778     switch (cmd) {
0779     case FIOCLEX:
0780         set_close_on_exec(fd, 1);
0781         return 0;
0782 
0783     case FIONCLEX:
0784         set_close_on_exec(fd, 0);
0785         return 0;
0786 
0787     case FIONBIO:
0788         return ioctl_fionbio(filp, argp);
0789 
0790     case FIOASYNC:
0791         return ioctl_fioasync(fd, filp, argp);
0792 
0793     case FIOQSIZE:
0794         if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
0795             S_ISLNK(inode->i_mode)) {
0796             loff_t res = inode_get_bytes(inode);
0797             return copy_to_user(argp, &res, sizeof(res)) ?
0798                         -EFAULT : 0;
0799         }
0800 
0801         return -ENOTTY;
0802 
0803     case FIFREEZE:
0804         return ioctl_fsfreeze(filp);
0805 
0806     case FITHAW:
0807         return ioctl_fsthaw(filp);
0808 
0809     case FS_IOC_FIEMAP:
0810         return ioctl_fiemap(filp, argp);
0811 
0812     case FIGETBSZ:
0813         /* anon_bdev filesystems may not have a block size */
0814         if (!inode->i_sb->s_blocksize)
0815             return -EINVAL;
0816 
0817         return put_user(inode->i_sb->s_blocksize, (int __user *)argp);
0818 
0819     case FICLONE:
0820         return ioctl_file_clone(filp, arg, 0, 0, 0);
0821 
0822     case FICLONERANGE:
0823         return ioctl_file_clone_range(filp, argp);
0824 
0825     case FIDEDUPERANGE:
0826         return ioctl_file_dedupe_range(filp, argp);
0827 
0828     case FIONREAD:
0829         if (!S_ISREG(inode->i_mode))
0830             return vfs_ioctl(filp, cmd, arg);
0831 
0832         return put_user(i_size_read(inode) - filp->f_pos,
0833                 (int __user *)argp);
0834 
0835     case FS_IOC_GETFLAGS:
0836         return ioctl_getflags(filp, argp);
0837 
0838     case FS_IOC_SETFLAGS:
0839         return ioctl_setflags(filp, argp);
0840 
0841     case FS_IOC_FSGETXATTR:
0842         return ioctl_fsgetxattr(filp, argp);
0843 
0844     case FS_IOC_FSSETXATTR:
0845         return ioctl_fssetxattr(filp, argp);
0846 
0847     default:
0848         if (S_ISREG(inode->i_mode))
0849             return file_ioctl(filp, cmd, argp);
0850         break;
0851     }
0852 
0853     return -ENOIOCTLCMD;
0854 }
0855 
0856 SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
0857 {
0858     struct fd f = fdget(fd);
0859     int error;
0860 
0861     if (!f.file)
0862         return -EBADF;
0863 
0864     error = security_file_ioctl(f.file, cmd, arg);
0865     if (error)
0866         goto out;
0867 
0868     error = do_vfs_ioctl(f.file, fd, cmd, arg);
0869     if (error == -ENOIOCTLCMD)
0870         error = vfs_ioctl(f.file, cmd, arg);
0871 
0872 out:
0873     fdput(f);
0874     return error;
0875 }
0876 
0877 #ifdef CONFIG_COMPAT
0878 /**
0879  * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation
0880  *
0881  * This is not normally called as a function, but instead set in struct
0882  * file_operations as
0883  *
0884  *     .compat_ioctl = compat_ptr_ioctl,
0885  *
0886  * On most architectures, the compat_ptr_ioctl() just passes all arguments
0887  * to the corresponding ->ioctl handler. The exception is arch/s390, where
0888  * compat_ptr() clears the top bit of a 32-bit pointer value, so user space
0889  * pointers to the second 2GB alias the first 2GB, as is the case for
0890  * native 32-bit s390 user space.
0891  *
0892  * The compat_ptr_ioctl() function must therefore be used only with ioctl
0893  * functions that either ignore the argument or pass a pointer to a
0894  * compatible data type.
0895  *
0896  * If any ioctl command handled by fops->unlocked_ioctl passes a plain
0897  * integer instead of a pointer, or any of the passed data types
0898  * is incompatible between 32-bit and 64-bit architectures, a proper
0899  * handler is required instead of compat_ptr_ioctl.
0900  */
0901 long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0902 {
0903     if (!file->f_op->unlocked_ioctl)
0904         return -ENOIOCTLCMD;
0905 
0906     return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
0907 }
0908 EXPORT_SYMBOL(compat_ptr_ioctl);
0909 
0910 COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
0911                compat_ulong_t, arg)
0912 {
0913     struct fd f = fdget(fd);
0914     int error;
0915 
0916     if (!f.file)
0917         return -EBADF;
0918 
0919     /* RED-PEN how should LSM module know it's handling 32bit? */
0920     error = security_file_ioctl(f.file, cmd, arg);
0921     if (error)
0922         goto out;
0923 
0924     switch (cmd) {
0925     /* FICLONE takes an int argument, so don't use compat_ptr() */
0926     case FICLONE:
0927         error = ioctl_file_clone(f.file, arg, 0, 0, 0);
0928         break;
0929 
0930 #if defined(CONFIG_X86_64)
0931     /* these get messy on amd64 due to alignment differences */
0932     case FS_IOC_RESVSP_32:
0933     case FS_IOC_RESVSP64_32:
0934         error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
0935         break;
0936     case FS_IOC_UNRESVSP_32:
0937     case FS_IOC_UNRESVSP64_32:
0938         error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
0939                 compat_ptr(arg));
0940         break;
0941     case FS_IOC_ZERO_RANGE_32:
0942         error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
0943                 compat_ptr(arg));
0944         break;
0945 #endif
0946 
0947     /*
0948      * These access 32-bit values anyway so no further handling is
0949      * necessary.
0950      */
0951     case FS_IOC32_GETFLAGS:
0952     case FS_IOC32_SETFLAGS:
0953         cmd = (cmd == FS_IOC32_GETFLAGS) ?
0954             FS_IOC_GETFLAGS : FS_IOC_SETFLAGS;
0955         fallthrough;
0956     /*
0957      * everything else in do_vfs_ioctl() takes either a compatible
0958      * pointer argument or no argument -- call it with a modified
0959      * argument.
0960      */
0961     default:
0962         error = do_vfs_ioctl(f.file, fd, cmd,
0963                      (unsigned long)compat_ptr(arg));
0964         if (error != -ENOIOCTLCMD)
0965             break;
0966 
0967         if (f.file->f_op->compat_ioctl)
0968             error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
0969         if (error == -ENOIOCTLCMD)
0970             error = -ENOTTY;
0971         break;
0972     }
0973 
0974  out:
0975     fdput(f);
0976 
0977     return error;
0978 }
0979 #endif