LCOV - code coverage report
Current view: top level - fs - ioctl.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 48 346 13.9 %
Date: 2022-03-28 13:20:08 Functions: 5 24 20.8 %
Branches: 27 234 11.5 %

           Branch data     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                 :            : 
      22                 :            : #include "internal.h"
      23                 :            : 
      24                 :            : #include <asm/ioctls.h>
      25                 :            : 
      26                 :            : /* So that the fiemap access checks can't overflow on 32 bit machines. */
      27                 :            : #define FIEMAP_MAX_EXTENTS      (UINT_MAX / sizeof(struct fiemap_extent))
      28                 :            : 
      29                 :            : /**
      30                 :            :  * vfs_ioctl - call filesystem specific ioctl methods
      31                 :            :  * @filp:       open file to invoke ioctl method on
      32                 :            :  * @cmd:        ioctl command to execute
      33                 :            :  * @arg:        command-specific argument for ioctl
      34                 :            :  *
      35                 :            :  * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
      36                 :            :  * returns -ENOTTY.
      37                 :            :  *
      38                 :            :  * Returns 0 on success, -errno on error.
      39                 :            :  */
      40                 :      14168 : long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
      41                 :            : {
      42                 :      14168 :         int error = -ENOTTY;
      43                 :            : 
      44         [ #  # ]:          0 :         if (!filp->f_op->unlocked_ioctl)
      45                 :       2508 :                 goto out;
      46                 :            : 
      47                 :      11660 :         error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
      48   [ +  +  +  -  :      11660 :         if (error == -ENOIOCTLCMD)
                   -  - ]
      49                 :        288 :                 error = -ENOTTY;
      50                 :      11372 :  out:
      51                 :      11508 :         return error;
      52                 :            : }
      53                 :            : EXPORT_SYMBOL(vfs_ioctl);
      54                 :            : 
      55                 :          0 : static int ioctl_fibmap(struct file *filp, int __user *p)
      56                 :            : {
      57                 :          0 :         struct inode *inode = file_inode(filp);
      58                 :          0 :         int error, ur_block;
      59                 :          0 :         sector_t block;
      60                 :            : 
      61         [ #  # ]:          0 :         if (!capable(CAP_SYS_RAWIO))
      62                 :            :                 return -EPERM;
      63                 :            : 
      64                 :          0 :         error = get_user(ur_block, p);
      65         [ #  # ]:          0 :         if (error)
      66                 :            :                 return error;
      67                 :            : 
      68         [ #  # ]:          0 :         if (ur_block < 0)
      69                 :            :                 return -EINVAL;
      70                 :            : 
      71                 :          0 :         block = ur_block;
      72                 :          0 :         error = bmap(inode, &block);
      73                 :            : 
      74         [ #  # ]:          0 :         if (error)
      75                 :            :                 ur_block = 0;
      76                 :            :         else
      77                 :          0 :                 ur_block = block;
      78                 :            : 
      79         [ #  # ]:          0 :         if (put_user(ur_block, p))
      80                 :          0 :                 error = -EFAULT;
      81                 :            : 
      82                 :            :         return error;
      83                 :            : }
      84                 :            : 
      85                 :            : /**
      86                 :            :  * fiemap_fill_next_extent - Fiemap helper function
      87                 :            :  * @fieinfo:    Fiemap context passed into ->fiemap
      88                 :            :  * @logical:    Extent logical start offset, in bytes
      89                 :            :  * @phys:       Extent physical start offset, in bytes
      90                 :            :  * @len:        Extent length, in bytes
      91                 :            :  * @flags:      FIEMAP_EXTENT flags that describe this extent
      92                 :            :  *
      93                 :            :  * Called from file system ->fiemap callback. Will populate extent
      94                 :            :  * info as passed in via arguments and copy to user memory. On
      95                 :            :  * success, extent count on fieinfo is incremented.
      96                 :            :  *
      97                 :            :  * Returns 0 on success, -errno on error, 1 if this was the last
      98                 :            :  * extent that will fit in user array.
      99                 :            :  */
     100                 :            : #define SET_UNKNOWN_FLAGS       (FIEMAP_EXTENT_DELALLOC)
     101                 :            : #define SET_NO_UNMOUNTED_IO_FLAGS       (FIEMAP_EXTENT_DATA_ENCRYPTED)
     102                 :            : #define SET_NOT_ALIGNED_FLAGS   (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
     103                 :          0 : int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
     104                 :            :                             u64 phys, u64 len, u32 flags)
     105                 :            : {
     106                 :          0 :         struct fiemap_extent extent;
     107                 :          0 :         struct fiemap_extent __user *dest = fieinfo->fi_extents_start;
     108                 :            : 
     109                 :            :         /* only count the extents */
     110         [ #  # ]:          0 :         if (fieinfo->fi_extents_max == 0) {
     111                 :          0 :                 fieinfo->fi_extents_mapped++;
     112                 :          0 :                 return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
     113                 :            :         }
     114                 :            : 
     115         [ #  # ]:          0 :         if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
     116                 :            :                 return 1;
     117                 :            : 
     118         [ #  # ]:          0 :         if (flags & SET_UNKNOWN_FLAGS)
     119                 :          0 :                 flags |= FIEMAP_EXTENT_UNKNOWN;
     120         [ #  # ]:          0 :         if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
     121                 :          0 :                 flags |= FIEMAP_EXTENT_ENCODED;
     122         [ #  # ]:          0 :         if (flags & SET_NOT_ALIGNED_FLAGS)
     123                 :          0 :                 flags |= FIEMAP_EXTENT_NOT_ALIGNED;
     124                 :            : 
     125                 :          0 :         memset(&extent, 0, sizeof(extent));
     126                 :          0 :         extent.fe_logical = logical;
     127                 :          0 :         extent.fe_physical = phys;
     128                 :          0 :         extent.fe_length = len;
     129                 :          0 :         extent.fe_flags = flags;
     130                 :            : 
     131                 :          0 :         dest += fieinfo->fi_extents_mapped;
     132         [ #  # ]:          0 :         if (copy_to_user(dest, &extent, sizeof(extent)))
     133                 :            :                 return -EFAULT;
     134                 :            : 
     135                 :          0 :         fieinfo->fi_extents_mapped++;
     136         [ #  # ]:          0 :         if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
     137                 :            :                 return 1;
     138                 :          0 :         return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
     139                 :            : }
     140                 :            : EXPORT_SYMBOL(fiemap_fill_next_extent);
     141                 :            : 
     142                 :            : /**
     143                 :            :  * fiemap_check_flags - check validity of requested flags for fiemap
     144                 :            :  * @fieinfo:    Fiemap context passed into ->fiemap
     145                 :            :  * @fs_flags:   Set of fiemap flags that the file system understands
     146                 :            :  *
     147                 :            :  * Called from file system ->fiemap callback. This will compute the
     148                 :            :  * intersection of valid fiemap flags and those that the fs supports. That
     149                 :            :  * value is then compared against the user supplied flags. In case of bad user
     150                 :            :  * flags, the invalid values will be written into the fieinfo structure, and
     151                 :            :  * -EBADR is returned, which tells ioctl_fiemap() to return those values to
     152                 :            :  * userspace. For this reason, a return code of -EBADR should be preserved.
     153                 :            :  *
     154                 :            :  * Returns 0 on success, -EBADR on bad flags.
     155                 :            :  */
     156                 :          0 : int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags)
     157                 :            : {
     158                 :          0 :         u32 incompat_flags;
     159                 :            : 
     160                 :          0 :         incompat_flags = fieinfo->fi_flags & ~(FIEMAP_FLAGS_COMPAT & fs_flags);
     161         [ #  # ]:          0 :         if (incompat_flags) {
     162                 :          0 :                 fieinfo->fi_flags = incompat_flags;
     163                 :          0 :                 return -EBADR;
     164                 :            :         }
     165                 :            :         return 0;
     166                 :            : }
     167                 :            : EXPORT_SYMBOL(fiemap_check_flags);
     168                 :            : 
     169                 :          0 : static int fiemap_check_ranges(struct super_block *sb,
     170                 :            :                                u64 start, u64 len, u64 *new_len)
     171                 :            : {
     172                 :          0 :         u64 maxbytes = (u64) sb->s_maxbytes;
     173                 :            : 
     174                 :          0 :         *new_len = len;
     175                 :            : 
     176                 :          0 :         if (len == 0)
     177                 :            :                 return -EINVAL;
     178                 :            : 
     179         [ #  # ]:          0 :         if (start > maxbytes)
     180                 :            :                 return -EFBIG;
     181                 :            : 
     182                 :            :         /*
     183                 :            :          * Shrink request scope to what the fs can actually handle.
     184                 :            :          */
     185   [ #  #  #  # ]:          0 :         if (len > maxbytes || (maxbytes - len) < start)
     186                 :          0 :                 *new_len = maxbytes - start;
     187                 :            : 
     188                 :            :         return 0;
     189                 :            : }
     190                 :            : 
     191                 :          0 : static int ioctl_fiemap(struct file *filp, struct fiemap __user *ufiemap)
     192                 :            : {
     193                 :          0 :         struct fiemap fiemap;
     194                 :          0 :         struct fiemap_extent_info fieinfo = { 0, };
     195         [ #  # ]:          0 :         struct inode *inode = file_inode(filp);
     196                 :          0 :         struct super_block *sb = inode->i_sb;
     197                 :          0 :         u64 len;
     198                 :          0 :         int error;
     199                 :            : 
     200         [ #  # ]:          0 :         if (!inode->i_op->fiemap)
     201                 :            :                 return -EOPNOTSUPP;
     202                 :            : 
     203         [ #  # ]:          0 :         if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap)))
     204                 :            :                 return -EFAULT;
     205                 :            : 
     206         [ #  # ]:          0 :         if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
     207                 :            :                 return -EINVAL;
     208                 :            : 
     209         [ #  # ]:          0 :         error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
     210                 :            :                                     &len);
     211                 :          0 :         if (error)
     212                 :          0 :                 return error;
     213                 :            : 
     214                 :          0 :         fieinfo.fi_flags = fiemap.fm_flags;
     215                 :          0 :         fieinfo.fi_extents_max = fiemap.fm_extent_count;
     216                 :          0 :         fieinfo.fi_extents_start = ufiemap->fm_extents;
     217                 :            : 
     218         [ #  # ]:          0 :         if (fiemap.fm_extent_count != 0 &&
     219   [ #  #  #  # ]:          0 :             !access_ok(fieinfo.fi_extents_start,
     220                 :            :                        fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
     221                 :            :                 return -EFAULT;
     222                 :            : 
     223         [ #  # ]:          0 :         if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
     224                 :          0 :                 filemap_write_and_wait(inode->i_mapping);
     225                 :            : 
     226                 :          0 :         error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start, len);
     227                 :          0 :         fiemap.fm_flags = fieinfo.fi_flags;
     228                 :          0 :         fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
     229         [ #  # ]:          0 :         if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap)))
     230                 :          0 :                 error = -EFAULT;
     231                 :            : 
     232                 :            :         return error;
     233                 :            : }
     234                 :            : 
     235                 :        120 : static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
     236                 :            :                              u64 off, u64 olen, u64 destoff)
     237                 :            : {
     238                 :        120 :         struct fd src_file = fdget(srcfd);
     239                 :        120 :         loff_t cloned;
     240                 :        120 :         int ret;
     241                 :            : 
     242         [ +  - ]:        120 :         if (!src_file.file)
     243                 :            :                 return -EBADF;
     244                 :        120 :         ret = -EXDEV;
     245         [ -  + ]:        120 :         if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
     246                 :          0 :                 goto fdput;
     247                 :        120 :         cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
     248                 :            :                                       olen, 0);
     249         [ +  - ]:        120 :         if (cloned < 0)
     250                 :        120 :                 ret = cloned;
     251         [ #  # ]:          0 :         else if (olen && cloned != olen)
     252                 :            :                 ret = -EINVAL;
     253                 :            :         else
     254                 :          0 :                 ret = 0;
     255                 :        120 : fdput:
     256         [ -  + ]:        120 :         fdput(src_file);
     257                 :        120 :         return ret;
     258                 :            : }
     259                 :            : 
     260                 :          0 : static long ioctl_file_clone_range(struct file *file,
     261                 :            :                                    struct file_clone_range __user *argp)
     262                 :            : {
     263                 :          0 :         struct file_clone_range args;
     264                 :            : 
     265         [ #  # ]:          0 :         if (copy_from_user(&args, argp, sizeof(args)))
     266                 :            :                 return -EFAULT;
     267                 :          0 :         return ioctl_file_clone(file, args.src_fd, args.src_offset,
     268                 :            :                                 args.src_length, args.dest_offset);
     269                 :            : }
     270                 :            : 
     271                 :            : #ifdef CONFIG_BLOCK
     272                 :            : 
     273                 :          0 : static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
     274                 :            : {
     275                 :          0 :         return (offset >> inode->i_blkbits);
     276                 :            : }
     277                 :            : 
     278                 :          0 : static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
     279                 :            : {
     280                 :          0 :         return (blk << inode->i_blkbits);
     281                 :            : }
     282                 :            : 
     283                 :            : /**
     284                 :            :  * __generic_block_fiemap - FIEMAP for block based inodes (no locking)
     285                 :            :  * @inode: the inode to map
     286                 :            :  * @fieinfo: the fiemap info struct that will be passed back to userspace
     287                 :            :  * @start: where to start mapping in the inode
     288                 :            :  * @len: how much space to map
     289                 :            :  * @get_block: the fs's get_block function
     290                 :            :  *
     291                 :            :  * This does FIEMAP for block based inodes.  Basically it will just loop
     292                 :            :  * through get_block until we hit the number of extents we want to map, or we
     293                 :            :  * go past the end of the file and hit a hole.
     294                 :            :  *
     295                 :            :  * If it is possible to have data blocks beyond a hole past @inode->i_size, then
     296                 :            :  * please do not use this function, it will stop at the first unmapped block
     297                 :            :  * beyond i_size.
     298                 :            :  *
     299                 :            :  * If you use this function directly, you need to do your own locking. Use
     300                 :            :  * generic_block_fiemap if you want the locking done for you.
     301                 :            :  */
     302                 :            : 
     303                 :          0 : int __generic_block_fiemap(struct inode *inode,
     304                 :            :                            struct fiemap_extent_info *fieinfo, loff_t start,
     305                 :            :                            loff_t len, get_block_t *get_block)
     306                 :            : {
     307                 :          0 :         struct buffer_head map_bh;
     308                 :          0 :         sector_t start_blk, last_blk;
     309         [ #  # ]:          0 :         loff_t isize = i_size_read(inode);
     310                 :          0 :         u64 logical = 0, phys = 0, size = 0;
     311                 :          0 :         u32 flags = FIEMAP_EXTENT_MERGED;
     312                 :          0 :         bool past_eof = false, whole_file = false;
     313                 :          0 :         int ret = 0;
     314                 :            : 
     315         [ #  # ]:          0 :         ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
     316                 :          0 :         if (ret)
     317                 :          0 :                 return ret;
     318                 :            : 
     319                 :            :         /*
     320                 :            :          * Either the i_mutex or other appropriate locking needs to be held
     321                 :            :          * since we expect isize to not change at all through the duration of
     322                 :            :          * this call.
     323                 :            :          */
     324         [ #  # ]:          0 :         if (len >= isize) {
     325                 :          0 :                 whole_file = true;
     326                 :          0 :                 len = isize;
     327                 :            :         }
     328                 :            : 
     329                 :            :         /*
     330                 :            :          * Some filesystems can't deal with being asked to map less than
     331                 :            :          * blocksize, so make sure our len is at least block length.
     332                 :            :          */
     333         [ #  # ]:          0 :         if (logical_to_blk(inode, len) == 0)
     334                 :          0 :                 len = blk_to_logical(inode, 1);
     335                 :            : 
     336                 :          0 :         start_blk = logical_to_blk(inode, start);
     337                 :          0 :         last_blk = logical_to_blk(inode, start + len - 1);
     338                 :            : 
     339                 :          0 :         do {
     340                 :            :                 /*
     341                 :            :                  * we set b_size to the total size we want so it will map as
     342                 :            :                  * many contiguous blocks as possible at once
     343                 :            :                  */
     344                 :          0 :                 memset(&map_bh, 0, sizeof(struct buffer_head));
     345                 :          0 :                 map_bh.b_size = len;
     346                 :            : 
     347                 :          0 :                 ret = get_block(inode, start_blk, &map_bh, 0);
     348         [ #  # ]:          0 :                 if (ret)
     349                 :            :                         break;
     350                 :            : 
     351                 :            :                 /* HOLE */
     352         [ #  # ]:          0 :                 if (!buffer_mapped(&map_bh)) {
     353                 :          0 :                         start_blk++;
     354                 :            : 
     355                 :            :                         /*
     356                 :            :                          * We want to handle the case where there is an
     357                 :            :                          * allocated block at the front of the file, and then
     358                 :            :                          * nothing but holes up to the end of the file properly,
     359                 :            :                          * to make sure that extent at the front gets properly
     360                 :            :                          * marked with FIEMAP_EXTENT_LAST
     361                 :            :                          */
     362         [ #  # ]:          0 :                         if (!past_eof &&
     363         [ #  # ]:          0 :                             blk_to_logical(inode, start_blk) >= isize)
     364                 :          0 :                                 past_eof = 1;
     365                 :            : 
     366                 :            :                         /*
     367                 :            :                          * First hole after going past the EOF, this is our
     368                 :            :                          * last extent
     369                 :            :                          */
     370         [ #  # ]:          0 :                         if (past_eof && size) {
     371                 :          0 :                                 flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST;
     372                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     373                 :            :                                                               phys, size,
     374                 :            :                                                               flags);
     375         [ #  # ]:          0 :                         } else if (size) {
     376                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     377                 :            :                                                               phys, size, flags);
     378                 :          0 :                                 size = 0;
     379                 :            :                         }
     380                 :            : 
     381                 :            :                         /* if we have holes up to/past EOF then we're done */
     382   [ #  #  #  # ]:          0 :                         if (start_blk > last_blk || past_eof || ret)
     383                 :            :                                 break;
     384                 :            :                 } else {
     385                 :            :                         /*
     386                 :            :                          * We have gone over the length of what we wanted to
     387                 :            :                          * map, and it wasn't the entire file, so add the extent
     388                 :            :                          * we got last time and exit.
     389                 :            :                          *
     390                 :            :                          * This is for the case where say we want to map all the
     391                 :            :                          * way up to the second to the last block in a file, but
     392                 :            :                          * the last block is a hole, making the second to last
     393                 :            :                          * block FIEMAP_EXTENT_LAST.  In this case we want to
     394                 :            :                          * see if there is a hole after the second to last block
     395                 :            :                          * so we can mark it properly.  If we found data after
     396                 :            :                          * we exceeded the length we were requesting, then we
     397                 :            :                          * are good to go, just add the extent to the fieinfo
     398                 :            :                          * and break
     399                 :            :                          */
     400         [ #  # ]:          0 :                         if (start_blk > last_blk && !whole_file) {
     401                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     402                 :            :                                                               phys, size,
     403                 :            :                                                               flags);
     404                 :          0 :                                 break;
     405                 :            :                         }
     406                 :            : 
     407                 :            :                         /*
     408                 :            :                          * if size != 0 then we know we already have an extent
     409                 :            :                          * to add, so add it.
     410                 :            :                          */
     411         [ #  # ]:          0 :                         if (size) {
     412                 :          0 :                                 ret = fiemap_fill_next_extent(fieinfo, logical,
     413                 :            :                                                               phys, size,
     414                 :            :                                                               flags);
     415         [ #  # ]:          0 :                                 if (ret)
     416                 :            :                                         break;
     417                 :            :                         }
     418                 :            : 
     419                 :          0 :                         logical = blk_to_logical(inode, start_blk);
     420                 :          0 :                         phys = blk_to_logical(inode, map_bh.b_blocknr);
     421                 :          0 :                         size = map_bh.b_size;
     422                 :          0 :                         flags = FIEMAP_EXTENT_MERGED;
     423                 :            : 
     424                 :          0 :                         start_blk += logical_to_blk(inode, size);
     425                 :            : 
     426                 :            :                         /*
     427                 :            :                          * If we are past the EOF, then we need to make sure as
     428                 :            :                          * soon as we find a hole that the last extent we found
     429                 :            :                          * is marked with FIEMAP_EXTENT_LAST
     430                 :            :                          */
     431   [ #  #  #  # ]:          0 :                         if (!past_eof && logical + size >= isize)
     432                 :          0 :                                 past_eof = true;
     433                 :            :                 }
     434                 :          0 :                 cond_resched();
     435         [ #  # ]:          0 :                 if (fatal_signal_pending(current)) {
     436                 :            :                         ret = -EINTR;
     437                 :            :                         break;
     438                 :            :                 }
     439                 :            : 
     440                 :            :         } while (1);
     441                 :            : 
     442                 :            :         /* If ret is 1 then we just hit the end of the extent array */
     443         [ #  # ]:          0 :         if (ret == 1)
     444                 :          0 :                 ret = 0;
     445                 :            : 
     446                 :            :         return ret;
     447                 :            : }
     448                 :            : EXPORT_SYMBOL(__generic_block_fiemap);
     449                 :            : 
     450                 :            : /**
     451                 :            :  * generic_block_fiemap - FIEMAP for block based inodes
     452                 :            :  * @inode: The inode to map
     453                 :            :  * @fieinfo: The mapping information
     454                 :            :  * @start: The initial block to map
     455                 :            :  * @len: The length of the extect to attempt to map
     456                 :            :  * @get_block: The block mapping function for the fs
     457                 :            :  *
     458                 :            :  * Calls __generic_block_fiemap to map the inode, after taking
     459                 :            :  * the inode's mutex lock.
     460                 :            :  */
     461                 :            : 
     462                 :          0 : int generic_block_fiemap(struct inode *inode,
     463                 :            :                          struct fiemap_extent_info *fieinfo, u64 start,
     464                 :            :                          u64 len, get_block_t *get_block)
     465                 :            : {
     466                 :          0 :         int ret;
     467                 :          0 :         inode_lock(inode);
     468                 :          0 :         ret = __generic_block_fiemap(inode, fieinfo, start, len, get_block);
     469                 :          0 :         inode_unlock(inode);
     470                 :          0 :         return ret;
     471                 :            : }
     472                 :            : EXPORT_SYMBOL(generic_block_fiemap);
     473                 :            : 
     474                 :            : #endif  /*  CONFIG_BLOCK  */
     475                 :            : 
     476                 :            : /*
     477                 :            :  * This provides compatibility with legacy XFS pre-allocation ioctls
     478                 :            :  * which predate the fallocate syscall.
     479                 :            :  *
     480                 :            :  * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
     481                 :            :  * are used here, rest are ignored.
     482                 :            :  */
     483                 :          0 : static int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
     484                 :            : {
     485                 :          0 :         struct inode *inode = file_inode(filp);
     486                 :          0 :         struct space_resv sr;
     487                 :            : 
     488         [ #  # ]:          0 :         if (copy_from_user(&sr, argp, sizeof(sr)))
     489                 :            :                 return -EFAULT;
     490                 :            : 
     491   [ #  #  #  # ]:          0 :         switch (sr.l_whence) {
     492                 :            :         case SEEK_SET:
     493                 :            :                 break;
     494                 :          0 :         case SEEK_CUR:
     495                 :          0 :                 sr.l_start += filp->f_pos;
     496                 :          0 :                 break;
     497                 :          0 :         case SEEK_END:
     498                 :          0 :                 sr.l_start += i_size_read(inode);
     499                 :          0 :                 break;
     500                 :            :         default:
     501                 :            :                 return -EINVAL;
     502                 :            :         }
     503                 :            : 
     504                 :          0 :         return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
     505                 :            :                         sr.l_len);
     506                 :            : }
     507                 :            : 
     508                 :            : /* on ia32 l_start is on a 32-bit boundary */
     509                 :            : #if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
     510                 :            : /* just account for different alignment */
     511                 :          0 : static int compat_ioctl_preallocate(struct file *file, int mode,
     512                 :            :                                     struct space_resv_32 __user *argp)
     513                 :            : {
     514                 :          0 :         struct inode *inode = file_inode(file);
     515                 :          0 :         struct space_resv_32 sr;
     516                 :            : 
     517         [ #  # ]:          0 :         if (copy_from_user(&sr, argp, sizeof(sr)))
     518                 :            :                 return -EFAULT;
     519                 :            : 
     520   [ #  #  #  # ]:          0 :         switch (sr.l_whence) {
     521                 :            :         case SEEK_SET:
     522                 :            :                 break;
     523                 :          0 :         case SEEK_CUR:
     524                 :          0 :                 sr.l_start += file->f_pos;
     525                 :          0 :                 break;
     526                 :          0 :         case SEEK_END:
     527                 :          0 :                 sr.l_start += i_size_read(inode);
     528                 :          0 :                 break;
     529                 :            :         default:
     530                 :            :                 return -EINVAL;
     531                 :            :         }
     532                 :            : 
     533                 :          0 :         return vfs_fallocate(file, mode | FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
     534                 :            : }
     535                 :            : #endif
     536                 :            : 
     537                 :        420 : static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
     538                 :            : {
     539   [ -  -  -  -  :        420 :         switch (cmd) {
                      + ]
     540                 :          0 :         case FIBMAP:
     541                 :          0 :                 return ioctl_fibmap(filp, p);
     542                 :          0 :         case FS_IOC_RESVSP:
     543                 :            :         case FS_IOC_RESVSP64:
     544                 :          0 :                 return ioctl_preallocate(filp, 0, p);
     545                 :          0 :         case FS_IOC_UNRESVSP:
     546                 :            :         case FS_IOC_UNRESVSP64:
     547                 :          0 :                 return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
     548                 :          0 :         case FS_IOC_ZERO_RANGE:
     549                 :          0 :                 return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
     550                 :            :         }
     551                 :            : 
     552                 :            :         return -ENOIOCTLCMD;
     553                 :            : }
     554                 :            : 
     555                 :          0 : static int ioctl_fionbio(struct file *filp, int __user *argp)
     556                 :            : {
     557                 :          0 :         unsigned int flag;
     558                 :          0 :         int on, error;
     559                 :            : 
     560                 :          0 :         error = get_user(on, argp);
     561         [ #  # ]:          0 :         if (error)
     562                 :            :                 return error;
     563                 :          0 :         flag = O_NONBLOCK;
     564                 :            : #ifdef __sparc__
     565                 :            :         /* SunOS compatibility item. */
     566                 :            :         if (O_NONBLOCK != O_NDELAY)
     567                 :            :                 flag |= O_NDELAY;
     568                 :            : #endif
     569                 :          0 :         spin_lock(&filp->f_lock);
     570         [ #  # ]:          0 :         if (on)
     571                 :          0 :                 filp->f_flags |= flag;
     572                 :            :         else
     573                 :          0 :                 filp->f_flags &= ~flag;
     574                 :          0 :         spin_unlock(&filp->f_lock);
     575                 :          0 :         return error;
     576                 :            : }
     577                 :            : 
     578                 :          0 : static int ioctl_fioasync(unsigned int fd, struct file *filp,
     579                 :            :                           int __user *argp)
     580                 :            : {
     581                 :          0 :         unsigned int flag;
     582                 :          0 :         int on, error;
     583                 :            : 
     584                 :          0 :         error = get_user(on, argp);
     585         [ #  # ]:          0 :         if (error)
     586                 :            :                 return error;
     587         [ #  # ]:          0 :         flag = on ? FASYNC : 0;
     588                 :            : 
     589                 :            :         /* Did FASYNC state change ? */
     590         [ #  # ]:          0 :         if ((flag ^ filp->f_flags) & FASYNC) {
     591         [ #  # ]:          0 :                 if (filp->f_op->fasync)
     592                 :            :                         /* fasync() adjusts filp->f_flags */
     593                 :          0 :                         error = filp->f_op->fasync(fd, filp, on);
     594                 :            :                 else
     595                 :            :                         error = -ENOTTY;
     596                 :            :         }
     597                 :          0 :         return error < 0 ? error : 0;
     598                 :            : }
     599                 :            : 
     600                 :          0 : static int ioctl_fsfreeze(struct file *filp)
     601                 :            : {
     602                 :          0 :         struct super_block *sb = file_inode(filp)->i_sb;
     603                 :            : 
     604         [ #  # ]:          0 :         if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
     605                 :            :                 return -EPERM;
     606                 :            : 
     607                 :            :         /* If filesystem doesn't support freeze feature, return. */
     608   [ #  #  #  # ]:          0 :         if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL)
     609                 :            :                 return -EOPNOTSUPP;
     610                 :            : 
     611                 :            :         /* Freeze */
     612         [ #  # ]:          0 :         if (sb->s_op->freeze_super)
     613                 :          0 :                 return sb->s_op->freeze_super(sb);
     614                 :          0 :         return freeze_super(sb);
     615                 :            : }
     616                 :            : 
     617                 :          0 : static int ioctl_fsthaw(struct file *filp)
     618                 :            : {
     619                 :          0 :         struct super_block *sb = file_inode(filp)->i_sb;
     620                 :            : 
     621         [ #  # ]:          0 :         if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
     622                 :            :                 return -EPERM;
     623                 :            : 
     624                 :            :         /* Thaw */
     625         [ #  # ]:          0 :         if (sb->s_op->thaw_super)
     626                 :          0 :                 return sb->s_op->thaw_super(sb);
     627                 :          0 :         return thaw_super(sb);
     628                 :            : }
     629                 :            : 
     630                 :          0 : static int ioctl_file_dedupe_range(struct file *file,
     631                 :            :                                    struct file_dedupe_range __user *argp)
     632                 :            : {
     633                 :          0 :         struct file_dedupe_range *same = NULL;
     634                 :          0 :         int ret;
     635                 :          0 :         unsigned long size;
     636                 :          0 :         u16 count;
     637                 :            : 
     638         [ #  # ]:          0 :         if (get_user(count, &argp->dest_count)) {
     639                 :          0 :                 ret = -EFAULT;
     640                 :          0 :                 goto out;
     641                 :            :         }
     642                 :            : 
     643                 :          0 :         size = offsetof(struct file_dedupe_range __user, info[count]);
     644         [ #  # ]:          0 :         if (size > PAGE_SIZE) {
     645                 :          0 :                 ret = -ENOMEM;
     646                 :          0 :                 goto out;
     647                 :            :         }
     648                 :            : 
     649                 :          0 :         same = memdup_user(argp, size);
     650         [ #  # ]:          0 :         if (IS_ERR(same)) {
     651                 :          0 :                 ret = PTR_ERR(same);
     652                 :          0 :                 same = NULL;
     653                 :          0 :                 goto out;
     654                 :            :         }
     655                 :            : 
     656                 :          0 :         same->dest_count = count;
     657                 :          0 :         ret = vfs_dedupe_file_range(file, same);
     658         [ #  # ]:          0 :         if (ret)
     659                 :          0 :                 goto out;
     660                 :            : 
     661         [ #  # ]:          0 :         ret = copy_to_user(argp, same, size);
     662         [ #  # ]:          0 :         if (ret)
     663                 :          0 :                 ret = -EFAULT;
     664                 :            : 
     665                 :          0 : out:
     666                 :          0 :         kfree(same);
     667                 :          0 :         return ret;
     668                 :            : }
     669                 :            : 
     670                 :            : /*
     671                 :            :  * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
     672                 :            :  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
     673                 :            :  *
     674                 :            :  * When you add any new common ioctls to the switches above and below,
     675                 :            :  * please ensure they have compatible arguments in compat mode.
     676                 :            :  */
     677                 :      14288 : static int do_vfs_ioctl(struct file *filp, unsigned int fd,
     678                 :            :                         unsigned int cmd, unsigned long arg)
     679                 :            : {
     680                 :      14288 :         void __user *argp = (void __user *)arg;
     681   [ -  -  -  -  :      14288 :         struct inode *inode = file_inode(filp);
          -  -  -  -  -  
             +  -  -  +  
                      + ]
     682                 :            : 
     683   [ -  -  -  -  :      14288 :         switch (cmd) {
          -  -  -  -  -  
             +  -  -  +  
                      + ]
     684                 :          0 :         case FIOCLEX:
     685                 :          0 :                 set_close_on_exec(fd, 1);
     686                 :          0 :                 return 0;
     687                 :            : 
     688                 :          0 :         case FIONCLEX:
     689                 :          0 :                 set_close_on_exec(fd, 0);
     690                 :          0 :                 return 0;
     691                 :            : 
     692                 :          0 :         case FIONBIO:
     693                 :          0 :                 return ioctl_fionbio(filp, argp);
     694                 :            : 
     695                 :          0 :         case FIOASYNC:
     696                 :          0 :                 return ioctl_fioasync(fd, filp, argp);
     697                 :            : 
     698                 :          0 :         case FIOQSIZE:
     699   [ #  #  #  # ]:          0 :                 if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
     700                 :            :                     S_ISLNK(inode->i_mode)) {
     701                 :          0 :                         loff_t res = inode_get_bytes(inode);
     702                 :          0 :                         return copy_to_user(argp, &res, sizeof(res)) ?
     703         [ #  # ]:          0 :                                             -EFAULT : 0;
     704                 :            :                 }
     705                 :            : 
     706                 :            :                 return -ENOTTY;
     707                 :            : 
     708                 :          0 :         case FIFREEZE:
     709                 :          0 :                 return ioctl_fsfreeze(filp);
     710                 :            : 
     711                 :          0 :         case FITHAW:
     712                 :          0 :                 return ioctl_fsthaw(filp);
     713                 :            : 
     714                 :          0 :         case FS_IOC_FIEMAP:
     715                 :          0 :                 return ioctl_fiemap(filp, argp);
     716                 :            : 
     717                 :          0 :         case FIGETBSZ:
     718                 :            :                 /* anon_bdev filesystems may not have a block size */
     719         [ #  # ]:          0 :                 if (!inode->i_sb->s_blocksize)
     720                 :            :                         return -EINVAL;
     721                 :            : 
     722                 :          0 :                 return put_user(inode->i_sb->s_blocksize, (int __user *)argp);
     723                 :            : 
     724                 :        120 :         case FICLONE:
     725                 :        120 :                 return ioctl_file_clone(filp, arg, 0, 0, 0);
     726                 :            : 
     727                 :          0 :         case FICLONERANGE:
     728                 :          0 :                 return ioctl_file_clone_range(filp, argp);
     729                 :            : 
     730                 :          0 :         case FIDEDUPERANGE:
     731                 :          0 :                 return ioctl_file_dedupe_range(filp, argp);
     732                 :            : 
     733                 :       2660 :         case FIONREAD:
     734         [ +  - ]:       2660 :                 if (!S_ISREG(inode->i_mode))
     735         [ -  + ]:       5320 :                         return vfs_ioctl(filp, cmd, arg);
     736                 :            : 
     737                 :          0 :                 return put_user(i_size_read(inode) - filp->f_pos,
     738                 :            :                                 (int __user *)argp);
     739                 :            : 
     740                 :      11508 :         default:
     741         [ +  + ]:      11508 :                 if (S_ISREG(inode->i_mode))
     742                 :        420 :                         return file_ioctl(filp, cmd, argp);
     743                 :            :                 break;
     744                 :            :         }
     745                 :            : 
     746                 :            :         return -ENOIOCTLCMD;
     747                 :            : }
     748                 :            : 
     749                 :      14438 : int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
     750                 :            : {
     751                 :      14438 :         struct fd f = fdget(fd);
     752                 :      14438 :         int error;
     753                 :            : 
     754         [ +  + ]:      14438 :         if (!f.file)
     755                 :            :                 return -EBADF;
     756                 :            : 
     757                 :      14288 :         error = security_file_ioctl(f.file, cmd, arg);
     758         [ -  + ]:      14288 :         if (error)
     759                 :          0 :                 goto out;
     760                 :            : 
     761                 :      14288 :         error = do_vfs_ioctl(f.file, fd, cmd, arg);
     762         [ +  + ]:      14288 :         if (error == -ENOIOCTLCMD)
     763         [ +  + ]:      11508 :                 error = vfs_ioctl(f.file, cmd, arg);
     764                 :            : 
     765                 :       2780 : out:
     766         [ +  + ]:      14288 :         fdput(f);
     767                 :            :         return error;
     768                 :            : }
     769                 :            : 
     770                 :      28816 : SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
     771                 :            : {
     772                 :      14408 :         return ksys_ioctl(fd, cmd, arg);
     773                 :            : }
     774                 :            : 
     775                 :            : #ifdef CONFIG_COMPAT
     776                 :            : /**
     777                 :            :  * compat_ptr_ioctl - generic implementation of .compat_ioctl file operation
     778                 :            :  *
     779                 :            :  * This is not normally called as a function, but instead set in struct
     780                 :            :  * file_operations as
     781                 :            :  *
     782                 :            :  *     .compat_ioctl = compat_ptr_ioctl,
     783                 :            :  *
     784                 :            :  * On most architectures, the compat_ptr_ioctl() just passes all arguments
     785                 :            :  * to the corresponding ->ioctl handler. The exception is arch/s390, where
     786                 :            :  * compat_ptr() clears the top bit of a 32-bit pointer value, so user space
     787                 :            :  * pointers to the second 2GB alias the first 2GB, as is the case for
     788                 :            :  * native 32-bit s390 user space.
     789                 :            :  *
     790                 :            :  * The compat_ptr_ioctl() function must therefore be used only with ioctl
     791                 :            :  * functions that either ignore the argument or pass a pointer to a
     792                 :            :  * compatible data type.
     793                 :            :  *
     794                 :            :  * If any ioctl command handled by fops->unlocked_ioctl passes a plain
     795                 :            :  * integer instead of a pointer, or any of the passed data types
     796                 :            :  * is incompatible between 32-bit and 64-bit architectures, a proper
     797                 :            :  * handler is required instead of compat_ptr_ioctl.
     798                 :            :  */
     799                 :          0 : long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
     800                 :            : {
     801         [ #  # ]:          0 :         if (!file->f_op->unlocked_ioctl)
     802                 :            :                 return -ENOIOCTLCMD;
     803                 :            : 
     804                 :          0 :         return file->f_op->unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
     805                 :            : }
     806                 :            : EXPORT_SYMBOL(compat_ptr_ioctl);
     807                 :            : 
     808                 :          0 : COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
     809                 :            :                        compat_ulong_t, arg)
     810                 :            : {
     811                 :          0 :         struct fd f = fdget(fd);
     812                 :          0 :         int error;
     813                 :            : 
     814         [ #  # ]:          0 :         if (!f.file)
     815                 :            :                 return -EBADF;
     816                 :            : 
     817                 :            :         /* RED-PEN how should LSM module know it's handling 32bit? */
     818                 :          0 :         error = security_file_ioctl(f.file, cmd, arg);
     819         [ #  # ]:          0 :         if (error)
     820                 :          0 :                 goto out;
     821                 :            : 
     822   [ #  #  #  #  :          0 :         switch (cmd) {
                      # ]
     823                 :            :         /* FICLONE takes an int argument, so don't use compat_ptr() */
     824                 :          0 :         case FICLONE:
     825                 :          0 :                 error = ioctl_file_clone(f.file, arg, 0, 0, 0);
     826                 :          0 :                 break;
     827                 :            : 
     828                 :            : #if defined(CONFIG_X86_64)
     829                 :            :         /* these get messy on amd64 due to alignment differences */
     830                 :            :         case FS_IOC_RESVSP_32:
     831                 :            :         case FS_IOC_RESVSP64_32:
     832                 :          0 :                 error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
     833                 :          0 :                 break;
     834                 :            :         case FS_IOC_UNRESVSP_32:
     835                 :            :         case FS_IOC_UNRESVSP64_32:
     836                 :          0 :                 error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
     837                 :            :                                 compat_ptr(arg));
     838                 :          0 :                 break;
     839                 :            :         case FS_IOC_ZERO_RANGE_32:
     840                 :          0 :                 error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
     841                 :            :                                 compat_ptr(arg));
     842                 :          0 :                 break;
     843                 :            : #endif
     844                 :            : 
     845                 :            :         /*
     846                 :            :          * everything else in do_vfs_ioctl() takes either a compatible
     847                 :            :          * pointer argument or no argument -- call it with a modified
     848                 :            :          * argument.
     849                 :            :          */
     850                 :            :         default:
     851                 :          0 :                 error = do_vfs_ioctl(f.file, fd, cmd,
     852                 :            :                                      (unsigned long)compat_ptr(arg));
     853         [ #  # ]:          0 :                 if (error != -ENOIOCTLCMD)
     854                 :            :                         break;
     855                 :            : 
     856         [ #  # ]:          0 :                 if (f.file->f_op->compat_ioctl)
     857                 :          0 :                         error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
     858         [ #  # ]:          0 :                 if (error == -ENOIOCTLCMD)
     859                 :          0 :                         error = -ENOTTY;
     860                 :            :                 break;
     861                 :            :         }
     862                 :            : 
     863                 :          0 :  out:
     864         [ #  # ]:          0 :         fdput(f);
     865                 :            : 
     866                 :          0 :         return error;
     867                 :            : }
     868                 :            : #endif

Generated by: LCOV version 1.14