PT-2026-90391 · Linux · Linux

CVE-2026-89675

·

Publicado

2026-09-11

·

Atualizado

2026-09-11

CVSS v3.1

9.8

Crítica

VetorAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
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 (OFFLOAD CANCEL, nfsd4 shutdown copy, nfsd4 cancel copy by sb) raced the copy kthread:
  • find async copy() bumped copy->refcount but left the copy on clp->async copies, so the reaper's cleanup async copy() could run release copy files() concurrently with a cancel/shutdown caller. Both put and NULL nf src/nf dst without a common lock, double-putting the nfsd file and freeing it early.
  • nfsd4 do async copy() set NFSD4 COPY F STOPPED before its final uses of the copy (nfsd update cmtime attr() on copy->nf dst, nfsd4 send cb offload()). nfsd4 stop copy() treats a set STOPPED bit as "kthread done, skip kthread stop()", so a teardown caller ran release copy files() -- 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 kthread stop()'s get task struct() could touch a freed task struct.
  • co cb is embedded in the copy, but nfsd4 send cb offload() 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:
  • find async copy() unlinks the copy (clear cp clp, list del init) under async lock; the cancel, shutdown, and sb-cancel paths drop the list-membership reference via nfs4 put copy() after nfsd4 stop copy(). Drop the now-redundant list del fixup from cleanup async copy().
  • Because unlinking hides the copy from the reaper, its cleanup async copy() can no longer remove the copy's s2s cp stateids entry; the cancel/shutdown/sb-cancel paths now call nfs4 free copy state() themselves (while cp clp is still valid) so the entry does not dangle at freed memory for the laundromat and manage cpntf state() to dereference.
  • Give the kthread its own reference, taken in nfsd4 copy() before wake up process() and dropped at the end of nfsd4 do async copy(); call wake up process() before list add().
  • Pin the task struct with get task struct() in nfsd4 copy(), released in nfs4 put copy(), so kthread stop() is safe whenever the kthread exits. Set NFSD4 COPY F STOPPED only in nfsd4 stop copy(), which now always kthread stop()s before release copy files(); completion is still reported via NFSD4 COPY F COMPLETED, so nfsd4 has active async copies() is unaffected. Each teardown caller removes the copy from clp->async copies first, so kthread stop() runs exactly once.
  • Take a copy reference in nfsd4 send cb offload(), dropped in nfsd4 cb offload release(). The kthread still holds its own reference there, so the refcount inc() cannot race the final free.
  • Read cp clp with smp load acquire() to pair with the unordered set bit()/clear bit() writers (Documentation/atomic bitops.rst).

Correção

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

CVE-2026-89675

Produtos afetados

Linux