CVE-2026-89670
High · 7.8CVSS
7.8
EPSS
0.2%
Published
Sep 11, 2026
CISA due date
—
Cloudanix analysis
A flaw in the Linux kernel's file sharing server can let a logged-in user crash the whole machine or possibly gain extra privileges.
- Exploitation
- Local Privilege
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Full Compromise
- Component
- OS kernel
- Class
- Use After Free
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Use-after-free in nfsd_open_local_fh() where a cmpxchg loads a pointer to an nfsd_file object that can be freed via call_rcu and then reused; the subsequent refcount_inc_not_zero and dereference of nf_net/nf_file occur without an enclosing rcu_read_lock, allowing access to recycled slab memory.
Why it matters to the business
Local attackers on Linux systems running the NFS server can trigger kernel memory corruption, leading to crashes, denial of service, or potential privilege escalation; the issue affects any deployment exposing nfsd local file handle paths and requires urgent kernel updates given the 43-day window since disclosure.
How an attack unfolds
An attacker with local access concurrently invokes nfs_open_local_fh while another thread performs nfsd_file_put_local, causing the cmpxchg in nfsd_open_local_fh to observe a pointer that is immediately xchg'd and freed via call_rcu; after the grace period the slab is recycled, the refcount operation succeeds on freed memory, and later dereferences produce the use-after-free.
How to fix it
Apply the upstream fix that wraps the cmpxchg retry block with rcu_read_lock held on all three exit paths; rebuild and deploy the patched kernel; no configuration changes are required.
How to confirm the fix worked
Confirm the patched kernel source contains the rcu_read_lock immediately before the cmpxchg and rcu_read_unlock on the retry, lost-race, and success paths; run kernel selftests exercising nfsd local file handles under concurrency; verify no slab-use-after-free reports in dmesg during stress.
Typical attack path
- Obtain local shell on a system running nfsd
- Trigger repeated nfs_open_local_fh calls while racing with nfsd_file_put_local operations
- Force RCU grace period to reclaim the nfsd_file slab page
- Observe refcount_inc_not_zero succeeding on recycled memory
- Dereference freed nf_net or nf_file fields to corrupt kernel state or crash
How to detect it
Search kernel logs for oops or warnings referencing nfsd_file, nf_ref, or call_rcu in the nfsd path; inspect for concurrent local file handle operations preceding the crash; no public exploit artifacts are known.
What your security team should do
- Patch kernels to the version containing the RCU fix within the next maintenance window
- Restrict local access to systems running nfsd until patched
- Enable kernel hardening features such as CONFIG_SLAB_VIRTUAL and lockdep to increase exploit difficulty
- Monitor for nfsd-related oops and RCU stalls in production logs
The record
In the Linux kernel, the following vulnerability has been resolved: nfsd: hold rcu across localio cmpxchg retry nfsd_file objects are freed via call_rcu (filecache.c:296), and nfsd_file_slab is created without SLAB_TYPESAFE_BY_RCU (KMEM_CACHE(nfsd_file, 0) at filecache.c:789), so the slab page backing a freed nfsd_file becomes freely reclaimable once the RCU grace period elapses. The again: retry block in nfsd_open_local_fh() loads a pointer with cmpxchg and then calls nfsd_file_get(new) (which is refcount_inc_not_zero) without holding rcu_read_lock. The sole caller nfs_open_local_fh() drops rcu_read_lock before invoking this helper, so no outer reader-side critical section covers the load. CPU 0 (nfsd_open_local_fh) CPU 1 (nfsd_file_put_local) ----- ----- new = cmpxchg(pnf, NULL, ...) nf = xchg(pnf, NULL) nfsd_file_put(nf) last ref -> call_rcu() /* grace period elapses; slab page recycled */ nfsd_file_get(new) refcount_inc_not_zero(&new->nf_ref) /* operates on recycled memory */ A non-zero word at the nf_ref offset of the recycled object makes the refcount bump appear to succeed, and the caller then dereferences new->nf_net and new->nf_file out of freed memory. Fix by taking rcu_read_lock() immediately before the cmpxchg and releasing it on all three exits of the if (new) block: the goto-again retry, the lost-race cleanup path, and the install-succeeded path. nfsd_file_put() and nfsd_net_put() stay outside the RCU section so they remain free to block.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|