CVE-2026-64142

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
19/07/2026
Last modified:
30/07/2026

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> ksmbd: close durable scavenger races against m_fp_list lookups<br /> <br /> ksmbd_durable_scavenger() has two related races against any walker<br /> that iterates f_ci-&gt;m_fp_list, including ksmbd_lookup_fd_inode()<br /> (used by ksmbd_vfs_rename) and the share-mode checks in<br /> fs/smb/server/smb_common.c.<br /> <br /> (1) fp-&gt;node list-head reuse. Durable-preserved handles can remain<br /> linked on f_ci-&gt;m_fp_list after session teardown so share-mode checks<br /> still see them while the handle is reconnectable. The scavenger<br /> collected expired handles by adding fp-&gt;node to a local<br /> scavenger_list after removing them from the global durable idr.<br /> Because fp-&gt;node is the same list_head used by m_fp_list,<br /> list_add(&amp;fp-&gt;node, &amp;scavenger_list) overwrites the m_fp_list links<br /> and corrupts both lists. CONFIG_DEBUG_LIST can report this on the<br /> share-mode walk path.<br /> <br /> (2) Refcount race against m_fp_list walkers. The scavenger qualifies<br /> an expired durable handle with atomic_read(&amp;fp-&gt;refcount) &gt; 1 and<br /> fp-&gt;conn under global_ft.lock, removes fp from global_ft, then drops<br /> global_ft.lock before unlinking fp from m_fp_list and freeing it.<br /> During that gap fp is still linked on m_fp_list with f_state ==<br /> FP_INITED. ksmbd_lookup_fd_inode() under m_lock read calls<br /> ksmbd_fp_get() (atomic_inc_not_zero on refcount that is still 1) and<br /> takes a live reference; the scavenger then unlinks and frees fp<br /> while the holder owns a reference, leading to UAF on the holder&amp;#39;s<br /> subsequent ksmbd_fd_put() and on any field reads performed by a<br /> concurrent share-mode walker that iterates m_fp_list without taking<br /> ksmbd_fp_get() (smb_check_perm_dleases-like paths).<br /> <br /> Fix both:<br /> <br /> * Stop reusing fp-&gt;node as a scavenger-private list node. Remove<br /> one expired handle from global_ft under global_ft.lock, take an<br /> explicit transient reference, drop the lock, unlink fp-&gt;node<br /> from m_fp_list under f_ci-&gt;m_lock, then drop both the durable<br /> lifetime and transient references with atomic_sub_and_test(2,<br /> &amp;fp-&gt;refcount). If the scavenger is the last putter the close<br /> runs there; otherwise an in-flight holder that already raced<br /> through the m_fp_list lookup owns the final close via its<br /> ksmbd_fd_put() path. The one-at-a-time disposal can rescan the<br /> durable idr when multiple handles expire in the same pass, but<br /> durable scavenging is a background expiration path and the final<br /> full scan recomputes min_timeout before the next wait.<br /> <br /> * Clear fp-&gt;persistent_id inside __ksmbd_remove_durable_fd() right<br /> after idr_remove(), so a delayed final close from a holder that<br /> snatched fp does not re-issue idr_remove() on a persistent id<br /> that idr_alloc_cyclic() in ksmbd_open_durable_fd() may have<br /> already handed out to a brand-new durable handle.<br /> <br /> * Bypass the per-conn open_files_count decrement in<br /> __put_fd_final() when fp is detached from any session table<br /> (fp-&gt;conn cleared by session_fd_check() at durable preserve --<br /> paired with the volatile_id clear at unpublish, so checking<br /> fp-&gt;conn alone is sufficient). The walker that owns the final<br /> close runs from an unrelated work-&gt;conn whose<br /> stats.open_files_count never tracked this durable fp; without<br /> this guard the holder would underflow that unrelated counter.<br /> <br /> The two races are folded into one patch because patch (1) alone<br /> cleans up the corrupted list but leaves a deterministic UAF window<br /> for m_fp_list walkers that the transient-reference and<br /> persistent_id discipline in (2) close; bisecting onto an<br /> intermediate state would land on a UAF that pre-patch chaos merely<br /> made less reproducible.<br /> <br /> Validation:<br /> * CONFIG_DEBUG_LIST coverage for the list_head reuse path.<br /> * KASAN-enabled direct SMB2 durable-handle coverage that exercised<br /> ksmbd_durable_scavenger() and non-NULL ksmbd_lookup_fd_inode()<br /> returns while durable handles expired under concurrent rename<br /> lookups, with no KASAN, UAF, list-corruption, ODEBUG, or WARNING<br /> reports.<br /> ---truncated---