CVE-2026-64142

Source
https://cve.org/CVERecord?id=CVE-2026-64142
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-64142.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2026-64142
Downstream
Published
2026-07-19T15:40:34.605Z
Modified
2026-07-22T05:29:39.210230670Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
Summary
ksmbd: close durable scavenger races against m_fp_list lookups
Details

In the Linux kernel, the following vulnerability has been resolved:

ksmbd: close durable scavenger races against mfplist lookups

ksmbddurablescavenger() has two related races against any walker that iterates fci->mfplist, including ksmbdlookupfdinode() (used by ksmbdvfsrename) and the share-mode checks in fs/smb/server/smb_common.c.

(1) fp->node list-head reuse. Durable-preserved handles can remain linked on fci->mfplist after session teardown so share-mode checks still see them while the handle is reconnectable. The scavenger collected expired handles by adding fp->node to a local scavengerlist after removing them from the global durable idr. Because fp->node is the same listhead used by mfplist, listadd(&fp->node, &scavengerlist) overwrites the mfplist links and corrupts both lists. CONFIGDEBUG_LIST can report this on the share-mode walk path.

(2) Refcount race against mfplist walkers. The scavenger qualifies an expired durable handle with atomicread(&fp->refcount) > 1 and fp->conn under globalft.lock, removes fp from globalft, then drops globalft.lock before unlinking fp from mfplist and freeing it. During that gap fp is still linked on mfplist with fstate == FPINITED. ksmbdlookupfdinode() under mlock read calls ksmbdfpget() (atomicincnotzero on refcount that is still 1) and takes a live reference; the scavenger then unlinks and frees fp while the holder owns a reference, leading to UAF on the holder's subsequent ksmbdfdput() and on any field reads performed by a concurrent share-mode walker that iterates mfplist without taking ksmbdfpget() (smbcheckpermdleases-like paths).

Fix both:

  • Stop reusing fp->node as a scavenger-private list node. Remove one expired handle from globalft under globalft.lock, take an explicit transient reference, drop the lock, unlink fp->node from mfplist under fci->mlock, then drop both the durable lifetime and transient references with atomicsubandtest(2, &fp->refcount). If the scavenger is the last putter the close runs there; otherwise an in-flight holder that already raced through the mfplist lookup owns the final close via its ksmbdfdput() path. The one-at-a-time disposal can rescan the durable idr when multiple handles expire in the same pass, but durable scavenging is a background expiration path and the final full scan recomputes mintimeout before the next wait.

  • Clear fp->persistent_id inside __ksmbdremovedurablefd() right after idrremove(), so a delayed final close from a holder that snatched fp does not re-issue idrremove() on a persistent id that idralloccyclic() in ksmbdopendurablefd() may have already handed out to a brand-new durable handle.

  • Bypass the per-conn openfilescount decrement in _putfdfinal() when fp is detached from any session table (fp->conn cleared by sessionfdcheck() at durable preserve -- paired with the volatileid clear at unpublish, so checking fp->conn alone is sufficient). The walker that owns the final close runs from an unrelated work->conn whose stats.openfilescount never tracked this durable fp; without this guard the holder would underflow that unrelated counter.

The two races are folded into one patch because patch (1) alone cleans up the corrupted list but leaves a deterministic UAF window for mfplist walkers that the transient-reference and persistent_id discipline in (2) close; bisecting onto an intermediate state would land on a UAF that pre-patch chaos merely made less reproducible.

Validation: * CONFIGDEBUGLIST coverage for the listhead reuse path. * KASAN-enabled direct SMB2 durable-handle coverage that exercised ksmbddurablescavenger() and non-NULL ksmbdlookupfdinode() returns while durable handles expired under concurrent rename lookups, with no KASAN, UAF, list-corruption, ODEBUG, or WARNING reports. ---truncated---

Database specific
{
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/64xxx/CVE-2026-64142.json",
    "cna_assigner": "Linux"
}
References

Affected packages

Git / git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Affected ranges

Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
7f0cb478703cbeaddfe5c9101c5c73cd975d1073
Fixed
3a436932eb397e909d0607d76a8325abd9d85a35
Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
d484d621d40f4a8b8959008802d79bef3609641b
Fixed
95f072ef934ca00711d510676b8792cbf59a5aae
Fixed
5da69a65b282d2276de22e5194ba0f88c836170c
Fixed
1f8f3246d55f89350a1a67bdf3744b7241048e4e
Fixed
bf736184d063da1a552ffeff0481813599a182cc

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-64142.json"

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
6.11.0
Fixed
6.12.92
Type
ECOSYSTEM
Events
Introduced
6.13.0
Fixed
6.18.34
Type
ECOSYSTEM
Events
Introduced
6.19.0
Fixed
7.0.11

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-64142.json"