diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ioctl.c | 4 | ||||
-rw-r--r-- | fs/read_write.c | 8 |
2 files changed, 10 insertions, 2 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c index c415668c86d4..6715b7208835 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -223,7 +223,11 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, if (!src_file.file) return -EBADF; + ret = -EXDEV; + if (src_file.file->f_path.mnt != dst_file->f_path.mnt) + goto fdput; ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen); +fdput: fdput(src_file); return ret; } diff --git a/fs/read_write.c b/fs/read_write.c index 3d810a11102c..175d30e3b603 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1655,8 +1655,12 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in, struct inode *inode_out = file_inode(file_out); int ret; - if (inode_in->i_sb != inode_out->i_sb || - file_in->f_path.mnt != file_out->f_path.mnt) + /* + * FICLONE/FICLONERANGE ioctls enforce that src and dest files are on + * the same mount. Practically, they only need to be on the same file + * system. + */ + if (inode_in->i_sb != inode_out->i_sb) return -EXDEV; if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) |