Skip to content

Commit de3208f

Browse files
author
Olga Kornievskaia
committed
nfsd: don't ignore the return code of svc_proc_register()
JIRA: https://issues.redhat.com/browse/RHEL-93612 CVE: CVE-2025-22026 Conflicts: several conflicts patching file fs/nfsd/nfsctl.c Hunk #1 FAILED at 2202. Due to missing 86ab08b "SUNRPC: replace program list with program array" -- a part of a large patch series Due to missing 73598a0 "nfsd: don't allocate the versions array." -- a part of the large patch series Hunk #2 FAILED at 2213. because there is no LOCALIO functionality but specifically fa49838 "nfsd: add LOCALIO support" checking file fs/nfsd/stats.h Hunk #1 FAILED at 10. Due to missing 7d12cce "fs: nfsd: use group allocation/free of per-cpu counters API" commit 930b64c Author: Jeff Layton <[email protected]> Date: Thu, 6 Feb 2025 13:12:13 -0500 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: [email protected] Closes: https://lore.kernel.org/linux-nfs/[email protected]/ Cc: [email protected] # v6.9 Signed-off-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]> Signed-off-by: Olga Kornievskaia <[email protected]>
1 parent 6e54f33 commit de3208f

File tree

3 files changed

+10
-4
lines changed

3 files changed

+10
-4
lines changed

fs/nfsd/nfsctl.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2236,19 +2236,25 @@ static __net_init int nfsd_net_init(struct net *net)
22362236
retval = nfsd_stat_counters_init(nn);
22372237
if (retval)
22382238
goto out_repcache_error;
2239+
22392240
memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
22402241
nn->nfsd_svcstats.program = &nfsd_program;
2242+
if (!nfsd_proc_stat_init(net)) {
2243+
retval = -ENOMEM;
2244+
goto out_proc_error;
2245+
}
22412246
nn->nfsd_versions = NULL;
22422247
nn->nfsd4_minorversions = NULL;
22432248
nn->nfsd_info.mutex = &nfsd_mutex;
22442249
nn->nfsd_serv = NULL;
22452250
nfsd4_init_leases_net(nn);
22462251
get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key));
22472252
seqlock_init(&nn->writeverf_lock);
2248-
nfsd_proc_stat_init(net);
22492253

22502254
return 0;
22512255

2256+
out_proc_error:
2257+
percpu_counter_destroy_many(nn->counter, NFSD_STATS_COUNTERS_NUM);
22522258
out_repcache_error:
22532259
nfsd_idmap_shutdown(net);
22542260
out_idmap_error:

fs/nfsd/stats.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ void nfsd_stat_counters_destroy(struct nfsd_net *nn)
115115
nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM);
116116
}
117117

118-
void nfsd_proc_stat_init(struct net *net)
118+
struct proc_dir_entry *nfsd_proc_stat_init(struct net *net)
119119
{
120120
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
121121

122-
svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops);
122+
return svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops);
123123
}
124124

125125
void nfsd_proc_stat_shutdown(struct net *net)

fs/nfsd/stats.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num);
1515
void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num);
1616
int nfsd_stat_counters_init(struct nfsd_net *nn);
1717
void nfsd_stat_counters_destroy(struct nfsd_net *nn);
18-
void nfsd_proc_stat_init(struct net *net);
18+
struct proc_dir_entry *nfsd_proc_stat_init(struct net *net);
1919
void nfsd_proc_stat_shutdown(struct net *net);
2020

2121
static inline void nfsd_stats_rc_hits_inc(struct nfsd_net *nn)

0 commit comments

Comments
 (0)