LCOV - code coverage report
Current view: top level - fs - ioctl.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 349 429 81.4 %
Date: 2023-07-31 20:08:22 Functions: 27 33 81.8 %

          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  2859019774 : long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
      45             : {
      46  2859019774 :         int error = -ENOTTY;
      47             : 
      48  2859019774 :         if (!filp->f_op->unlocked_ioctl)
      49    24662120 :                 goto out;
      50             : 
      51  2834357654 :         error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
      52  2832954793 :         if (error == -ENOIOCTLCMD)
      53     3056386 :                 error = -ENOTTY;
      54  2829898407 :  out:
      55  2857616913 :         return error;
      56             : }
      57             : EXPORT_SYMBOL(vfs_ioctl);
      58             : 
      59       30746 : static int ioctl_fibmap(struct file *filp, int __user *p)
      60             : {
      61       30746 :         struct inode *inode = file_inode(filp);
      62       30746 :         struct super_block *sb = inode->i_sb;
      63       30746 :         int error, ur_block;
      64       30746 :         sector_t block;
      65             : 
      66       30746 :         if (!capable(CAP_SYS_RAWIO))
      67             :                 return -EPERM;
      68             : 
      69       30746 :         error = get_user(ur_block, p);
      70       30746 :         if (error)
      71             :                 return error;
      72             : 
      73       30746 :         if (ur_block < 0)
      74             :                 return -EINVAL;
      75             : 
      76       30746 :         block = ur_block;
      77       30746 :         error = bmap(inode, &block);
      78             : 
      79       30746 :         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       30746 :         if (error)
      87             :                 ur_block = 0;
      88             :         else
      89       30744 :                 ur_block = block;
      90             : 
      91       30746 :         if (put_user(ur_block, p))
      92           0 :                 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     6087103 : int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
     116             :                             u64 phys, u64 len, u32 flags)
     117             : {
     118     6087103 :         struct fiemap_extent extent;
     119     6087103 :         struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
     120             : 
     121             :         /* only count the extents */
     122     6087103 :         if (fieinfo->fi_extents_max == 0) {
     123     1069916 :                 fieinfo->fi_extents_mapped++;
     124     1069916 :                 return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
     125             :         }
     126             : 
     127     5017187 :         if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
     128             :                 return 1;
     129             : 
     130     5005027 :         if (flags & SET_UNKNOWN_FLAGS)
     131       27475 :                 flags |= FIEMAP_EXTENT_UNKNOWN;
     132     5005027 :         if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
     133           0 :                 flags |= FIEMAP_EXTENT_ENCODED;
     134     5005027 :         if (flags & SET_NOT_ALIGNED_FLAGS)
     135           5 :                 flags |= FIEMAP_EXTENT_NOT_ALIGNED;
     136             : 
     137     5005027 :         memset(&extent, 0, sizeof(extent));
     138     5005027 :         extent.fe_logical = logical;
     139     5005027 :         extent.fe_physical = phys;
     140     5005027 :         extent.fe_length = len;
     141     5005027 :         extent.fe_flags = flags;
     142             : 
     143     5005027 :         dest += fieinfo->fi_extents_mapped;
     144     5005027 :         if (copy_to_user(dest, &extent, sizeof(extent)))
     145             :                 return -EFAULT;
     146             : 
     147     5005897 :         fieinfo->fi_extents_mapped++;
     148     5005897 :         if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
     149             :                 return 1;
     150     4962908 :         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     1647031 : int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
     168             :                 u64 start, u64 *len, u32 supported_flags)
     169             : {
     170     1647031 :         u64 maxbytes = inode->i_sb->s_maxbytes;
     171     1647031 :         u32 incompat_flags;
     172     1647031 :         int ret = 0;
     173             : 
     174     1647031 :         if (*len == 0)
     175             :                 return -EINVAL;
     176     1647022 :         if (start >= maxbytes)
     177             :                 return -EFBIG;
     178             : 
     179             :         /*
     180             :          * Shrink request scope to what the fs can actually handle.
     181             :          */
     182     1647022 :         if (*len > maxbytes || (maxbytes - *len) < start)
     183      190162 :                 *len = maxbytes - start;
     184             : 
     185     1647022 :         supported_flags |= FIEMAP_FLAG_SYNC;
     186     1647022 :         supported_flags &= FIEMAP_FLAGS_COMPAT;
     187     1647022 :         incompat_flags = fieinfo->fi_flags & ~supported_flags;
     188     1647022 :         if (incompat_flags) {
     189      635405 :                 fieinfo->fi_flags = incompat_flags;
     190      635405 :                 return -EBADR;
     191             :         }
     192             : 
     193     1011617 :         if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
     194      488330 :                 ret = filemap_write_and_wait(inode->i_mapping);
     195             :         return ret;
     196             : }
     197             : EXPORT_SYMBOL(fiemap_prep);
     198             : 
     199     1649993 : static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap)
     200             : {
     201     1649993 :         struct fiemap fiemap;
     202     1649993 :         struct fiemap_extent_info fieinfo = { 0, };
     203     1649993 :         struct inode *inode = file_inode(filp);
     204     1649993 :         int error;
     205             : 
     206     1649993 :         if (!inode->i_op->fiemap)
     207             :                 return -EOPNOTSUPP;
     208             : 
     209     1647060 :         if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
     210             :                 return -EFAULT;
     211             : 
     212     1647064 :         if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
     213             :                 return -EINVAL;
     214             : 
     215     1647064 :         fieinfo.fi_flags = fiemap.fm_flags;
     216     1647064 :         fieinfo.fi_extents_max = fiemap.fm_extent_count;
     217     1647064 :         fieinfo.fi_extents_start = ufiemap->fm_extents;
     218             : 
     219     1647064 :         error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start,
     220             :                         fiemap.fm_length);
     221             : 
     222     1647060 :         fiemap.fm_flags = fieinfo.fi_flags;
     223     1647060 :         fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
     224     1647060 :         if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
     225           0 :                 error = -EFAULT;
     226             : 
     227             :         return error;
     228             : }
     229             : 
     230     6967892 : static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
     231             :                              u64 off, u64 olen, u64 destoff)
     232             : {
     233     6967892 :         struct fd src_file = fdget(srcfd);
     234     6967768 :         loff_t cloned;
     235     6967768 :         int ret;
     236             : 
     237     6967768 :         if (!src_file.file)
     238             :                 return -EBADF;
     239     6967768 :         cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
     240             :                                       olen, 0);
     241     6967878 :         if (cloned < 0)
     242     1830278 :                 ret = cloned;
     243     5137600 :         else if (olen && cloned != olen)
     244             :                 ret = -EINVAL;
     245             :         else
     246     5136826 :                 ret = 0;
     247     6967878 :         fdput(src_file);
     248     6967878 :         return ret;
     249             : }
     250             : 
     251     6915511 : static long ioctl_file_clone_range(struct file *file,
     252             :                                    struct file_clone_range __user *argp)
     253             : {
     254     6915511 :         struct file_clone_range args;
     255             : 
     256     6915511 :         if (copy_from_user(&args, argp, sizeof(args)))
     257             :                 return -EFAULT;
     258     6915449 :         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     3287012 : static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
     270             : {
     271     3287012 :         struct inode *inode = file_inode(filp);
     272     3287012 :         struct space_resv sr;
     273             : 
     274     3287012 :         if (copy_from_user(&sr, argp, sizeof(sr)))
     275             :                 return -EFAULT;
     276             : 
     277     3286948 :         switch (sr.l_whence) {
     278             :         case SEEK_SET:
     279             :                 break;
     280       45549 :         case SEEK_CUR:
     281       45549 :                 sr.l_start += filp->f_pos;
     282       45549 :                 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     3286948 :         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           0 : static int compat_ioctl_preallocate(struct file *file, int mode,
     298             :                                     struct space_resv_32 __user *argp)
     299             : {
     300           0 :         struct inode *inode = file_inode(file);
     301           0 :         struct space_resv_32 sr;
     302             : 
     303           0 :         if (copy_from_user(&sr, argp, sizeof(sr)))
     304             :                 return -EFAULT;
     305             : 
     306           0 :         switch (sr.l_whence) {
     307             :         case SEEK_SET:
     308             :                 break;
     309           0 :         case SEEK_CUR:
     310           0 :                 sr.l_start += file->f_pos;
     311           0 :                 break;
     312             :         case SEEK_END:
     313           0 :                 sr.l_start += i_size_read(inode);
     314           0 :                 break;
     315             :         default:
     316             :                 return -EINVAL;
     317             :         }
     318             : 
     319           0 :         return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
     320             : }
     321             : #endif
     322             : 
     323   738682354 : static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
     324             : {
     325   738682354 :         switch (cmd) {
     326       30746 :         case FIBMAP:
     327       30746 :                 return ioctl_fibmap(filp, p);
     328     1844059 :         case FS_IOC_RESVSP:
     329             :         case FS_IOC_RESVSP64:
     330     1844059 :                 return ioctl_preallocate(filp, 0, p);
     331     1442738 :         case FS_IOC_UNRESVSP:
     332             :         case FS_IOC_UNRESVSP64:
     333     1442738 :                 return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
     334         273 :         case FS_IOC_ZERO_RANGE:
     335         273 :                 return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
     336             :         }
     337             : 
     338             :         return -ENOIOCTLCMD;
     339             : }
     340             : 
     341        1980 : static int ioctl_fionbio(struct file *filp, int __user *argp)
     342             : {
     343        1980 :         unsigned int flag;
     344        1980 :         int on, error;
     345             : 
     346        1980 :         error = get_user(on, argp);
     347        1980 :         if (error)
     348             :                 return error;
     349        1980 :         flag = O_NONBLOCK;
     350             : #ifdef __sparc__
     351             :         /* SunOS compatibility item. */
     352             :         if (O_NONBLOCK != O_NDELAY)
     353             :                 flag |= O_NDELAY;
     354             : #endif
     355        1980 :         spin_lock(&filp->f_lock);
     356        1980 :         if (on)
     357        1980 :                 filp->f_flags |= flag;
     358             :         else
     359           0 :                 filp->f_flags &= ~flag;
     360        1980 :         spin_unlock(&filp->f_lock);
     361        1980 :         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             :                 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       28331 : static int ioctl_fsfreeze(struct file *filp)
     387             : {
     388       28331 :         struct super_block *sb = file_inode(filp)->i_sb;
     389             : 
     390       28331 :         if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
     391             :                 return -EPERM;
     392             : 
     393             :         /* If filesystem doesn't support freeze feature, return. */
     394       28330 :         if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL)
     395             :                 return -EOPNOTSUPP;
     396             : 
     397             :         /* Freeze */
     398       28330 :         if (sb->s_op->freeze_super)
     399           0 :                 return sb->s_op->freeze_super(sb, FREEZE_HOLDER_USERSPACE);
     400       28330 :         return freeze_super(sb, FREEZE_HOLDER_USERSPACE);
     401             : }
     402             : 
     403       28488 : static int ioctl_fsthaw(struct file *filp)
     404             : {
     405       28488 :         struct super_block *sb = file_inode(filp)->i_sb;
     406             : 
     407       28488 :         if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
     408             :                 return -EPERM;
     409             : 
     410             :         /* Thaw */
     411       28488 :         if (sb->s_op->thaw_super)
     412           0 :                 return sb->s_op->thaw_super(sb, FREEZE_HOLDER_USERSPACE);
     413       28488 :         return thaw_super(sb, FREEZE_HOLDER_USERSPACE);
     414             : }
     415             : 
     416     6455084 : static int ioctl_file_dedupe_range(struct file *file,
     417             :                                    struct file_dedupe_range __user *argp)
     418             : {
     419     6455084 :         struct file_dedupe_range *same = NULL;
     420     6455084 :         int ret;
     421     6455084 :         unsigned long size;
     422     6455084 :         u16 count;
     423             : 
     424     6455084 :         if (get_user(count, &argp->dest_count)) {
     425           0 :                 ret = -EFAULT;
     426           0 :                 goto out;
     427             :         }
     428             : 
     429     6455089 :         size = offsetof(struct file_dedupe_range, info[count]);
     430     6455089 :         if (size > PAGE_SIZE) {
     431           0 :                 ret = -ENOMEM;
     432           0 :                 goto out;
     433             :         }
     434             : 
     435     6455089 :         same = memdup_user(argp, size);
     436     6455145 :         if (IS_ERR(same)) {
     437           0 :                 ret = PTR_ERR(same);
     438           0 :                 same = NULL;
     439           0 :                 goto out;
     440             :         }
     441             : 
     442     6455145 :         same->dest_count = count;
     443     6455145 :         ret = vfs_dedupe_file_range(file, same);
     444     6455109 :         if (ret)
     445       49697 :                 goto out;
     446             : 
     447     6405412 :         ret = copy_to_user(argp, same, size);
     448     6405433 :         if (ret)
     449           0 :                 ret = -EFAULT;
     450             : 
     451     6405433 : out:
     452     6455130 :         kfree(same);
     453     6455088 :         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     3662697 : void fileattr_fill_xflags(struct fileattr *fa, u32 xflags)
     465             : {
     466     3662697 :         memset(fa, 0, sizeof(*fa));
     467     3662697 :         fa->fsx_valid = true;
     468     3662697 :         fa->fsx_xflags = xflags;
     469     3662697 :         if (fa->fsx_xflags & FS_XFLAG_IMMUTABLE)
     470         744 :                 fa->flags |= FS_IMMUTABLE_FL;
     471     3662697 :         if (fa->fsx_xflags & FS_XFLAG_APPEND)
     472         681 :                 fa->flags |= FS_APPEND_FL;
     473     3662697 :         if (fa->fsx_xflags & FS_XFLAG_SYNC)
     474         209 :                 fa->flags |= FS_SYNC_FL;
     475     3662697 :         if (fa->fsx_xflags & FS_XFLAG_NOATIME)
     476         156 :                 fa->flags |= FS_NOATIME_FL;
     477     3662697 :         if (fa->fsx_xflags & FS_XFLAG_NODUMP)
     478         134 :                 fa->flags |= FS_NODUMP_FL;
     479     3662697 :         if (fa->fsx_xflags & FS_XFLAG_DAX)
     480         304 :                 fa->flags |= FS_DAX_FL;
     481     3662697 :         if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT)
     482        3421 :                 fa->flags |= FS_PROJINHERIT_FL;
     483     3662697 : }
     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      332421 : void fileattr_fill_flags(struct fileattr *fa, u32 flags)
     495             : {
     496      332421 :         memset(fa, 0, sizeof(*fa));
     497      332421 :         fa->flags_valid = true;
     498      332421 :         fa->flags = flags;
     499      332421 :         if (fa->flags & FS_SYNC_FL)
     500       12690 :                 fa->fsx_xflags |= FS_XFLAG_SYNC;
     501      332421 :         if (fa->flags & FS_IMMUTABLE_FL)
     502       12885 :                 fa->fsx_xflags |= FS_XFLAG_IMMUTABLE;
     503      332421 :         if (fa->flags & FS_APPEND_FL)
     504       12903 :                 fa->fsx_xflags |= FS_XFLAG_APPEND;
     505      332421 :         if (fa->flags & FS_NODUMP_FL)
     506       12716 :                 fa->fsx_xflags |= FS_XFLAG_NODUMP;
     507      332421 :         if (fa->flags & FS_NOATIME_FL)
     508       12604 :                 fa->fsx_xflags |= FS_XFLAG_NOATIME;
     509      332421 :         if (fa->flags & FS_DAX_FL)
     510       12482 :                 fa->fsx_xflags |= FS_XFLAG_DAX;
     511      332421 :         if (fa->flags & FS_PROJINHERIT_FL)
     512       12490 :                 fa->fsx_xflags |= FS_XFLAG_PROJINHERIT;
     513      332421 : }
     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     3040698 : int vfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
     526             : {
     527     3040698 :         struct inode *inode = d_inode(dentry);
     528             : 
     529     3040698 :         if (!inode->i_op->fileattr_get)
     530             :                 return -ENOIOCTLCMD;
     531             : 
     532     3040659 :         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     1344619 : int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa)
     544             : {
     545     1344619 :         struct fsxattr xfa;
     546             : 
     547     1344619 :         memset(&xfa, 0, sizeof(xfa));
     548     1344619 :         xfa.fsx_xflags = fa->fsx_xflags;
     549     1344619 :         xfa.fsx_extsize = fa->fsx_extsize;
     550     1344619 :         xfa.fsx_nextents = fa->fsx_nextents;
     551     1344619 :         xfa.fsx_projid = fa->fsx_projid;
     552     1344619 :         xfa.fsx_cowextsize = fa->fsx_cowextsize;
     553             : 
     554     1344619 :         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      622149 : static int copy_fsxattr_from_user(struct fileattr *fa,
     562             :                                   struct fsxattr __user *ufa)
     563             : {
     564      622149 :         struct fsxattr xfa;
     565             : 
     566      622149 :         if (copy_from_user(&xfa, ufa, sizeof(xfa)))
     567             :                 return -EFAULT;
     568             : 
     569      622151 :         fileattr_fill_xflags(fa, xfa.fsx_xflags);
     570      622147 :         fa->fsx_extsize = xfa.fsx_extsize;
     571      622147 :         fa->fsx_nextents = xfa.fsx_nextents;
     572      622147 :         fa->fsx_projid = xfa.fsx_projid;
     573      622147 :         fa->fsx_cowextsize = xfa.fsx_cowextsize;
     574             : 
     575      622147 :         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      922239 : static int fileattr_set_prepare(struct inode *inode,
     585             :                               const struct fileattr *old_ma,
     586             :                               struct fileattr *fa)
     587             : {
     588      922239 :         int err;
     589             : 
     590             :         /*
     591             :          * The IMMUTABLE and APPEND_ONLY flags can only be changed by
     592             :          * the relevant capability.
     593             :          */
     594      940093 :         if ((fa->flags ^ old_ma->flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) &&
     595       17854 :             !capable(CAP_LINUX_IMMUTABLE))
     596             :                 return -EPERM;
     597             : 
     598      920403 :         err = fscrypt_prepare_setflags(inode, old_ma->flags, fa->flags);
     599      920403 :         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      920403 :         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     1430111 :                 if (old_ma->fsx_projid != fa->fsx_projid &&
     619      509711 :                     !projid_valid(make_kprojid(&init_user_ns, fa->fsx_projid)))
     620             :                         return -EINVAL;
     621             :         }
     622             : 
     623             :         /* Check extent size hints. */
     624      920400 :         if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode))
     625             :                 return -EINVAL;
     626             : 
     627      920400 :         if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
     628          73 :                         !S_ISDIR(inode->i_mode))
     629             :                 return -EINVAL;
     630             : 
     631      920400 :         if ((fa->fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
     632         380 :             !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      920400 :         if ((fa->fsx_xflags & FS_XFLAG_DAX) &&
     640       10381 :             !(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      920400 :         if (fa->fsx_extsize == 0)
     645      920255 :                 fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
     646      920400 :         if (fa->fsx_cowextsize == 0)
     647      920022 :                 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      927325 : int vfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
     669             :                      struct fileattr *fa)
     670             : {
     671      927325 :         struct inode *inode = d_inode(dentry);
     672      927325 :         struct fileattr old_ma = {};
     673      927325 :         int err;
     674             : 
     675      927325 :         if (!inode->i_op->fileattr_set)
     676             :                 return -ENOIOCTLCMD;
     677             : 
     678      927325 :         if (!inode_owner_or_capable(idmap, inode))
     679             :                 return -EPERM;
     680             : 
     681      922237 :         inode_lock(inode);
     682      922237 :         err = vfs_fileattr_get(dentry, &old_ma);
     683      922241 :         if (!err) {
     684             :                 /* initialize missing bits from old_ma */
     685      922241 :                 if (fa->flags_valid) {
     686      302692 :                         fa->fsx_xflags |= old_ma.fsx_xflags & ~FS_XFLAG_COMMON;
     687      302692 :                         fa->fsx_extsize = old_ma.fsx_extsize;
     688      302692 :                         fa->fsx_nextents = old_ma.fsx_nextents;
     689      302692 :                         fa->fsx_projid = old_ma.fsx_projid;
     690      302692 :                         fa->fsx_cowextsize = old_ma.fsx_cowextsize;
     691             :                 } else {
     692      619549 :                         fa->flags |= old_ma.flags & ~FS_COMMON_FL;
     693             :                 }
     694      922241 :                 err = fileattr_set_prepare(inode, &old_ma, fa);
     695      922222 :                 if (!err)
     696      920390 :                         err = inode->i_op->fileattr_set(idmap, dentry, fa);
     697             :         }
     698      922237 :         inode_unlock(inode);
     699             : 
     700      922237 :         return err;
     701             : }
     702             : EXPORT_SYMBOL(vfs_fileattr_set);
     703             : 
     704      800994 : static int ioctl_getflags(struct file *file, unsigned int __user *argp)
     705             : {
     706      800994 :         struct fileattr fa = { .flags_valid = true }; /* hint only */
     707      800994 :         int err;
     708             : 
     709      800994 :         err = vfs_fileattr_get(file->f_path.dentry, &fa);
     710      800997 :         if (!err)
     711      800995 :                 err = put_user(fa.flags, argp);
     712      800996 :         return err;
     713             : }
     714             : 
     715      305173 : static int ioctl_setflags(struct file *file, unsigned int __user *argp)
     716             : {
     717      305173 :         struct mnt_idmap *idmap = file_mnt_idmap(file);
     718      305173 :         struct dentry *dentry = file->f_path.dentry;
     719      305173 :         struct fileattr fa;
     720      305173 :         unsigned int flags;
     721      305173 :         int err;
     722             : 
     723      305173 :         err = get_user(flags, argp);
     724      305173 :         if (!err) {
     725      305173 :                 err = mnt_want_write_file(file);
     726      305173 :                 if (!err) {
     727      305174 :                         fileattr_fill_flags(&fa, flags);
     728      305173 :                         err = vfs_fileattr_set(idmap, dentry, &fa);
     729      305174 :                         mnt_drop_write_file(file);
     730             :                 }
     731             :         }
     732      305173 :         return err;
     733             : }
     734             : 
     735     1317442 : static int ioctl_fsgetxattr(struct file *file, void __user *argp)
     736             : {
     737     1317442 :         struct fileattr fa = { .fsx_valid = true }; /* hint only */
     738     1317442 :         int err;
     739             : 
     740     1317442 :         err = vfs_fileattr_get(file->f_path.dentry, &fa);
     741     1317431 :         if (!err)
     742     1317431 :                 err = copy_fsxattr_to_user(&fa, argp);
     743             : 
     744     1317425 :         return err;
     745             : }
     746             : 
     747      622150 : static int ioctl_fssetxattr(struct file *file, void __user *argp)
     748             : {
     749      622150 :         struct mnt_idmap *idmap = file_mnt_idmap(file);
     750      622153 :         struct dentry *dentry = file->f_path.dentry;
     751      622153 :         struct fileattr fa;
     752      622153 :         int err;
     753             : 
     754      622153 :         err = copy_fsxattr_from_user(&fa, argp);
     755      622147 :         if (!err) {
     756      622148 :                 err = mnt_want_write_file(file);
     757      622157 :                 if (!err) {
     758      622152 :                         err = vfs_fileattr_set(idmap, dentry, &fa);
     759      622159 :                         mnt_drop_write_file(file);
     760             :                 }
     761             :         }
     762      622160 :         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  2884071246 : static int do_vfs_ioctl(struct file *filp, unsigned int fd,
     773             :                         unsigned int cmd, unsigned long arg)
     774             : {
     775  2884071246 :         void __user *argp = (void __user *)arg;
     776  2884071246 :         struct inode *inode = file_inode(filp);
     777             : 
     778  2884071246 :         switch (cmd) {
     779          67 :         case FIOCLEX:
     780          67 :                 set_close_on_exec(fd, 1);
     781          67 :                 return 0;
     782             : 
     783           0 :         case FIONCLEX:
     784           0 :                 set_close_on_exec(fd, 0);
     785           0 :                 return 0;
     786             : 
     787        1980 :         case FIONBIO:
     788        1980 :                 return ioctl_fionbio(filp, argp);
     789             : 
     790           0 :         case FIOASYNC:
     791           0 :                 return ioctl_fioasync(fd, filp, argp);
     792             : 
     793       10348 :         case FIOQSIZE:
     794       10348 :                 if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
     795             :                     S_ISLNK(inode->i_mode)) {
     796       10348 :                         loff_t res = inode_get_bytes(inode);
     797       10348 :                         return copy_to_user(argp, &res, sizeof(res)) ?
     798       10348 :                                             -EFAULT : 0;
     799             :                 }
     800             : 
     801             :                 return -ENOTTY;
     802             : 
     803       28331 :         case FIFREEZE:
     804       28331 :                 return ioctl_fsfreeze(filp);
     805             : 
     806       28488 :         case FITHAW:
     807       28488 :                 return ioctl_fsthaw(filp);
     808             : 
     809     1650001 :         case FS_IOC_FIEMAP:
     810     1650001 :                 return ioctl_fiemap(filp, argp);
     811             : 
     812       43109 :         case FIGETBSZ:
     813             :                 /* anon_bdev filesystems may not have a block size */
     814       43109 :                 if (!inode->i_sb->s_blocksize)
     815             :                         return -EINVAL;
     816             : 
     817       43109 :                 return put_user(inode->i_sb->s_blocksize, (int __user *)argp);
     818             : 
     819       52277 :         case FICLONE:
     820       52277 :                 return ioctl_file_clone(filp, arg, 0, 0, 0);
     821             : 
     822     6915495 :         case FICLONERANGE:
     823     6915495 :                 return ioctl_file_clone_range(filp, argp);
     824             : 
     825     6455091 :         case FIDEDUPERANGE:
     826     6455091 :                 return ioctl_file_dedupe_range(filp, argp);
     827             : 
     828     2236136 :         case FIONREAD:
     829     2236136 :                 if (!S_ISREG(inode->i_mode))
     830     2236136 :                         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      800996 :         case FS_IOC_GETFLAGS:
     836      800996 :                 return ioctl_getflags(filp, argp);
     837             : 
     838      305173 :         case FS_IOC_SETFLAGS:
     839      305173 :                 return ioctl_setflags(filp, argp);
     840             : 
     841     1317456 :         case FS_IOC_FSGETXATTR:
     842     1317456 :                 return ioctl_fsgetxattr(filp, argp);
     843             : 
     844      622148 :         case FS_IOC_FSSETXATTR:
     845      622148 :                 return ioctl_fssetxattr(filp, argp);
     846             : 
     847  2863604150 :         default:
     848  2863604150 :                 if (S_ISREG(inode->i_mode))
     849   738942639 :                         return file_ioctl(filp, cmd, argp);
     850             :                 break;
     851             :         }
     852             : 
     853             :         return -ENOIOCTLCMD;
     854             : }
     855             : 
     856  5756410181 : SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
     857             : {
     858  2876019438 :         struct fd f = fdget(fd);
     859  2884498425 :         int error;
     860             : 
     861  2884498425 :         if (!f.file)
     862             :                 return -EBADF;
     863             : 
     864  2882762046 :         error = security_file_ioctl(f.file, cmd, arg);
     865  2882762046 :         if (error)
     866             :                 goto out;
     867             : 
     868  2882762046 :         error = do_vfs_ioctl(f.file, fd, cmd, arg);
     869  2880841532 :         if (error == -ENOIOCTLCMD)
     870  2857056782 :                 error = vfs_ioctl(f.file, cmd, arg);
     871             : 
     872    23784750 : out:
     873  2877129032 :         fdput(f);
     874  2879969941 :         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           0 : long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
     902             : {
     903           0 :         if (!file->f_op->unlocked_ioctl)
     904             :                 return -ENOIOCTLCMD;
     905             : 
     906           0 :         return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
     907             : }
     908             : EXPORT_SYMBOL(compat_ptr_ioctl);
     909             : 
     910           0 : COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
     911             :                        compat_ulong_t, arg)
     912             : {
     913           0 :         struct fd f = fdget(fd);
     914           0 :         int error;
     915             : 
     916           0 :         if (!f.file)
     917             :                 return -EBADF;
     918             : 
     919             :         /* RED-PEN how should LSM module know it's handling 32bit? */
     920           0 :         error = security_file_ioctl(f.file, cmd, arg);
     921           0 :         if (error)
     922             :                 goto out;
     923             : 
     924           0 :         switch (cmd) {
     925             :         /* FICLONE takes an int argument, so don't use compat_ptr() */
     926           0 :         case FICLONE:
     927           0 :                 error = ioctl_file_clone(f.file, arg, 0, 0, 0);
     928           0 :                 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           0 :                 error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
     935           0 :                 break;
     936             :         case FS_IOC_UNRESVSP_32:
     937             :         case FS_IOC_UNRESVSP64_32:
     938           0 :                 error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
     939             :                                 compat_ptr(arg));
     940           0 :                 break;
     941             :         case FS_IOC_ZERO_RANGE_32:
     942           0 :                 error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
     943             :                                 compat_ptr(arg));
     944           0 :                 break;
     945             : #endif
     946             : 
     947             :         /*
     948             :          * These access 32-bit values anyway so no further handling is
     949             :          * necessary.
     950             :          */
     951           0 :         case FS_IOC32_GETFLAGS:
     952             :         case FS_IOC32_SETFLAGS:
     953           0 :                 cmd = (cmd == FS_IOC32_GETFLAGS) ?
     954             :                         FS_IOC_GETFLAGS : FS_IOC_SETFLAGS;
     955           0 :                 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           0 :         default:
     962           0 :                 error = do_vfs_ioctl(f.file, fd, cmd,
     963             :                                      (unsigned long)compat_ptr(arg));
     964           0 :                 if (error != -ENOIOCTLCMD)
     965             :                         break;
     966             : 
     967           0 :                 if (f.file->f_op->compat_ioctl)
     968           0 :                         error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
     969           0 :                 if (error == -ENOIOCTLCMD)
     970           0 :                         error = -ENOTTY;
     971             :                 break;
     972             :         }
     973             : 
     974           0 :  out:
     975           0 :         fdput(f);
     976             : 
     977           0 :         return error;
     978             : }
     979             : #endif

Generated by: LCOV version 1.14