LCOV - code coverage report
Current view: top level - fs - ioctl.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 343 388 88.4 %
Date: 2023-07-31 20:08:07 Functions: 27 28 96.4 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  *  linux/fs/ioctl.c
       4             :  *
       5             :  *  Copyright (C) 1991, 1992  Linus Torvalds
       6             :  */
       7             : 
       8             : #include <linux/syscalls.h>
       9             : #include <linux/mm.h>
      10             : #include <linux/capability.h>
      11             : #include <linux/compat.h>
      12             : #include <linux/file.h>
      13             : #include <linux/fs.h>
      14             : #include <linux/security.h>
      15             : #include <linux/export.h>
      16             : #include <linux/uaccess.h>
      17             : #include <linux/writeback.h>
      18             : #include <linux/buffer_head.h>
      19             : #include <linux/falloc.h>
      20             : #include <linux/sched/signal.h>
      21             : #include <linux/fiemap.h>
      22             : #include <linux/mount.h>
      23             : #include <linux/fscrypt.h>
      24             : #include <linux/fileattr.h>
      25             : 
      26             : #include "internal.h"
      27             : 
      28             : #include <asm/ioctls.h>
      29             : 
      30             : /* So that the fiemap access checks can't overflow on 32 bit machines. */
      31             : #define FIEMAP_MAX_EXTENTS      (UINT_MAX / sizeof(struct fiemap_extent))
      32             : 
      33             : /**
      34             :  * vfs_ioctl - call filesystem specific ioctl methods
      35             :  * @filp:       open file to invoke ioctl method on
      36             :  * @cmd:        ioctl command to execute
      37             :  * @arg:        command-specific argument for ioctl
      38             :  *
      39             :  * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
      40             :  * returns -ENOTTY.
      41             :  *
      42             :  * Returns 0 on success, -errno on error.
      43             :  */
      44  1534352902 : long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
      45             : {
      46  1534352902 :         int error = -ENOTTY;
      47             : 
      48  1534352902 :         if (!filp->f_op->unlocked_ioctl)
      49    12723061 :                 goto out;
      50             : 
      51  1521629841 :         error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
      52  1521523185 :         if (error == -ENOIOCTLCMD)
      53      798462 :                 error = -ENOTTY;
      54  1520724723 :  out:
      55  1534246246 :         return error;
      56             : }
      57             : EXPORT_SYMBOL(vfs_ioctl);
      58             : 
      59        3844 : static int ioctl_fibmap(struct file *filp, int __user *p)
      60             : {
      61        3844 :         struct inode *inode = file_inode(filp);
      62        3844 :         struct super_block *sb = inode->i_sb;
      63        3844 :         int error, ur_block;
      64        3844 :         sector_t block;
      65             : 
      66        3844 :         if (!capable(CAP_SYS_RAWIO))
      67             :                 return -EPERM;
      68             : 
      69        3844 :         error = get_user(ur_block, p);
      70        3844 :         if (error)
      71           0 :                 return error;
      72             : 
      73        3844 :         if (ur_block < 0)
      74             :                 return -EINVAL;
      75             : 
      76        3844 :         block = ur_block;
      77        3844 :         error = bmap(inode, &block);
      78             : 
      79        3844 :         if (block > INT_MAX) {
      80           0 :                 error = -ERANGE;
      81           0 :                 pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n",
      82             :                                     current->comm, task_pid_nr(current),
      83             :                                     sb->s_id, filp);
      84             :         }
      85             : 
      86        3844 :         if (error)
      87             :                 ur_block = 0;
      88             :         else
      89        3844 :                 ur_block = block;
      90             : 
      91        3844 :         if (put_user(ur_block, p))
      92             :                 error = -EFAULT;
      93             : 
      94             :         return error;
      95             : }
      96             : 
      97             : /**
      98             :  * fiemap_fill_next_extent - Fiemap helper function
      99             :  * @fieinfo:    Fiemap context passed into ->fiemap
     100             :  * @logical:    Extent logical start offset, in bytes
     101             :  * @phys:       Extent physical start offset, in bytes
     102             :  * @len:        Extent length, in bytes
     103             :  * @flags:      FIEMAP_EXTENT flags that describe this extent
     104             :  *
     105             :  * Called from file system ->fiemap callback. Will populate extent
     106             :  * info as passed in via arguments and copy to user memory. On
     107             :  * success, extent count on fieinfo is incremented.
     108             :  *
     109             :  * Returns 0 on success, -errno on error, 1 if this was the last
     110             :  * extent that will fit in user array.
     111             :  */
     112             : #define SET_UNKNOWN_FLAGS       (FIEMAP_EXTENT_DELALLOC)
     113             : #define SET_NO_UNMOUNTED_IO_FLAGS       (FIEMAP_EXTENT_DATA_ENCRYPTED)
     114             : #define SET_NOT_ALIGNED_FLAGS   (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
     115     1387538 : int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
     116             :                             u64 phys, u64 len, u32 flags)
     117             : {
     118     1387538 :         struct fiemap_extent extent;
     119     1387538 :         struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
     120             : 
     121             :         /* only count the extents */
     122     1387538 :         if (fieinfo->fi_extents_max == 0) {
     123      125239 :                 fieinfo->fi_extents_mapped++;
     124      125239 :                 return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
     125             :         }
     126             : 
     127     1262299 :         if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
     128             :                 return 1;
     129             : 
     130     1258496 :         if (flags & SET_UNKNOWN_FLAGS)
     131        6955 :                 flags |= FIEMAP_EXTENT_UNKNOWN;
     132     1258496 :         if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
     133           0 :                 flags |= FIEMAP_EXTENT_ENCODED;
     134     1258496 :         if (flags & SET_NOT_ALIGNED_FLAGS)
     135           0 :                 flags |= FIEMAP_EXTENT_NOT_ALIGNED;
     136             : 
     137     1258496 :         memset(&extent, 0, sizeof(extent));
     138     1258496 :         extent.fe_logical = logical;
     139     1258496 :         extent.fe_physical = phys;
     140     1258496 :         extent.fe_length = len;
     141     1258496 :         extent.fe_flags = flags;
     142             : 
     143     1258496 :         dest += fieinfo->fi_extents_mapped;
     144     1258496 :         if (copy_to_user(dest, &extent, sizeof(extent)))
     145             :                 return -EFAULT;
     146             : 
     147     1258470 :         fieinfo->fi_extents_mapped++;
     148     1258470 :         if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
     149             :                 return 1;
     150     1253252 :         return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
     151             : }
     152             : EXPORT_SYMBOL(fiemap_fill_next_extent);
     153             : 
     154             : /**
     155             :  * fiemap_prep - check validity of requested flags for fiemap
     156             :  * @inode:      Inode to operate on
     157             :  * @fieinfo:    Fiemap context passed into ->fiemap
     158             :  * @start:      Start of the mapped range
     159             :  * @len:        Length of the mapped range, can be truncated by this function.
     160             :  * @supported_flags:    Set of fiemap flags that the file system understands
     161             :  *
     162             :  * This function must be called from each ->fiemap instance to validate the
     163             :  * fiemap request against the file system parameters.
     164             :  *
     165             :  * Returns 0 on success, or a negative error on failure.
     166             :  */
     167     1072752 : int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
     168             :                 u64 start, u64 *len, u32 supported_flags)
     169             : {
     170     1072752 :         u64 maxbytes = inode->i_sb->s_maxbytes;
     171     1072752 :         u32 incompat_flags;
     172     1072752 :         int ret = 0;
     173             : 
     174     1072752 :         if (*len == 0)
     175             :                 return -EINVAL;
     176     1072748 :         if (start >= maxbytes)
     177             :                 return -EFBIG;
     178             : 
     179             :         /*
     180             :          * Shrink request scope to what the fs can actually handle.
     181             :          */
     182     1072748 :         if (*len > maxbytes || (maxbytes - *len) < start)
     183       24013 :                 *len = maxbytes - start;
     184             : 
     185     1072748 :         supported_flags |= FIEMAP_FLAG_SYNC;
     186     1072748 :         supported_flags &= FIEMAP_FLAGS_COMPAT;
     187     1072748 :         incompat_flags = fieinfo->fi_flags & ~supported_flags;
     188     1072748 :         if (incompat_flags) {
     189      511836 :                 fieinfo->fi_flags = incompat_flags;
     190      511836 :                 return -EBADR;
     191             :         }
     192             : 
     193      560912 :         if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
     194      279621 :                 ret = filemap_write_and_wait(inode->i_mapping);
     195             :         return ret;
     196             : }
     197             : EXPORT_SYMBOL(fiemap_prep);
     198             : 
     199     1072772 : static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap)
     200             : {
     201     1072772 :         struct fiemap fiemap;
     202     1072772 :         struct fiemap_extent_info fieinfo = { 0, };
     203     1072772 :         struct inode *inode = file_inode(filp);
     204     1072772 :         int error;
     205             : 
     206     1072772 :         if (!inode->i_op->fiemap)
     207             :                 return -EOPNOTSUPP;
     208             : 
     209     1072752 :         if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
     210             :                 return -EFAULT;
     211             : 
     212     1072751 :         if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
     213             :                 return -EINVAL;
     214             : 
     215     1072751 :         fieinfo.fi_flags = fiemap.fm_flags;
     216     1072751 :         fieinfo.fi_extents_max = fiemap.fm_extent_count;
     217     1072751 :         fieinfo.fi_extents_start = ufiemap->fm_extents;
     218             : 
     219     1072751 :         error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start,
     220             :                         fiemap.fm_length);
     221             : 
     222     1072751 :         fiemap.fm_flags = fieinfo.fi_flags;
     223     1072751 :         fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
     224     1072751 :         if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
     225           0 :                 error = -EFAULT;
     226             : 
     227             :         return error;
     228             : }
     229             : 
     230     4441769 : static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
     231             :                              u64 off, u64 olen, u64 destoff)
     232             : {
     233     4441769 :         struct fd src_file = fdget(srcfd);
     234     4441763 :         loff_t cloned;
     235     4441763 :         int ret;
     236             : 
     237     4441763 :         if (!src_file.file)
     238             :                 return -EBADF;
     239     4441763 :         cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
     240             :                                       olen, 0);
     241     4441744 :         if (cloned < 0)
     242     1118988 :                 ret = cloned;
     243     3322756 :         else if (olen && cloned != olen)
     244             :                 ret = -EINVAL;
     245             :         else
     246     3322703 :                 ret = 0;
     247     4441744 :         fdput(src_file);
     248     4441744 :         return ret;
     249             : }
     250             : 
     251     4420429 : static long ioctl_file_clone_range(struct file *file,
     252             :                                    struct file_clone_range __user *argp)
     253             : {
     254     4420429 :         struct file_clone_range args;
     255             : 
     256     4420429 :         if (copy_from_user(&args, argp, sizeof(args)))
     257             :                 return -EFAULT;
     258     4420429 :         return ioctl_file_clone(file, args.src_fd, args.src_offset,
     259             :                                 args.src_length, args.dest_offset);
     260             : }
     261             : 
     262             : /*
     263             :  * This provides compatibility with legacy XFS pre-allocation ioctls
     264             :  * which predate the fallocate syscall.
     265             :  *
     266             :  * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
     267             :  * are used here, rest are ignored.
     268             :  */
     269     2177256 : static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
     270             : {
     271     2177256 :         struct inode *inode = file_inode(filp);
     272     2177256 :         struct space_resv sr;
     273             : 
     274     2177256 :         if (copy_from_user(&sr, argp, sizeof(sr)))
     275             :                 return -EFAULT;
     276             : 
     277     2177249 :         switch (sr.l_whence) {
     278             :         case SEEK_SET:
     279             :                 break;
     280        7326 :         case SEEK_CUR:
     281        7326 :                 sr.l_start += filp->f_pos;
     282        7326 :                 break;
     283             :         case SEEK_END:
     284           0 :                 sr.l_start += i_size_read(inode);
     285           0 :                 break;
     286             :         default:
     287             :                 return -EINVAL;
     288             :         }
     289             : 
     290     2177249 :         return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
     291             :                         sr.l_len);
     292             : }
     293             : 
     294             : /* on ia32 l_start is on a 32-bit boundary */
     295             : #if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
     296             : /* just account for different alignment */
     297             : static int compat_ioctl_preallocate(struct file *file, int mode,
     298             :                                     struct space_resv_32 __user *argp)
     299             : {
     300             :         struct inode *inode = file_inode(file);
     301             :         struct space_resv_32 sr;
     302             : 
     303             :         if (copy_from_user(&sr, argp, sizeof(sr)))
     304             :                 return -EFAULT;
     305             : 
     306             :         switch (sr.l_whence) {
     307             :         case SEEK_SET:
     308             :                 break;
     309             :         case SEEK_CUR:
     310             :                 sr.l_start += file->f_pos;
     311             :                 break;
     312             :         case SEEK_END:
     313             :                 sr.l_start += i_size_read(inode);
     314             :                 break;
     315             :         default:
     316             :                 return -EINVAL;
     317             :         }
     318             : 
     319             :         return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
     320             : }
     321             : #endif
     322             : 
     323   175544383 : static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
     324             : {
     325   175544383 :         switch (cmd) {
     326        3844 :         case FIBMAP:
     327        3844 :                 return ioctl_fibmap(filp, p);
     328     1124453 :         case FS_IOC_RESVSP:
     329             :         case FS_IOC_RESVSP64:
     330     1124453 :                 return ioctl_preallocate(filp, 0, p);
     331     1052753 :         case FS_IOC_UNRESVSP:
     332             :         case FS_IOC_UNRESVSP64:
     333     1052753 :                 return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
     334          56 :         case FS_IOC_ZERO_RANGE:
     335          56 :                 return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
     336             :         }
     337             : 
     338             :         return -ENOIOCTLCMD;
     339             : }
     340             : 
     341        1125 : static int ioctl_fionbio(struct file *filp, int __user *argp)
     342             : {
     343        1125 :         unsigned int flag;
     344        1125 :         int on, error;
     345             : 
     346        1125 :         error = get_user(on, argp);
     347        1125 :         if (error)
     348           0 :                 return error;
     349        1125 :         flag = O_NONBLOCK;
     350             : #ifdef __sparc__
     351             :         /* SunOS compatibility item. */
     352             :         if (O_NONBLOCK != O_NDELAY)
     353             :                 flag |= O_NDELAY;
     354             : #endif
     355        1125 :         spin_lock(&filp->f_lock);
     356        1125 :         if (on)
     357        1125 :                 filp->f_flags |= flag;
     358             :         else
     359           0 :                 filp->f_flags &= ~flag;
     360        1125 :         spin_unlock(&filp->f_lock);
     361        1125 :         return error;
     362             : }
     363             : 
     364           0 : static int ioctl_fioasync(unsigned int fd, struct file *filp,
     365             :                           int __user *argp)
     366             : {
     367           0 :         unsigned int flag;
     368           0 :         int on, error;
     369             : 
     370           0 :         error = get_user(on, argp);
     371           0 :         if (error)
     372           0 :                 return error;
     373           0 :         flag = on ? FASYNC : 0;
     374             : 
     375             :         /* Did FASYNC state change ? */
     376           0 :         if ((flag ^ filp->f_flags) & FASYNC) {
     377           0 :                 if (filp->f_op->fasync)
     378             :                         /* fasync() adjusts filp->f_flags */
     379           0 :                         error = filp->f_op->fasync(fd, filp, on);
     380             :                 else
     381             :                         error = -ENOTTY;
     382             :         }
     383           0 :         return error < 0 ? error : 0;
     384             : }
     385             : 
     386       14103 : static int ioctl_fsfreeze(struct file *filp)
     387             : {
     388       14103 :         struct super_block *sb = file_inode(filp)->i_sb;
     389             : 
     390       14103 :         if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
     391             :                 return -EPERM;
     392             : 
     393             :         /* If filesystem doesn't support freeze feature, return. */
     394       14103 :         if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL)
     395             :                 return -EOPNOTSUPP;
     396             : 
     397             :         /* Freeze */
     398       14103 :         if (sb->s_op->freeze_super)
     399           0 :                 return sb->s_op->freeze_super(sb, FREEZE_HOLDER_USERSPACE);
     400       14103 :         return freeze_super(sb, FREEZE_HOLDER_USERSPACE);
     401             : }
     402             : 
     403       14125 : static int ioctl_fsthaw(struct file *filp)
     404             : {
     405       14125 :         struct super_block *sb = file_inode(filp)->i_sb;
     406             : 
     407       14125 :         if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
     408             :                 return -EPERM;
     409             : 
     410             :         /* Thaw */
     411       14132 :         if (sb->s_op->thaw_super)
     412           0 :                 return sb->s_op->thaw_super(sb, FREEZE_HOLDER_USERSPACE);
     413       14132 :         return thaw_super(sb, FREEZE_HOLDER_USERSPACE);
     414             : }
     415             : 
     416     4261426 : static int ioctl_file_dedupe_range(struct file *file,
     417             :                                    struct file_dedupe_range __user *argp)
     418             : {
     419     4261426 :         struct file_dedupe_range *same = NULL;
     420     4261426 :         int ret;
     421     4261426 :         unsigned long size;
     422     4261426 :         u16 count;
     423             : 
     424     4261426 :         if (get_user(count, &argp->dest_count)) {
     425           0 :                 ret = -EFAULT;
     426           0 :                 goto out;
     427             :         }
     428             : 
     429     4261423 :         size = offsetof(struct file_dedupe_range, info[count]);
     430     4261423 :         if (size > PAGE_SIZE) {
     431           0 :                 ret = -ENOMEM;
     432           0 :                 goto out;
     433             :         }
     434             : 
     435     4261423 :         same = memdup_user(argp, size);
     436     4261409 :         if (IS_ERR(same)) {
     437           0 :                 ret = PTR_ERR(same);
     438           0 :                 same = NULL;
     439           0 :                 goto out;
     440             :         }
     441             : 
     442     4261409 :         same->dest_count = count;
     443     4261409 :         ret = vfs_dedupe_file_range(file, same);
     444     4261418 :         if (ret)
     445          96 :                 goto out;
     446             : 
     447     4261322 :         ret = copy_to_user(argp, same, size);
     448     4261332 :         if (ret)
     449           0 :                 ret = -EFAULT;
     450             : 
     451     4261332 : out:
     452     4261428 :         kfree(same);
     453     4261418 :         return ret;
     454             : }
     455             : 
     456             : /**
     457             :  * fileattr_fill_xflags - initialize fileattr with xflags
     458             :  * @fa:         fileattr pointer
     459             :  * @xflags:     FS_XFLAG_* flags
     460             :  *
     461             :  * Set ->fsx_xflags, ->fsx_valid and ->flags (translated xflags).  All
     462             :  * other fields are zeroed.
     463             :  */
     464     2818309 : void fileattr_fill_xflags(struct fileattr *fa, u32 xflags)
     465             : {
     466     2818309 :         memset(fa, 0, sizeof(*fa));
     467     2818309 :         fa->fsx_valid = true;
     468     2818309 :         fa->fsx_xflags = xflags;
     469     2818309 :         if (fa->fsx_xflags & FS_XFLAG_IMMUTABLE)
     470         150 :                 fa->flags |= FS_IMMUTABLE_FL;
     471     2818309 :         if (fa->fsx_xflags & FS_XFLAG_APPEND)
     472         122 :                 fa->flags |= FS_APPEND_FL;
     473     2818309 :         if (fa->fsx_xflags & FS_XFLAG_SYNC)
     474          36 :                 fa->flags |= FS_SYNC_FL;
     475     2818309 :         if (fa->fsx_xflags & FS_XFLAG_NOATIME)
     476          28 :                 fa->flags |= FS_NOATIME_FL;
     477     2818309 :         if (fa->fsx_xflags & FS_XFLAG_NODUMP)
     478          24 :                 fa->flags |= FS_NODUMP_FL;
     479     2818309 :         if (fa->fsx_xflags & FS_XFLAG_DAX)
     480          54 :                 fa->flags |= FS_DAX_FL;
     481     2818309 :         if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT)
     482        1138 :                 fa->flags |= FS_PROJINHERIT_FL;
     483     2818309 : }
     484             : EXPORT_SYMBOL(fileattr_fill_xflags);
     485             : 
     486             : /**
     487             :  * fileattr_fill_flags - initialize fileattr with flags
     488             :  * @fa:         fileattr pointer
     489             :  * @flags:      FS_*_FL flags
     490             :  *
     491             :  * Set ->flags, ->flags_valid and ->fsx_xflags (translated flags).
     492             :  * All other fields are zeroed.
     493             :  */
     494       83120 : void fileattr_fill_flags(struct fileattr *fa, u32 flags)
     495             : {
     496       83120 :         memset(fa, 0, sizeof(*fa));
     497       83120 :         fa->flags_valid = true;
     498       83120 :         fa->flags = flags;
     499       83120 :         if (fa->flags & FS_SYNC_FL)
     500        6442 :                 fa->fsx_xflags |= FS_XFLAG_SYNC;
     501       83120 :         if (fa->flags & FS_IMMUTABLE_FL)
     502        6505 :                 fa->fsx_xflags |= FS_XFLAG_IMMUTABLE;
     503       83120 :         if (fa->flags & FS_APPEND_FL)
     504        6554 :                 fa->fsx_xflags |= FS_XFLAG_APPEND;
     505       83120 :         if (fa->flags & FS_NODUMP_FL)
     506        6413 :                 fa->fsx_xflags |= FS_XFLAG_NODUMP;
     507       83120 :         if (fa->flags & FS_NOATIME_FL)
     508        6475 :                 fa->fsx_xflags |= FS_XFLAG_NOATIME;
     509       83120 :         if (fa->flags & FS_DAX_FL)
     510        6395 :                 fa->fsx_xflags |= FS_XFLAG_DAX;
     511       83120 :         if (fa->flags & FS_PROJINHERIT_FL)
     512        6450 :                 fa->fsx_xflags |= FS_XFLAG_PROJINHERIT;
     513       83120 : }
     514             : EXPORT_SYMBOL(fileattr_fill_flags);
     515             : 
     516             : /**
     517             :  * vfs_fileattr_get - retrieve miscellaneous file attributes
     518             :  * @dentry:     the object to retrieve from
     519             :  * @fa:         fileattr pointer
     520             :  *
     521             :  * Call i_op->fileattr_get() callback, if exists.
     522             :  *
     523             :  * Return: 0 on success, or a negative error on failure.
     524             :  */
     525     2330743 : int vfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
     526             : {
     527     2330743 :         struct inode *inode = d_inode(dentry);
     528             : 
     529     2330743 :         if (!inode->i_op->fileattr_get)
     530             :                 return -ENOIOCTLCMD;
     531             : 
     532     2330741 :         return inode->i_op->fileattr_get(dentry, fa);
     533             : }
     534             : EXPORT_SYMBOL(vfs_fileattr_get);
     535             : 
     536             : /**
     537             :  * copy_fsxattr_to_user - copy fsxattr to userspace.
     538             :  * @fa:         fileattr pointer
     539             :  * @ufa:        fsxattr user pointer
     540             :  *
     541             :  * Return: 0 on success, or -EFAULT on failure.
     542             :  */
     543     1240139 : int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
     544             : {
     545     1240139 :         struct fsxattr xfa;
     546             : 
     547     1240139 :         memset(&xfa, 0, sizeof(xfa));
     548     1240139 :         xfa.fsx_xflags = fa->fsx_xflags;
     549     1240139 :         xfa.fsx_extsize = fa->fsx_extsize;
     550     1240139 :         xfa.fsx_nextents = fa->fsx_nextents;
     551     1240139 :         xfa.fsx_projid = fa->fsx_projid;
     552     1240139 :         xfa.fsx_cowextsize = fa->fsx_cowextsize;
     553             : 
     554     1240139 :         if (copy_to_user(ufa, &xfa, sizeof(xfa)))
     555           0 :                 return -EFAULT;
     556             : 
     557             :         return 0;
     558             : }
     559             : EXPORT_SYMBOL(copy_fsxattr_to_user);
     560             : 
     561      483126 : static int copy_fsxattr_from_user(struct fileattr *fa,
     562             :                                   struct fsxattr __user *ufa)
     563             : {
     564      483126 :         struct fsxattr xfa;
     565             : 
     566      483126 :         if (copy_from_user(&xfa, ufa, sizeof(xfa)))
     567             :                 return -EFAULT;
     568             : 
     569      483126 :         fileattr_fill_xflags(fa, xfa.fsx_xflags);
     570      483125 :         fa->fsx_extsize = xfa.fsx_extsize;
     571      483125 :         fa->fsx_nextents = xfa.fsx_nextents;
     572      483125 :         fa->fsx_projid = xfa.fsx_projid;
     573      483125 :         fa->fsx_cowextsize = xfa.fsx_cowextsize;
     574             : 
     575      483125 :         return 0;
     576             : }
     577             : 
     578             : /*
     579             :  * Generic function to check FS_IOC_FSSETXATTR/FS_IOC_SETFLAGS values and reject
     580             :  * any invalid configurations.
     581             :  *
     582             :  * Note: must be called with inode lock held.
     583             :  */
     584      564367 : static int fileattr_set_prepare(struct inode *inode,
     585             :                               const struct fileattr *old_ma,
     586             :                               struct fileattr *fa)
     587             : {
     588      564367 :         int err;
     589             : 
     590             :         /*
     591             :          * The IMMUTABLE and APPEND_ONLY flags can only be changed by
     592             :          * the relevant capability.
     593             :          */
     594      573592 :         if ((fa->flags ^ old_ma->flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) &&
     595        9225 :             !capable(CAP_LINUX_IMMUTABLE))
     596             :                 return -EPERM;
     597             : 
     598      563847 :         err = fscrypt_prepare_setflags(inode, old_ma->flags, fa->flags);
     599      563847 :         if (err)
     600             :                 return err;
     601             : 
     602             :         /*
     603             :          * Project Quota ID state is only allowed to change from within the init
     604             :          * namespace. Enforce that restriction only if we are trying to change
     605             :          * the quota ID state. Everything else is allowed in user namespaces.
     606             :          */
     607      563847 :         if (current_user_ns() != &init_user_ns) {
     608           0 :                 if (old_ma->fsx_projid != fa->fsx_projid)
     609             :                         return -EINVAL;
     610           0 :                 if ((old_ma->fsx_xflags ^ fa->fsx_xflags) &
     611             :                                 FS_XFLAG_PROJINHERIT)
     612             :                         return -EINVAL;
     613             :         } else {
     614             :                 /*
     615             :                  * Caller is allowed to change the project ID. If it is being
     616             :                  * changed, make sure that the new value is valid.
     617             :                  */
     618      985032 :                 if (old_ma->fsx_projid != fa->fsx_projid &&
     619      421185 :                     !projid_valid(make_kprojid(&init_user_ns, fa->fsx_projid)))
     620             :                         return -EINVAL;
     621             :         }
     622             : 
     623             :         /* Check extent size hints. */
     624      563847 :         if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode))
     625             :                 return -EINVAL;
     626             : 
     627      563847 :         if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
     628          16 :                         !S_ISDIR(inode->i_mode))
     629             :                 return -EINVAL;
     630             : 
     631      563847 :         if ((fa->fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
     632         142 :             !S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
     633             :                 return -EINVAL;
     634             : 
     635             :         /*
     636             :          * It is only valid to set the DAX flag on regular files and
     637             :          * directories on filesystems.
     638             :          */
     639      563847 :         if ((fa->fsx_xflags & FS_XFLAG_DAX) &&
     640        5731 :             !(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
     641             :                 return -EINVAL;
     642             : 
     643             :         /* Extent size hints of zero turn off the flags. */
     644      563847 :         if (fa->fsx_extsize == 0)
     645      563813 :                 fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
     646      563847 :         if (fa->fsx_cowextsize == 0)
     647      563713 :                 fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
     648             : 
     649             :         return 0;
     650             : }
     651             : 
     652             : /**
     653             :  * vfs_fileattr_set - change miscellaneous file attributes
     654             :  * @idmap:      idmap of the mount
     655             :  * @dentry:     the object to change
     656             :  * @fa:         fileattr pointer
     657             :  *
     658             :  * After verifying permissions, call i_op->fileattr_set() callback, if
     659             :  * exists.
     660             :  *
     661             :  * Verifying attributes involves retrieving current attributes with
     662             :  * i_op->fileattr_get(), this also allows initializing attributes that have
     663             :  * not been set by the caller to current values.  Inode lock is held
     664             :  * thoughout to prevent racing with another instance.
     665             :  *
     666             :  * Return: 0 on success, or a negative error on failure.
     667             :  */
     668      566124 : int vfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
     669             :                      struct fileattr *fa)
     670             : {
     671      566124 :         struct inode *inode = d_inode(dentry);
     672      566124 :         struct fileattr old_ma = {};
     673      566124 :         int err;
     674             : 
     675      566124 :         if (!inode->i_op->fileattr_set)
     676             :                 return -ENOIOCTLCMD;
     677             : 
     678      566124 :         if (!inode_owner_or_capable(idmap, inode))
     679             :                 return -EPERM;
     680             : 
     681      564370 :         inode_lock(inode);
     682      564369 :         err = vfs_fileattr_get(dentry, &old_ma);
     683      564369 :         if (!err) {
     684             :                 /* initialize missing bits from old_ma */
     685      564369 :                 if (fa->flags_valid) {
     686       82134 :                         fa->fsx_xflags |= old_ma.fsx_xflags & ~FS_XFLAG_COMMON;
     687       82134 :                         fa->fsx_extsize = old_ma.fsx_extsize;
     688       82134 :                         fa->fsx_nextents = old_ma.fsx_nextents;
     689       82134 :                         fa->fsx_projid = old_ma.fsx_projid;
     690       82134 :                         fa->fsx_cowextsize = old_ma.fsx_cowextsize;
     691             :                 } else {
     692      482235 :                         fa->flags |= old_ma.flags & ~FS_COMMON_FL;
     693             :                 }
     694      564369 :                 err = fileattr_set_prepare(inode, &old_ma, fa);
     695      564366 :                 if (!err)
     696      563848 :                         err = inode->i_op->fileattr_set(idmap, dentry, fa);
     697             :         }
     698      564369 :         inode_unlock(inode);
     699             : 
     700      564369 :         return err;
     701             : }
     702             : EXPORT_SYMBOL(vfs_fileattr_set);
     703             : 
     704      530883 : static int ioctl_getflags(struct file *file, unsigned int __user *argp)
     705             : {
     706      530883 :         struct fileattr fa = { .flags_valid = true }; /* hint only */
     707      530883 :         int err;
     708             : 
     709      530883 :         err = vfs_fileattr_get(file->f_path.dentry, &fa);
     710      530883 :         if (!err)
     711      530883 :                 err = put_user(fa.flags, argp);
     712      530883 :         return err;
     713             : }
     714             : 
     715       82996 : static int ioctl_setflags(struct file *file, unsigned int __user *argp)
     716             : {
     717       82996 :         struct mnt_idmap *idmap = file_mnt_idmap(file);
     718       82996 :         struct dentry *dentry = file->f_path.dentry;
     719       82996 :         struct fileattr fa;
     720       82996 :         unsigned int flags;
     721       82996 :         int err;
     722             : 
     723       82996 :         err = get_user(flags, argp);
     724       82996 :         if (!err) {
     725       82996 :                 err = mnt_want_write_file(file);
     726       82996 :                 if (!err) {
     727       82996 :                         fileattr_fill_flags(&fa, flags);
     728       82996 :                         err = vfs_fileattr_set(idmap, dentry, &fa);
     729       82996 :                         mnt_drop_write_file(file);
     730             :                 }
     731             :         }
     732       82996 :         return err;
     733             : }
     734             : 
     735     1235500 : static int ioctl_fsgetxattr(struct file *file, void __user *argp)
     736             : {
     737     1235500 :         struct fileattr fa = { .fsx_valid = true }; /* hint only */
     738     1235500 :         int err;
     739             : 
     740     1235500 :         err = vfs_fileattr_get(file->f_path.dentry, &fa);
     741     1235396 :         if (!err)
     742     1235301 :                 err = copy_fsxattr_to_user(&fa, argp);
     743             : 
     744     1235307 :         return err;
     745             : }
     746             : 
     747      483124 : static int ioctl_fssetxattr(struct file *file, void __user *argp)
     748             : {
     749      483124 :         struct mnt_idmap *idmap = file_mnt_idmap(file);
     750      483125 :         struct dentry *dentry = file->f_path.dentry;
     751      483125 :         struct fileattr fa;
     752      483125 :         int err;
     753             : 
     754      483125 :         err = copy_fsxattr_from_user(&fa, argp);
     755      483124 :         if (!err) {
     756      483124 :                 err = mnt_want_write_file(file);
     757      483125 :                 if (!err) {
     758      483124 :                         err = vfs_fileattr_set(idmap, dentry, &fa);
     759      483129 :                         mnt_drop_write_file(file);
     760             :                 }
     761             :         }
     762      483129 :         return err;
     763             : }
     764             : 
     765             : /*
     766             :  * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
     767             :  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
     768             :  *
     769             :  * When you add any new common ioctls to the switches above and below,
     770             :  * please ensure they have compatible arguments in compat mode.
     771             :  */
     772  1548930400 : static int do_vfs_ioctl(struct file *filp, unsigned int fd,
     773             :                         unsigned int cmd, unsigned long arg)
     774             : {
     775  1548930400 :         void __user *argp = (void __user *)arg;
     776  1548930400 :         struct inode *inode = file_inode(filp);
     777             : 
     778  1548930400 :         switch (cmd) {
     779          22 :         case FIOCLEX:
     780          22 :                 set_close_on_exec(fd, 1);
     781          22 :                 return 0;
     782             : 
     783           0 :         case FIONCLEX:
     784           0 :                 set_close_on_exec(fd, 0);
     785           0 :                 return 0;
     786             : 
     787        1125 :         case FIONBIO:
     788        1125 :                 return ioctl_fionbio(filp, argp);
     789             : 
     790           0 :         case FIOASYNC:
     791           0 :                 return ioctl_fioasync(fd, filp, argp);
     792             : 
     793           0 :         case FIOQSIZE:
     794           0 :                 if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
     795             :                     S_ISLNK(inode->i_mode)) {
     796           0 :                         loff_t res = inode_get_bytes(inode);
     797           0 :                         return copy_to_user(argp, &res, sizeof(res)) ?
     798           0 :                                             -EFAULT : 0;
     799             :                 }
     800             : 
     801             :                 return -ENOTTY;
     802             : 
     803       14102 :         case FIFREEZE:
     804       14102 :                 return ioctl_fsfreeze(filp);
     805             : 
     806       14126 :         case FITHAW:
     807       14126 :                 return ioctl_fsthaw(filp);
     808             : 
     809     1072773 :         case FS_IOC_FIEMAP:
     810     1072773 :                 return ioctl_fiemap(filp, argp);
     811             : 
     812         239 :         case FIGETBSZ:
     813             :                 /* anon_bdev filesystems may not have a block size */
     814         239 :                 if (!inode->i_sb->s_blocksize)
     815             :                         return -EINVAL;
     816             : 
     817         239 :                 return put_user(inode->i_sb->s_blocksize, (int __user *)argp);
     818             : 
     819       21331 :         case FICLONE:
     820       21331 :                 return ioctl_file_clone(filp, arg, 0, 0, 0);
     821             : 
     822     4420427 :         case FICLONERANGE:
     823     4420427 :                 return ioctl_file_clone_range(filp, argp);
     824             : 
     825     4261416 :         case FIDEDUPERANGE:
     826     4261416 :                 return ioctl_file_dedupe_range(filp, argp);
     827             : 
     828      414992 :         case FIONREAD:
     829      414992 :                 if (!S_ISREG(inode->i_mode))
     830      414992 :                         return vfs_ioctl(filp, cmd, arg);
     831             : 
     832           0 :                 return put_user(i_size_read(inode) - filp->f_pos,
     833             :                                 (int __user *)argp);
     834             : 
     835      530883 :         case FS_IOC_GETFLAGS:
     836      530883 :                 return ioctl_getflags(filp, argp);
     837             : 
     838       82996 :         case FS_IOC_SETFLAGS:
     839       82996 :                 return ioctl_setflags(filp, argp);
     840             : 
     841     1235500 :         case FS_IOC_FSGETXATTR:
     842     1235500 :                 return ioctl_fsgetxattr(filp, argp);
     843             : 
     844      483124 :         case FS_IOC_FSSETXATTR:
     845      483124 :                 return ioctl_fssetxattr(filp, argp);
     846             : 
     847  1536377344 :         default:
     848  1536377344 :                 if (S_ISREG(inode->i_mode))
     849   175548703 :                         return file_ioctl(filp, cmd, argp);
     850             :                 break;
     851             :         }
     852             : 
     853             :         return -ENOIOCTLCMD;
     854             : }
     855             : 
     856  3098722498 : SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
     857             : {
     858  1549385968 :         struct fd f = fdget(fd);
     859  1549889255 :         int error;
     860             : 
     861  1549889255 :         if (!f.file)
     862             :                 return -EBADF;
     863             : 
     864  1548608278 :         error = security_file_ioctl(f.file, cmd, arg);
     865  1548608278 :         if (error)
     866             :                 goto out;
     867             : 
     868  1548608278 :         error = do_vfs_ioctl(f.file, fd, cmd, arg);
     869  1548672400 :         if (error == -ENOIOCTLCMD)
     870  1533938524 :                 error = vfs_ioctl(f.file, cmd, arg);
     871             : 
     872    14733876 : out:
     873  1548572623 :         fdput(f);
     874  1548641655 :         return error;
     875             : }
     876             : 
     877             : #ifdef CONFIG_COMPAT
     878             : /**
     879             :  * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation
     880             :  *
     881             :  * This is not normally called as a function, but instead set in struct
     882             :  * file_operations as
     883             :  *
     884             :  *     .compat_ioctl = compat_ptr_ioctl,
     885             :  *
     886             :  * On most architectures, the compat_ptr_ioctl() just passes all arguments
     887             :  * to the corresponding ->ioctl handler. The exception is arch/s390, where
     888             :  * compat_ptr() clears the top bit of a 32-bit pointer value, so user space
     889             :  * pointers to the second 2GB alias the first 2GB, as is the case for
     890             :  * native 32-bit s390 user space.
     891             :  *
     892             :  * The compat_ptr_ioctl() function must therefore be used only with ioctl
     893             :  * functions that either ignore the argument or pass a pointer to a
     894             :  * compatible data type.
     895             :  *
     896             :  * If any ioctl command handled by fops->unlocked_ioctl passes a plain
     897             :  * integer instead of a pointer, or any of the passed data types
     898             :  * is incompatible between 32-bit and 64-bit architectures, a proper
     899             :  * handler is required instead of compat_ptr_ioctl.
     900             :  */
     901             : long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
     902             : {
     903             :         if (!file->f_op->unlocked_ioctl)
     904             :                 return -ENOIOCTLCMD;
     905             : 
     906             :         return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
     907             : }
     908             : EXPORT_SYMBOL(compat_ptr_ioctl);
     909             : 
     910             : COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
     911             :                        compat_ulong_t, arg)
     912             : {
     913             :         struct fd f = fdget(fd);
     914             :         int error;
     915             : 
     916             :         if (!f.file)
     917             :                 return -EBADF;
     918             : 
     919             :         /* RED-PEN how should LSM module know it's handling 32bit? */
     920             :         error = security_file_ioctl(f.file, cmd, arg);
     921             :         if (error)
     922             :                 goto out;
     923             : 
     924             :         switch (cmd) {
     925             :         /* FICLONE takes an int argument, so don't use compat_ptr() */
     926             :         case FICLONE:
     927             :                 error = ioctl_file_clone(f.file, arg, 0, 0, 0);
     928             :                 break;
     929             : 
     930             : #if defined(CONFIG_X86_64)
     931             :         /* these get messy on amd64 due to alignment differences */
     932             :         case FS_IOC_RESVSP_32:
     933             :         case FS_IOC_RESVSP64_32:
     934             :                 error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
     935             :                 break;
     936             :         case FS_IOC_UNRESVSP_32:
     937             :         case FS_IOC_UNRESVSP64_32:
     938             :                 error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
     939             :                                 compat_ptr(arg));
     940             :                 break;
     941             :         case FS_IOC_ZERO_RANGE_32:
     942             :                 error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
     943             :                                 compat_ptr(arg));
     944             :                 break;
     945             : #endif
     946             : 
     947             :         /*
     948             :          * These access 32-bit values anyway so no further handling is
     949             :          * necessary.
     950             :          */
     951             :         case FS_IOC32_GETFLAGS:
     952             :         case FS_IOC32_SETFLAGS:
     953             :                 cmd = (cmd == FS_IOC32_GETFLAGS) ?
     954             :                         FS_IOC_GETFLAGS : FS_IOC_SETFLAGS;
     955             :                 fallthrough;
     956             :         /*
     957             :          * everything else in do_vfs_ioctl() takes either a compatible
     958             :          * pointer argument or no argument -- call it with a modified
     959             :          * argument.
     960             :          */
     961             :         default:
     962             :                 error = do_vfs_ioctl(f.file, fd, cmd,
     963             :                                      (unsigned long)compat_ptr(arg));
     964             :                 if (error != -ENOIOCTLCMD)
     965             :                         break;
     966             : 
     967             :                 if (f.file->f_op->compat_ioctl)
     968             :                         error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
     969             :                 if (error == -ENOIOCTLCMD)
     970             :                         error = -ENOTTY;
     971             :                 break;
     972             :         }
     973             : 
     974             :  out:
     975             :         fdput(f);
     976             : 
     977             :         return error;
     978             : }
     979             : #endif

Generated by: LCOV version 1.14