UBUNTU-CVE-2026-89663: Use After Free
In the Linux kernel, the following vulnerability has been resolved: nfsd: revoke copy-notify stateids before dropping their reference Copy-notify stateids live in the s2scpstateids IDR and on their parent stid's sccplist, pinned by a single membership reference. freecpntfstatelocked() only unlinks an entry once its refcount reaches zero, so any revoke path that runs while a concurrent findcpntfstate()/managecpntfstate() holder has elevated cscount drops the reference without unlinking, leaving the entry discoverable with its membership reference already consumed. A second revoke or a laundromat tick then frees it while the reader still holds the pointer -- a KASAN-detectable use-after-free at the reader's nfs4putcpntfstate(). This affected all three revoke paths: - The parent-stid drain (nfs4freecpntfstatelist()) repeatedly called freecpntfstatelocked() on the first list entry; a holder that had bumped cscount made it return early, so the next iteration re-decremented and burned the holder's reference. - OFFLOADCANCEL (managecpntfstate()) and laundromat expiry likewise used freecpntfstatelocked() and could drop 2->1 without unlinking. Add revokecpntfstatelocked(), which unhashes the entry from the IDR and sccplist first (deferring the final free to any holder), and use it from all three revoke paths. The drain now walks with listforeachentrysafe() and revokes each entry unconditionally, so it terminates in one pass per entry regardless of cscount. The unhash is gated on !listempty(&cps->cplist); the idrremove() gate matters because idralloccyclic() may have recycled the soid by then. Keep freecpntfstatelocked() for the reference-holder put path only, where a concurrent revoke may already have unlinked the entry (its listdelinit() then a no-op).