vsock transport reassignment refcount UAF (CVE-2025-21756)¶
Transport reassignment'ın zaten unbound bir socket'i unbind ettiği bir Linux
af_vsockreference-counting kusuru;vsock_sock'u, bind table'da linkli kalırken erken free eder — root'a escalate edilebilir bir use-after-free.
Mechanism¶
Note
vsock, socket'leri bound/unbound listelerinde tutar ve o liste üyeliği bir reference
tutar. Kırılan invariant: gerçekte gerçekleşmeyen bir liste removal'ı için bir reference
düşürülür. Transport reassignment sırasında (örn. connect()'te),
vsock_remove_sock(), hiçbir zaman bound listede olmamış bir socket üzerinde
vsock_remove_bound()'u çağırabilir ve vsock_sock refcount'unu bir fazla decrement
edebilir. Object sonra bind table ve dangling handle üzerinden hâlâ erişilebilirken free
edilir — socket object'inin bir use-after-free'i. Bkz.
vsock-uaf ailesi.
Walkthrough¶
Üst düzey, açık hoefler.dev writeup'ından. Yalnızca kavramsal aşamalar — offset yok.
- Refcount dengesizliğini kışkırt. Transport reassignment'ı tetikleyen bind/connect
dizisini sür ki buglı unbind yolu çalışsın ve socket'in reference count'unu fazla
decrement etsin, bir userland handle kalırken
vsock_sock'u free etsin:
vsock_create() -> refcnt = 1; vsock_insert_unbound() -> +1
transport reassignment -> vsock_remove_sock() wrongly runs vsock_remove_bound() -> -1
later vsock_bind() -> assumes still-unbound, removes again -> object freed early
-
Reclaim the freed slot. Groom the SLUB cache and reclaim the freed object's memory with an attacker-controlled buffer of the same size class — the writeup uses pipe buffers — so the dangling socket now overlays controlled bytes. See heap-grooming-feng-shui.
-
Defeat KASLR via a benign side channel. Most operations on the recycled socket are blocked by AppArmor LSM hooks (they panic before anything useful happens). The writeup routes around this using
vsock_diag_dump()— not gated by those hooks — as an oracle to brute-force a kernel pointer and recover the kernel base. -
Hijack a function pointer. With the overlay controlled, overwrite a socket callback (the writeup targets
sk->sk_error_report) with a stack-pivot gadget, then drivevsock_release()→sk_prot->close()→ the error-report callback to pivot onto a ROP chain. -
Escalate to root. The chain calls
commit_creds(init_cred)(or equivalent) to give the process full privileges.
Why list membership matters
The object stays linked in the bind table after the early free, so the kernel will keep
walking and dereferencing a freed (then attacker-reclaimed) vsock_sock during normal
lookups — that is what converts a one-off over-decrement into a durable, triggerable UAF.
KASAN signature when the UAF is hit without grooming
Public n-day analysis (the "Attack of the Clones" writeup) reports a slab-use-after-free
surfacing on the second removal, in the vsock_remove_bound / vsock_remove_sock path:
Detection¶
- Unusual
AF_VSOCKuse from unprivileged/containerized processes. vsock is mainly a guest↔host channel; heavy bind/connect churn from ordinary userland is anomalous. vsock_diag(NETLINK_SOCK_DIAG) queries paired with vsock socket churn can indicate the KASLR-leak oracle being exercised.- SLUB/grooming signals: bursts of pipe-buffer allocations sized to the vsock cache, alongside vsock socket create/free storms.
- Crash/oops telemetry: UAF detectors (KASAN in test fleets) or oopses in
vsock_remove_bound/__vsock_bindpaths are strong indicators; production EDR should flag kernel oopses referencing vsock symbols. commit_creds/cred-change anomalies — an unprivileged task suddenly running as root with no setuid execve is a generic post-exploit tell.
Mitigation¶
- Patch: upstream commit "vsock: Keep the binding until socket destruction"
(
fcdd2242c0231032fc84e1404315c245ae56322a, merged for 6.14) preserves the binding for the socket's lifetime and removes it only on destruction, fixing the refcount imbalance. Apply the stable backports (5.10/5.15/6.1/6.6/6.12 and later point releases). - Reduce attack surface: blacklist/unload the
vsockandvmw_vsock_*modules where guest↔host sockets are not needed; restrictAF_VSOCKvia seccomp/LSM policy. - Hardening that raises cost: KASLR (forces the leak step), SMEP/SMAP/KPTI,
CONFIG_SLAB_FREELIST_RANDOM/ hardened freelist, and CFI (e.g.CONFIG_CFI_CLANG) break the function-pointer hijack and stack pivot. - Defense-in-depth: AppArmor/SELinux already blocked most operations on the recycled socket here; tightening LSM coverage of diagnostic interfaces narrows leak oracles.