{"id":"CVE-2026-89675","title":"nfsd: fix UAF in async copy cancel and shutdown","summary":"In the Linux kernel, the following vulnerability has been resolved:\n\nnfsd: fix UAF in async copy cancel and shutdown\n\nAn async copy could be freed or used after free while a teardown caller\n(OFFLOAD_CANCEL, nfsd4_shutdown_copy, nfsd4_can…","severity":"critical","cvss":9.8,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","cvssSource":"cna","cwe":["CWE-825"],"vendor":"Linux","product":"Linux","affected":["Linux >= e0639dc5805a9d4faaa2c07ad98fa853b9529dd3 < 9031493ef7369d5c59c4bacc96f0c85965f09a98","Linux >= e0639dc5805a9d4faaa2c07ad98fa853b9529dd3 < a385cf5e016b748babf94cc664e43a26e17db117","Linux >= e0639dc5805a9d4faaa2c07ad98fa853b9529dd3 < 62c0f6eaf050bb9284c1f9cac6ed1770092e6b95","Linux 4.20"],"ssvc":{"exploitation":"none","automatable":"yes","technicalImpact":"total","timestamp":"2026-10-16T19:25:50.674765Z"},"published":"2026-09-11","updated":"2026-10-19","sourceUpdated":"2026-10-19T08:50:48.585Z","source":"CVEORG","sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-89675","references":[{"url":"https://git.kernel.org/stable/c/9031493ef7369d5c59c4bacc96f0c85965f09a98"},{"url":"https://git.kernel.org/stable/c/a385cf5e016b748babf94cc664e43a26e17db117"},{"url":"https://git.kernel.org/stable/c/62c0f6eaf050bb9284c1f9cac6ed1770092e6b95"},{"url":"https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-89675.json"},{"url":"https://access.redhat.com/security/cve/CVE-2026-89675"},{"url":"https://bugzilla.redhat.com/show_bug.cgi?id=2532272"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-89675"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-89675"},{"url":"https://git.kernel.org/pub/scm/linux/security/vulns.git/plain/cve/published/2026/CVE-2026-89675.mbox"}],"tags":["cve.org","csaf","vex","red-hat","score-dispute"],"epss":0.00442,"epssPercentile":0.38243,"scores":{"cna":9.8,"vendor":7},"ingestedAt":"2026-09-14T15:23:07.473Z","slug":"CVE-2026-89675","body":"## Overview\n\nIn the Linux kernel, the following vulnerability has been resolved:\n\nnfsd: fix UAF in async copy cancel and shutdown\n\nAn async copy could be freed or used after free while a teardown caller\n(OFFLOAD_CANCEL, nfsd4_shutdown_copy, nfsd4_cancel_copy_by_sb) raced the\ncopy kthread:\n\n  - find_async_copy() bumped copy->refcount but left the copy on\n    clp->async_copies, so the reaper's cleanup_async_copy() could run\n    release_copy_files() concurrently with a cancel/shutdown caller. Both\n    put and NULL nf_src/nf_dst without a common lock, double-putting the\n    nfsd_file and freeing it early.\n\n  - nfsd4_do_async_copy() set NFSD4_COPY_F_STOPPED before its final uses\n    of the copy (nfsd_update_cmtime_attr() on copy->nf_dst,\n    nfsd4_send_cb_offload()). nfsd4_stop_copy() treats a set STOPPED bit\n    as \"kthread done, skip kthread_stop()\", so a teardown caller ran\n    release_copy_files() -- which puts and NULLs nf_dst -- while the\n    kthread still dereferenced it (NULL/UAF).\n\n  - copy->copy_task was never pinned. The one-shot kthread self-reaps on\n    return, so kthread_stop()'s get_task_struct() could touch a freed\n    task_struct.\n\n  - co_cb is embedded in the copy, but nfsd4_send_cb_offload() held a\n    reference only on the client, so a concurrent teardown could free\n    the copy while the CB_OFFLOAD callback was in flight.\n\nFix the teardown lifetime as a whole:\n\n  - find_async_copy() unlinks the copy (clear cp_clp, list_del_init)\n    under async_lock; the cancel, shutdown, and sb-cancel paths drop the\n    list-membership reference via nfs4_put_copy() after nfsd4_stop_copy().\n    Drop the now-redundant list_del fixup from cleanup_async_copy().\n\n  - Because unlinking hides the copy from the reaper, its\n    cleanup_async_copy() can no longer remove the copy's s2s_cp_stateids\n    entry; the cancel/shutdown/sb-cancel paths now call\n    nfs4_free_copy_state() themselves (while cp_clp is still valid) so\n    the entry does not dangle at freed memory for the laundromat and\n    manage_cpntf_state() to dereference.\n\n  - Give the kthread its own reference, taken in nfsd4_copy() before\n    wake_up_process() and dropped at the end of nfsd4_do_async_copy();\n    call wake_up_process() before list_add().\n\n  - Pin the task_struct with get_task_struct() in nfsd4_copy(), released\n    in nfs4_put_copy(), so kthread_stop() is safe whenever the kthread\n    exits. Set NFSD4_COPY_F_STOPPED only in nfsd4_stop_copy(), which now\n    always kthread_stop()s before release_copy_files(); completion is\n    still reported via NFSD4_COPY_F_COMPLETED, so\n    nfsd4_has_active_async_copies() is unaffected. Each teardown caller\n    removes the copy from clp->async_copies first, so kthread_stop() runs\n    exactly once.\n\n  - Take a copy reference in nfsd4_send_cb_offload(), dropped in\n    nfsd4_cb_offload_release(). The kthread still holds its own reference\n    there, so the refcount_inc() cannot race the final free.\n\n  - Read cp_clp with smp_load_acquire() to pair with the unordered\n    set_bit()/clear_bit() writers (Documentation/atomic_bitops.rst).\n\n## Affected\n\n- `Linux >= e0639dc5805a9d4faaa2c07ad98fa853b9529dd3 < 9031493ef7369d5c59c4bacc96f0c85965f09a98`\n- `Linux >= e0639dc5805a9d4faaa2c07ad98fa853b9529dd3 < a385cf5e016b748babf94cc664e43a26e17db117`\n- `Linux >= e0639dc5805a9d4faaa2c07ad98fa853b9529dd3 < 62c0f6eaf050bb9284c1f9cac6ed1770092e6b95`\n- `Linux 4.20`\n\n## Remediation\n\nRefer to the linked advisories for vendor-supplied fixes and affected version ranges.\n\n## Vendor advisories\n\n- **Red Hat VEX** · Important · affected: Red Hat Enterprise Linux 10, Red Hat Enterprise Linux 8, Red Hat Enterprise Linux 9, Red Hat OpenShift Container Platform 4 · no fix planned: Red Hat Enterprise Linux 10, Red Hat Enterprise Linux 8, Red Hat Enterprise Linux 9, Red Hat OpenShift Container Platform 4 · updated 2026-09-21 · [vex](https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-89675.json)","depth":"midnight","depthScore":54,"depthScoreParts":{"impact":53.9,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[{"seq":223244,"id":"CVE-2026-89675","ts":1792180029549,"field":"cvss","old":"7","new":"9.8"},{"seq":223243,"id":"CVE-2026-89675","ts":1792180029549,"field":"severity","old":"high","new":"critical"},{"seq":208455,"id":"CVE-2026-89675","ts":1790005706034,"field":"cvss","old":"6.4","new":"7"},{"seq":208454,"id":"CVE-2026-89675","ts":1790005706034,"field":"severity","old":"medium","new":"high"},{"seq":202991,"id":"CVE-2026-89675","ts":1789403733260,"field":"cvss","old":"9.8","new":"6.4"},{"seq":202990,"id":"CVE-2026-89675","ts":1789403733260,"field":"severity","old":"critical","new":"medium"},{"seq":197766,"id":"CVE-2026-89675","ts":1789384318758,"field":"cvss","old":"6.4","new":"9.8"},{"seq":197765,"id":"CVE-2026-89675","ts":1789384318758,"field":"severity","old":"medium","new":"critical"},{"seq":183689,"id":"CVE-2026-89675","ts":1789356676960,"field":"cvss","old":"9.8","new":"6.4"},{"seq":183688,"id":"CVE-2026-89675","ts":1789356676960,"field":"severity","old":"critical","new":"medium"},{"seq":153542,"id":"CVE-2026-89675","ts":1789285351214,"field":"cvss","old":null,"new":"9.8"},{"seq":153541,"id":"CVE-2026-89675","ts":1789285351214,"field":"severity","old":"none","new":"critical"},{"seq":147536,"id":"CVE-2026-89675","ts":1789270211293,"field":"cvss","old":null,"new":"6.4"},{"seq":147535,"id":"CVE-2026-89675","ts":1789270211293,"field":"severity","old":"none","new":"medium"},{"seq":109298,"id":"CVE-2026-89675","ts":1789183731330,"field":"cvss","old":null,"new":"6.4"},{"seq":109297,"id":"CVE-2026-89675","ts":1789183731330,"field":"severity","old":"none","new":"medium"}]}