Re: [PATCH] NFSD: Guard admin state-revocation walks with NFSD_NET_UP

Jeff Layton <[email protected]>
Newsgroups gmane.linux.nfs
Message-ID <[email protected]>
On Sun, 2026-06-21 at 12:25 -0400, Chuck Lever wrote:

> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> index 11bbc7e8210c..29d68abfa5c8 100644
> --- a/fs/nfsd/nfsctl.c
> +++ b/fs/nfsd/nfsctl.c
> @@ -296,14 +296,15 @@ static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size)
>  	 * 2.  Is that directory a mount point, or
>  	 * 3.  Is that directory the root of an exported file system?
>  	 */
> -	nfsd4_cancel_copy_by_sb(netns(file), path.dentry->d_sb);
>  	error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
>  	mutex_lock(&nfsd_mutex);
>  	nn = net_generic(netns(file), nfsd_net_id);
> -	if (nn->nfsd_serv)
> +	if (nn->nfsd_serv) {
> +		nfsd4_cancel_copy_by_sb(netns(file), path.dentry->d_sb);
>  		nfsd4_revoke_states(nn, path.dentry->d_sb);
> -	else
> +	} else {
>  		error = -EINVAL;
> +	}
>  	mutex_unlock(&nfsd_mutex);

Can nn->nfsd_serv be non-NULL while the NFSv4 state tables are still
NULL? Looking at nfsd_create_serv() in nfssvc.c, it sets nn->nfsd_serv
when a listener is added via portlist or netlink, and that path does not
run nfsd_startup_net().

nfsd_startup_net() is what calls nfs4_state_start_net() which allocates
nn->conf_id_hashtbl in nfs4_state_create_net(). Until threads are started,
nn->nfsd_net_up stays false and the hashtables stay NULL.

In that startup window, write_unlock_fs() would pass the nn->nfsd_serv
check and then call nfsd4_cancel_copy_by_sb():

fs/nfsd/nfs4proc.c:nfsd4_cancel_copy_by_sb() {
    ...
    spin_lock(&nn->client_lock);
    for (idhashval = 0; idhashval < CLIENT_HASH_SIZE; idhashval++) {
        struct list_head *head = &nn->conf_id_hashtbl[idhashval];
        ...

Would this dereference a NULL conf_id_hashtbl and trigger the null-ptr-deref
reported in the thread? The KASAN trace shows RIP in nfsd4_cancel_copy_by_sb
at offset 0x184 with RAX 0, which matches the head pointer load.

The same pattern applies to nfsd4_revoke_states() which walks the same
table, and to nfsd_nl_unlock_filesystem_doit() in the netlink path.

Would checking nn->nfsd_net_up instead of nn->nfsd_serv be more accurate
here, since nfsd_net_up is set at the tail of nfsd_startup_net() exactly
when the state tables become valid?

-- 
Jeff Layton <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.