From: Amir Goldstein <amir73il@gmail.com> mainline inclusion from mainline-v6.5-rc1 commit dff745c1221a402b4921d54f292288373cff500c category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/15316 CVE: CVE-2026-46054 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- The use of file_free_rcu() in init_file() to free the struct that was allocated by the caller was hacky and we got what we deserved. Let init_file() and its callers take care of cleaning up each after their own allocated resources on error. Fixes: 62d53c4a1dfe ("fs: use backing_file container for internal files with "fake" f_path") # mainline only Reported-and-tested-by: syzbot+ada42aab05cf51b00e98@syzkaller.appspotmail.com Signed-off-by: Amir Goldstein <amir73il@gmail.com> Message-Id: <20230701171134.239409-1-amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org> Conflicts: fs/file_table.c [Original patch is file_free_rcu(&f->f_rcuhead); But for 5.10 is file_free_rcu(&f_u.fu_rcuhead). We replace that with put_cred(f->f_cred).] Signed-off-by: Cai Xinchen <caixinchen1@huawei.com> --- fs/file_table.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/file_table.c b/fs/file_table.c index 94e99c9700cd..3d27e490d163 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -153,7 +153,7 @@ static int init_file(struct file *f, int flags, const struct cred *cred) f->f_cred = get_cred(cred); error = security_file_alloc(f); if (unlikely(error)) { - file_free_rcu(&f->f_u.fu_rcuhead); + put_cred(f->f_cred); return error; } @@ -202,8 +202,10 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) return ERR_PTR(-ENOMEM); error = init_file(f, flags, cred); - if (unlikely(error)) + if (unlikely(error)) { + kmem_cache_free(filp_cachep, f); return ERR_PTR(error); + } percpu_counter_inc(&nr_files); @@ -234,8 +236,10 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred) return ERR_PTR(-ENOMEM); error = init_file(f, flags, cred); - if (unlikely(error)) + if (unlikely(error)) { + kmem_cache_free(filp_cachep, f); return ERR_PTR(error); + } f->f_mode |= FMODE_NOACCOUNT; @@ -259,8 +263,10 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred) return ERR_PTR(-ENOMEM); error = init_file(&ff->file, flags, cred); - if (unlikely(error)) + if (unlikely(error)) { + kfree(ff); return ERR_PTR(error); + } ff->file.f_mode |= FMODE_BACKING | FMODE_NOACCOUNT; return &ff->file; -- 2.18.0.huawei.25