Skip to content

Commit e80bdc5

Browse files
committed
Merge tag 'nfsd-5.16-2' of git://linux-nfs.org/~bfields/linux
Pull nfsd fixes from Bruce Fields: "Fix a race on startup and another in the delegation code. The latter has been around for years, but I suspect recent changes may have widened the race window a little, so I'd like to go ahead and get it in" * tag 'nfsd-5.16-2' of git://linux-nfs.org/~bfields/linux: nfsd: fix use-after-free due to delegation race nfsd: Fix nsfd startup race (again)
2 parents b990264 + 548ec08 commit e80bdc5

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

fs/nfsd/nfs4recover.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,6 +2156,7 @@ static struct notifier_block nfsd4_cld_block = {
21562156
int
21572157
register_cld_notifier(void)
21582158
{
2159+
WARN_ON(!nfsd_net_id);
21592160
return rpc_pipefs_notifier_register(&nfsd4_cld_block);
21602161
}
21612162

fs/nfsd/nfs4state.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,14 +1207,19 @@ hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
12071207
return 0;
12081208
}
12091209

1210+
static bool delegation_hashed(struct nfs4_delegation *dp)
1211+
{
1212+
return !(list_empty(&dp->dl_perfile));
1213+
}
1214+
12101215
static bool
12111216
unhash_delegation_locked(struct nfs4_delegation *dp)
12121217
{
12131218
struct nfs4_file *fp = dp->dl_stid.sc_file;
12141219

12151220
lockdep_assert_held(&state_lock);
12161221

1217-
if (list_empty(&dp->dl_perfile))
1222+
if (!delegation_hashed(dp))
12181223
return false;
12191224

12201225
dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
@@ -4598,7 +4603,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb)
45984603
* queued for a lease break. Don't queue it again.
45994604
*/
46004605
spin_lock(&state_lock);
4601-
if (dp->dl_time == 0) {
4606+
if (delegation_hashed(dp) && dp->dl_time == 0) {
46024607
dp->dl_time = ktime_get_boottime_seconds();
46034608
list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
46044609
}

fs/nfsd/nfsctl.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,12 +1521,9 @@ static int __init init_nfsd(void)
15211521
int retval;
15221522
printk(KERN_INFO "Installing knfsd (copyright (C) 1996 [email protected]).\n");
15231523

1524-
retval = register_cld_notifier();
1525-
if (retval)
1526-
return retval;
15271524
retval = nfsd4_init_slabs();
15281525
if (retval)
1529-
goto out_unregister_notifier;
1526+
return retval;
15301527
retval = nfsd4_init_pnfs();
15311528
if (retval)
15321529
goto out_free_slabs;
@@ -1545,9 +1542,14 @@ static int __init init_nfsd(void)
15451542
goto out_free_exports;
15461543
retval = register_pernet_subsys(&nfsd_net_ops);
15471544
if (retval < 0)
1545+
goto out_free_filesystem;
1546+
retval = register_cld_notifier();
1547+
if (retval)
15481548
goto out_free_all;
15491549
return 0;
15501550
out_free_all:
1551+
unregister_pernet_subsys(&nfsd_net_ops);
1552+
out_free_filesystem:
15511553
unregister_filesystem(&nfsd_fs_type);
15521554
out_free_exports:
15531555
remove_proc_entry("fs/nfs/exports", NULL);
@@ -1561,13 +1563,12 @@ static int __init init_nfsd(void)
15611563
nfsd4_exit_pnfs();
15621564
out_free_slabs:
15631565
nfsd4_free_slabs();
1564-
out_unregister_notifier:
1565-
unregister_cld_notifier();
15661566
return retval;
15671567
}
15681568

15691569
static void __exit exit_nfsd(void)
15701570
{
1571+
unregister_cld_notifier();
15711572
unregister_pernet_subsys(&nfsd_net_ops);
15721573
nfsd_drc_slab_free();
15731574
remove_proc_entry("fs/nfs/exports", NULL);
@@ -1577,7 +1578,6 @@ static void __exit exit_nfsd(void)
15771578
nfsd4_free_slabs();
15781579
nfsd4_exit_pnfs();
15791580
unregister_filesystem(&nfsd_fs_type);
1580-
unregister_cld_notifier();
15811581
}
15821582

15831583
MODULE_AUTHOR("Olaf Kirch <[email protected]>");

0 commit comments

Comments
 (0)