CVE-2026-89660
largeUse-After-Free in Linux Kernel NFSD During Admin State Revocation
A race condition in the Linux kernel's NFS server daemon (NFSD) allows a use-after-free when an administrator revokes a client's state (e.g., via nfsdctl/clients revocation) while that client is concurrently tearing down its session via DESTROY_CLIENTID or EXCHANGE_ID. Because a stateid holds only a bare, unpinned pointer to its nfs4_client, nfsd4_revoke_states() can drop client_lock and dereference a client that a racing teardown has already freed. A remote, unauthenticated NFS client that can win this race gains kernel memory corruption on the server, plausibly yielding a crash or code execution in kernel context; the flaw is rated CVSS 9.8. Any host running the kernel-space NFSD with NFSv4 state revocation support is affected, though triggering it requires the revocation path to be exercised during active client churn. No public proof-of-concept exists and the issue is not listed in CISA's KEV catalog, so no exploitation is currently known.
What to do: Install a kernel containing the upstream NFSD fix as soon as your distribution backports it. Until patched, avoid invoking nfsdctl/client revocation operations during heavy client connect/disconnect activity, restrict NFS exports to trusted networks, and firewall port 2049 from untrusted sources. Monitor NFS servers for oopses or crashes in nfsd4_revoke_states/revoke_one_stid paths as an indicator of attempted triggering.
| Linux kernel (in-kernel NFSD) | — |
Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.
In the Linux kernel, the following vulnerability has been resolved: NFSD: Prevent client use-after-free during admin state revocation A stateid holds only a bare pointer to its nfs4_client; a stateid reference does not pin it. The client survives only because __destroy_client() drains its stateids before free_client() runs. nfsd4_revoke_states() drops nn->client_lock across revoke_one_stid(), which dereferences the client to revoke a stateid and read clp->cl_minorversion. A teardown racing the dropped lock can free the client first. Pinning cl_rpc_users under client_lock blocks the DESTROY_CLIENTID and EXCHANGE_ID teardown, which refuses while cl_rpc_users is non-zero. force_expire_client() ignores it: once its wait for cl_rpc_users to reach zero has passed, a later pin goes unnoticed. Under client_lock, skip a client whose cl_time is already zero -- force_expire_client() clears it there before waiting -- otherwise pin cl_rpc_users before dropping the lock. The walk then either sees the expiry and skips, or pins in time for that wait to cover the revoke.
- Vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
In the news0 stories
No ingested article mentions this CVE yet.