CVE-2026-89675
In the Linux kernel, the following vulnerability has been resolved:
nfsd: fix UAF in async copy cancel and shutdown
An async copy could be freed or used after free while a teardown caller
(OFFLOADCANCEL, nfsd4shutdowncopy, nfsd4cancelcopyby_sb) raced the
copy kthread:
- findasynccopy() bumped copy->refcount but left the copy on
clp->asynccopies, so the reaper's cleanupasync_copy() could run
releasecopyfiles() concurrently with a cancel/shutdown caller. Both
put and NULL nfsrc/nfdst without a common lock, double-putting the
nfsd_file and freeing it early.
- nfsd4doasynccopy() set NFSD4COPYFSTOPPED before its final uses
of the copy (nfsdupdatecmtimeattr() on copy->nfdst,
nfsd4sendcboffload()). nfsd4stop_copy() treats a set STOPPED bit
as "kthread done, skip kthread_stop()", so a teardown caller ran
releasecopyfiles() -- which puts and NULLs nf_dst -- while the
kthread still dereferenced it (NULL/UAF).
- copy->copy_task was never pinned. The one-shot kthread self-reaps on
return, so kthreadstop()'s gettask_struct() could touch a freed
task_struct.
- cocb is embedded in the copy, but nfsd4sendcboffload() held a
reference only on the client, so a concurrent teardown could free
the copy while the CB_OFFLOAD callback was in flight.
Fix the teardown lifetime as a whole:
- findasynccopy() unlinks the copy (clear cpclp, listdel_init)
under async_lock; the cancel, shutdown, and sb-cancel paths drop the
list-membership reference via nfs4putcopy() after nfsd4stopcopy().
Drop the now-redundant listdel fixup from cleanupasync_copy().
- Because unlinking hides the copy from the reaper, its
cleanupasynccopy() can no longer remove the copy's s2scpstateids
entry; the cancel/shutdown/sb-cancel paths now call
nfs4freecopystate() themselves (while cpclp is still valid) so
the entry does not dangle at freed memory for the laundromat and
managecpntfstate() to dereference.
- Give the kthread its own reference, taken in nfsd4_copy() before
wakeupprocess() and dropped at the end of nfsd4doasync_copy();
call wakeupprocess() before list_add().
- Pin the taskstruct with gettaskstruct() in nfsd4copy(), released
in nfs4putcopy(), so kthread_stop() is safe whenever the kthread
exits. Set NFSD4COPYFSTOPPED only in nfsd4stop_copy(), which now
always kthreadstop()s before releasecopy_files(); completion is
still reported via NFSD4COPYF_COMPLETED, so
nfsd4hasactiveasynccopies() is unaffected. Each teardown caller
removes the copy from clp->asynccopies first, so kthreadstop() runs
exactly once.
- Take a copy reference in nfsd4sendcb_offload(), dropped in
nfsd4cboffload_release(). The kthread still holds its own reference
there, so the refcount_inc() cannot race the final free.
- Read cpclp with smpload_acquire() to pair with the unordered
setbit()/clearbit() writers (Documentation/atomic_bitops.rst).
Package Versions Affected
Automatically patch vulnerabilities without upgrading
CVSS Version



Related Resources
References
https://git.kernel.org/stable/c/62c0f6eaf050bb9284c1f9cac6ed1770092e6b95, https://git.kernel.org/stable/c/9031493ef7369d5c59c4bacc96f0c85965f09a98, https://git.kernel.org/stable/c/a385cf5e016b748babf94cc664e43a26e17db117, https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/89xxx/CVE-2026-89675.json, https://nvd.nist.gov/vuln/detail/CVE-2026-89675, https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git