Skip to content

Commit 81026fb

Browse files
pvts-matPlaidCat
authored andcommitted
nfsd: don't ignore the return code of svc_proc_register()
jira VULN-64890 cve CVE-2025-22026 commit-author Jeff Layton <jlayton@kernel.org> commit 930b64c upstream-diff Ignored cherry-pick of the upstrem fix - the LTS 8.6 nfsd codebase was too distinct from the upstream for auto merging to be useful in any way. Backported checking of the `svc_proc_register()' exit code manually: fs/nfsd/stats.c Modified function `nfsd_stat_init()' instead of `nfsd_proc_stat_init()' because it was renamed in the non-backported commit 93483ac. fs/nfsd/stats.h Like above fs/nfsd/nfsctl.c - Modified `init_nfsd()' where `nfsd_stat_init()' is actually used in LTS 8.6 instead of `nfsd_net_init()', where this function call (named `nfsd_proc_stat_init()' at that time) was moved in the non-backported commit 93483ac. - Ignored the `percpu_counter_destroy_many()' cleanup not applicable to the `init_nfsd()' function. Included in the exit path instead the `nfsd4_exit_pnfs()' call with the use of newly introduced label `out_free_pnfs'. 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 <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> (cherry picked from commit 930b64c) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
1 parent 656ce6d commit 81026fb

3 files changed

Lines changed: 8 additions & 4 deletions

File tree

fs/nfsd/nfsctl.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1524,7 +1524,10 @@ static int __init init_nfsd(void)
15241524
retval = nfsd4_init_pnfs();
15251525
if (retval)
15261526
goto out_free_slabs;
1527-
nfsd_stat_init(); /* Statistics */
1527+
if (!nfsd_stat_init()) { /* Statistics */
1528+
retval = -ENOMEM;
1529+
goto out_free_pnfs;
1530+
}
15281531
retval = nfsd_drc_slab_create();
15291532
if (retval)
15301533
goto out_free_stat;
@@ -1549,6 +1552,7 @@ static int __init init_nfsd(void)
15491552
nfsd_drc_slab_free();
15501553
out_free_stat:
15511554
nfsd_stat_shutdown();
1555+
out_free_pnfs:
15521556
nfsd4_exit_pnfs();
15531557
out_free_slabs:
15541558
nfsd4_free_slabs();

fs/nfsd/stats.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ static const struct file_operations nfsd_proc_fops = {
9191
.release = single_release,
9292
};
9393

94-
void
94+
struct proc_dir_entry *
9595
nfsd_stat_init(void)
9696
{
97-
svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_fops);
97+
return svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_fops);
9898
}
9999

100100
void

fs/nfsd/stats.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct nfsd_stats {
3838
extern struct nfsd_stats nfsdstats;
3939
extern struct svc_stat nfsd_svcstats;
4040

41-
void nfsd_stat_init(void);
41+
struct proc_dir_entry * nfsd_stat_init(void);
4242
void nfsd_stat_shutdown(void);
4343

4444
#endif /* _NFSD_STATS_H */

0 commit comments

Comments
 (0)