Commit 010bd965 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'ovl-fixes-4.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs

Miklos writes:
  "overlayfs fixes for 4.19-rc7

   This update fixes a couple of regressions in the stacked file update
   added in this cycle, as well as some older bugs uncovered by
   syzkaller.

   There's also one trivial naming change that touches other parts of
   the fs subsystem."

* tag 'ovl-fixes-4.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
  ovl: fix format of setxattr debug
  ovl: fix access beyond unterminated strings
  ovl: make symbol 'ovl_aops' static
  vfs: swap names of {do,vfs}_clone_file_range()
  ovl: fix freeze protection bypass in ovl_clone_file_range()
  ovl: fix freeze protection bypass in ovl_write_iter()
  ovl: fix memory leak on unlink of indexed file
parents ac0657ed 1a8f8d2a
...@@ -230,7 +230,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, ...@@ -230,7 +230,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
ret = -EXDEV; ret = -EXDEV;
if (src_file.file->f_path.mnt != dst_file->f_path.mnt) if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
goto fdput; goto fdput;
ret = do_clone_file_range(src_file.file, off, dst_file, destoff, olen); ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen);
fdput: fdput:
fdput(src_file); fdput(src_file);
return ret; return ret;
......
...@@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, ...@@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
__be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst, __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
u64 dst_pos, u64 count) u64 dst_pos, u64 count)
{ {
return nfserrno(do_clone_file_range(src, src_pos, dst, dst_pos, count)); return nfserrno(vfs_clone_file_range(src, src_pos, dst, dst_pos,
count));
} }
ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst, ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
......
...@@ -141,7 +141,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) ...@@ -141,7 +141,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
} }
/* Try to use clone_file_range to clone up within the same fs */ /* Try to use clone_file_range to clone up within the same fs */
error = vfs_clone_file_range(old_file, 0, new_file, 0, len); error = do_clone_file_range(old_file, 0, new_file, 0, len);
if (!error) if (!error)
goto out; goto out;
/* Couldn't clone, so now we try to copy the data */ /* Couldn't clone, so now we try to copy the data */
......
...@@ -240,8 +240,10 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter) ...@@ -240,8 +240,10 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
goto out_unlock; goto out_unlock;
old_cred = ovl_override_creds(file_inode(file)->i_sb); old_cred = ovl_override_creds(file_inode(file)->i_sb);
file_start_write(real.file);
ret = vfs_iter_write(real.file, iter, &iocb->ki_pos, ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
ovl_iocb_to_rwf(iocb)); ovl_iocb_to_rwf(iocb));
file_end_write(real.file);
revert_creds(old_cred); revert_creds(old_cred);
/* Update size */ /* Update size */
......
...@@ -504,7 +504,7 @@ static const struct inode_operations ovl_special_inode_operations = { ...@@ -504,7 +504,7 @@ static const struct inode_operations ovl_special_inode_operations = {
.update_time = ovl_update_time, .update_time = ovl_update_time,
}; };
const struct address_space_operations ovl_aops = { static const struct address_space_operations ovl_aops = {
/* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO */ /* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO */
.direct_IO = noop_direct_IO, .direct_IO = noop_direct_IO,
}; };
......
...@@ -686,7 +686,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper, ...@@ -686,7 +686,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
index = NULL; index = NULL;
goto out; goto out;
} }
pr_warn_ratelimited("overlayfs: failed inode index lookup (ino=%lu, key=%*s, err=%i);\n" pr_warn_ratelimited("overlayfs: failed inode index lookup (ino=%lu, key=%.*s, err=%i);\n"
"overlayfs: mount with '-o index=off' to disable inodes index.\n", "overlayfs: mount with '-o index=off' to disable inodes index.\n",
d_inode(origin)->i_ino, name.len, name.name, d_inode(origin)->i_ino, name.len, name.name,
err); err);
......
...@@ -152,8 +152,8 @@ static inline int ovl_do_setxattr(struct dentry *dentry, const char *name, ...@@ -152,8 +152,8 @@ static inline int ovl_do_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags) const void *value, size_t size, int flags)
{ {
int err = vfs_setxattr(dentry, name, value, size, flags); int err = vfs_setxattr(dentry, name, value, size, flags);
pr_debug("setxattr(%pd2, \"%s\", \"%*s\", 0x%x) = %i\n", pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, 0x%x) = %i\n",
dentry, name, (int) size, (char *) value, flags, err); dentry, name, min((int)size, 48), value, size, flags, err);
return err; return err;
} }
......
...@@ -683,7 +683,7 @@ static void ovl_cleanup_index(struct dentry *dentry) ...@@ -683,7 +683,7 @@ static void ovl_cleanup_index(struct dentry *dentry)
struct dentry *upperdentry = ovl_dentry_upper(dentry); struct dentry *upperdentry = ovl_dentry_upper(dentry);
struct dentry *index = NULL; struct dentry *index = NULL;
struct inode *inode; struct inode *inode;
struct qstr name; struct qstr name = { };
int err; int err;
err = ovl_get_index_name(lowerdentry, &name); err = ovl_get_index_name(lowerdentry, &name);
...@@ -726,6 +726,7 @@ static void ovl_cleanup_index(struct dentry *dentry) ...@@ -726,6 +726,7 @@ static void ovl_cleanup_index(struct dentry *dentry)
goto fail; goto fail;
out: out:
kfree(name.name);
dput(index); dput(index);
return; return;
......
...@@ -1818,8 +1818,8 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, ...@@ -1818,8 +1818,8 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
} }
EXPORT_SYMBOL(vfs_clone_file_prep_inodes); EXPORT_SYMBOL(vfs_clone_file_prep_inodes);
int vfs_clone_file_range(struct file *file_in, loff_t pos_in, int do_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, u64 len) struct file *file_out, loff_t pos_out, u64 len)
{ {
struct inode *inode_in = file_inode(file_in); struct inode *inode_in = file_inode(file_in);
struct inode *inode_out = file_inode(file_out); struct inode *inode_out = file_inode(file_out);
...@@ -1866,6 +1866,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in, ...@@ -1866,6 +1866,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
return ret; return ret;
} }
EXPORT_SYMBOL(do_clone_file_range);
int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, u64 len)
{
int ret;
file_start_write(file_out);
ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len);
file_end_write(file_out);
return ret;
}
EXPORT_SYMBOL(vfs_clone_file_range); EXPORT_SYMBOL(vfs_clone_file_range);
/* /*
......
...@@ -1828,8 +1828,10 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, ...@@ -1828,8 +1828,10 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *,
extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
struct inode *inode_out, loff_t pos_out, struct inode *inode_out, loff_t pos_out,
u64 *len, bool is_dedupe); u64 *len, bool is_dedupe);
extern int do_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, u64 len);
extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out, u64 len); struct file *file_out, loff_t pos_out, u64 len);
extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
struct inode *dest, loff_t destoff, struct inode *dest, loff_t destoff,
loff_t len, bool *is_same); loff_t len, bool *is_same);
...@@ -2773,19 +2775,6 @@ static inline void file_end_write(struct file *file) ...@@ -2773,19 +2775,6 @@ static inline void file_end_write(struct file *file)
__sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE);
} }
static inline int do_clone_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out,
u64 len)
{
int ret;
file_start_write(file_out);
ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len);
file_end_write(file_out);
return ret;
}
/* /*
* get_write_access() gets write permission for a file. * get_write_access() gets write permission for a file.
* put_write_access() releases this write permission. * put_write_access() releases this write permission.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment