]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
NFS: Pin the 'struct nfs_server' during a FREE_STATEID call
authorAnna Schumaker <anna.schumaker@hammerspace.com>
Tue, 30 Jun 2026 18:31:00 +0000 (14:31 -0400)
committerAnna Schumaker <anna.schumaker@hammerspace.com>
Mon, 20 Jul 2026 15:03:56 +0000 (11:03 -0400)
Dan Aloni reports that he was able to hit a use-after-free bug if a
FREE_STATEID operation gets delayed for whatever reason. Fix this by
bumping the refcount of the 'struct nfs_server' object for the duration
of the FREE_STATEID so it doesn't get cleaned up from underneath us
while operations are still in flight.

Reported-by: Dan Aloni <dan.aloni@vastdata.com>
Fixes: 7c1d5fae4a87 ("NFSv4: Convert nfs41_free_stateid to use an asynchronous RPC call")
Tested-by: Dan Aloni <dan.aloni@vastdata.com>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
fs/nfs/nfs4proc.c

index 1360409d8de96df570025a1e125e464c25ed2196..71b6ab863b395453f8a663d6739280db42819a32 100644 (file)
@@ -10364,6 +10364,7 @@ static void nfs41_free_stateid_release(void *calldata)
        struct nfs_free_stateid_data *data = calldata;
        struct nfs_client *clp = data->server->nfs_client;
 
+       nfs_sb_deactive(data->server->super);
        nfs_put_client(clp);
        kfree(calldata);
 }
@@ -10405,6 +10406,10 @@ static int nfs41_free_stateid(struct nfs_server *server,
 
        if (!refcount_inc_not_zero(&clp->cl_count))
                return -EIO;
+       if (!nfs_sb_active(server->super)) {
+               nfs_put_client(clp);
+               return -EIO;
+       }
 
        nfs4_state_protect(clp, NFS_SP4_MACH_CRED_STATEID,
                &task_setup.rpc_client, &msg);