Commit 28c7980f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'v6.5/vfs.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs fix from Christian Brauner:
 "A fix for the backing file work from this cycle.

  When init_file() failed it would call file_free_rcu() on the file
  allocated by the caller of init_file(). It naively assumed that the
  correct cleanup operation would be called depending on whether it is a
  regular file or a backing file. However, that presupposes that the
  FMODE_BACKING flag would already be set which it won't be as that is
  done in the caller of init_file().

  Fix that bug by moving the cleanup of the allocated file into the
  caller where it belongs in the first place. There's no good reason for
  init_file() to consume resources it didn't allocate. This is a
  mainline only fix and was reported by syzbot. The fix was validated by
  syzbot against the provided reproducer"

* tag 'v6.5/vfs.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  fs: move cleanup from init_file() into its callers
parents 5def00ca dff745c1
...@@ -160,7 +160,7 @@ static int init_file(struct file *f, int flags, const struct cred *cred) ...@@ -160,7 +160,7 @@ static int init_file(struct file *f, int flags, const struct cred *cred)
f->f_cred = get_cred(cred); f->f_cred = get_cred(cred);
error = security_file_alloc(f); error = security_file_alloc(f);
if (unlikely(error)) { if (unlikely(error)) {
file_free_rcu(&f->f_rcuhead); put_cred(f->f_cred);
return error; return error;
} }
...@@ -208,8 +208,10 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) ...@@ -208,8 +208,10 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
error = init_file(f, flags, cred); error = init_file(f, flags, cred);
if (unlikely(error)) if (unlikely(error)) {
kmem_cache_free(filp_cachep, f);
return ERR_PTR(error); return ERR_PTR(error);
}
percpu_counter_inc(&nr_files); percpu_counter_inc(&nr_files);
...@@ -240,8 +242,10 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred) ...@@ -240,8 +242,10 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
error = init_file(f, flags, cred); error = init_file(f, flags, cred);
if (unlikely(error)) if (unlikely(error)) {
kmem_cache_free(filp_cachep, f);
return ERR_PTR(error); return ERR_PTR(error);
}
f->f_mode |= FMODE_NOACCOUNT; f->f_mode |= FMODE_NOACCOUNT;
...@@ -265,8 +269,10 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred) ...@@ -265,8 +269,10 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
error = init_file(&ff->file, flags, cred); error = init_file(&ff->file, flags, cred);
if (unlikely(error)) if (unlikely(error)) {
kfree(ff);
return ERR_PTR(error); return ERR_PTR(error);
}
ff->file.f_mode |= FMODE_BACKING | FMODE_NOACCOUNT; ff->file.f_mode |= FMODE_BACKING | FMODE_NOACCOUNT;
return &ff->file; return &ff->file;
......
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