From 3d32877322450061e245c0fbbe9f1777b74aabe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Wcis=C5=82o?= Date: Tue, 9 Sep 2025 01:20:38 +0200 Subject: [PATCH] nfsd: don't ignore the return code of svc_proc_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jira VULN-64896 cve CVE-2025-22026 commit-author Jeff Layton commit 930b64ca0c511521f0abdd1d57ce52b2a6e3476b upstream-diff | nfsd underwent considerable architectural changes related to the exposition of network stats in the user space since `ciqlts9_4' branched off, which are assumed by the upstream fix 930b64ca0c511521f0abdd1d57ce52b2a6e3476b to be in place - see patches d98416cc2, 93483ac5f, 4b1488541, e41ee44cc, 16fb9808a. This backport addresses the core of the issue without pulling in all of these changes, which is checking the value returned by `svc_proc_register'. Currently, nfsd_proc_stat_init() ignores the return value of svc_proc_register(). If the procfile creation fails, then the kernel will WARN when it tries to remove the entry later. Fix nfsd_proc_stat_init() to return the same type of pointer as svc_proc_register(), and fix up nfsd_net_init() to check that and fail the nfsd_net construction if it occurs. svc_proc_register() can fail if the dentry can't be allocated, or if an identical dentry already exists. The second case is pretty unlikely in the nfsd_net construction codepath, so if this happens, return -ENOMEM. Reported-by: syzbot+e34ad04f27991521104c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-nfs/67a47501.050a0220.19061f.05f9.GAE@google.com/ Cc: stable@vger.kernel.org # v6.9 Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever (cherry picked from commit 930b64ca0c511521f0abdd1d57ce52b2a6e3476b) Signed-off-by: Marcin Wcisło --- fs/nfsd/stats.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index 63797635e1c32..a4e6b149da56b 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c @@ -126,7 +126,10 @@ int nfsd_stat_init(void) if (err) return err; - svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_ops); + if (!svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_ops)) { + nfsd_stat_counters_destroy(); + return -ENOMEM; + } return 0; }