Skip to main content

Linux Kernel CVE-2026-64109

| EUVDEUVD-2026-45794 HIGH
Use After Free (CWE-416)
2026-07-19 Linux GHSA-mh36-g5h5-fxqc
8.8
CVSS 3.1 · Vendor: Linux
Share

Severity by source

Vendor (Linux) PRIMARY
8.8 HIGH
AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
vuln.today AI
5.3 MEDIUM

Local low-priv trigger (AV:L/PR:L), race condition forces AC:H; read-only UAF yields limited info leak (C:L) with the dominant impact being a kernel crash/DoS (A:H).

3.1 AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:H
4.0 AV:L/AC:H/AT:N/PR:L/UI:N/VC:L/VI:N/VA:H/SC:N/SI:N/SA:N
SUSE
HIGH
qualitative
Red Hat
7.0 MEDIUM
qualitative

Primary rating from Vendor (Linux).

CVSS VectorVendor: Linux

Attack Vector
Local
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

5
Analysis Generated
Jul 20, 2026 - 17:29 vuln.today
CVSS changed
Jul 20, 2026 - 15:22 NVD
8.8 (HIGH)
Patch available
Jul 19, 2026 - 17:03 EUVD
CVE Published
Jul 19, 2026 - 15:40 cve.org
UNKNOWN (no severity yet)
CVE Published
Jul 19, 2026 - 15:40 cve.org
HIGH 8.8

DescriptionCVE.org

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

af_unix: Fix UAF read of tail->len in unix_stream_data_wait()

unix_stream_data_wait() does skb_peek_tail(&sk->sk_receive_queue) without holding any lock that prevents SKBs on that queue from being dequeued and freed. This has been the case since commit 79f632c71bea ("unix/stream: fix peeking with an offset larger than data in queue"). The first consequence of this is that the pointer comparison tail != last can be false even if last semantically refers to an already-freed SKB while tail is a new SKB allocated at the same address; which can cause unix_stream_data_wait() to wrongly keep blocking after new data has arrived, but only in a weird scenario where a peeking recv() and a normal recv() on the same socket are racing, which is probably not a real problem.

But since commit 2b514574f7e8 ("net: af_unix: implement splice for stream af_unix sockets"), tail is actually dereferenced, which can cause UAF in the following race scenario (where test_setup() runs single-threaded, and afterwards, test_thread1() and test_thread2() run concurrently in two threads:

static int socks[2];
void test_setup(void) {
  socketpair(AF_UNIX, SOCK_STREAM, 0, socks);
  send(socks[1], "A", 1, 0);
  int peekoff = 1;
  setsockopt(socks[0], SOL_SOCKET, SO_PEEK_OFF, &peekoff, sizeof(peekoff));
}
void test_thread1(void) {
  char dummy;
  recv(socks[0], &dummy, 1, MSG_PEEK);
}
void test_thread2(void) {
  char dummy;
  recv(socks[0], &dummy, 1, 0);
  shutdown(socks[1], SHUT_WR);
}

when racing like this:

thread1                       thread2
unix_stream_read_generic
  mutex_lock(&u->iolock)
  skb_peek(&sk->sk_receive_queue)
  skb_peek_next(skb, &sk->sk_receive_queue)
  mutex_unlock(&u->iolock)
                              unix_stream_read_generic
                                unix_state_lock(sk)
                                skb_peek(&sk->sk_receive_queue)
                                unix_state_unlock(sk)
  unix_stream_data_wait
    unix_state_lock(sk)
    tail = skb_peek_tail(&sk->sk_receive_queue)
                                spin_lock(&sk->sk_receive_queue.lock)
                                __skb_unlink(skb, &sk->sk_receive_queue)
                                spin_unlock(&sk->sk_receive_queue.lock)
                                consume_skb(skb) [frees the SKB]
    `tail != last`: false
    `tail`: true
    `tail->len != last_len` ***UAF***

Fix the UAF by removing the read of tail->len; checking tail->len would only make sense if SKBs in the receive queue of a UNIX socket could grow, which can no longer happen.

Kuniyuki explained:

> When commit 869e7c62486e ("net: af_unix: implement stream sendpage > support") added sendpage() support, data could be appended to the last > skb in the receiver's queue. > > That's why we needed to check if the length of the last skb was changed > while waiting for new data in unix_stream_data_wait(). > > However, commit a0dbf5f818f9 ("af_unix: Support MSG_SPLICE_PAGES") and > commit 57d44a354a43 ("unix: Convert unix_stream_sendpage() to use > MSG_SPLICE_PAGES") refactored sendmsg(), and now data is always added > to a new skb.

That means this fix is not suitable for kernels before 6.5.

AnalysisAI

Use-after-free read in the Linux kernel's AF_UNIX stream socket handler (unix_stream_data_wait()) lets a local user leak or corrupt kernel memory state and potentially crash the system by racing a peeking recv() against a normal recv() on the same socket. The flaw affects kernels from ~6.5 onward, where unix_stream_data_wait() dereferences tail->len from an SKB read via skb_peek_tail() without a lock preventing that SKB from being concurrently dequeued and freed. EPSS is low (0.17%, 6th percentile) and there is no public exploit identified at time of analysis, though the fix commit includes a race reproducer; the issue is fixed in stable releases.

Technical ContextAI

The vulnerability lives in the AF_UNIX stream socket receive path of the Linux networking stack (net/unix/af_unix.c). unix_stream_data_wait() calls skb_peek_tail(&sk->sk_receive_queue) to obtain the tail socket buffer (SKB) but does not hold sk_receive_queue.lock, so another thread executing unix_stream_read_generic() can __skb_unlink() and consume_skb() that same SKB concurrently. This is a classic use-after-free (CWE-416, though the input lists CWE as N/A) triggered by insufficient locking around a shared queue. The historical need to read tail->len came from commit 869e7c62486e (stream sendpage support), which allowed data to be appended to the last SKB; commits a0dbf5f818f9 (MSG_SPLICE_PAGES) and 57d44a354a43 removed that behavior so data now always lands in a new SKB, making the length re-check both unnecessary and dangerous. The dereference bug was introduced by commit 2b514574f7e8 (splice for stream AF_UNIX sockets), which is why the fix does not apply to kernels before 6.5. CPE data identifies the affected component simply as cpe:2.3:a:linux:linux.

RemediationAI

Vendor-released patch: upgrade to a fixed Linux stable release - 6.6.143, 6.12.92, 6.18.34, 7.0.11, or 7.1 (or later) matching your branch - and reboot into the patched kernel, since this is a core net/unix change with no runtime toggle. The fix simply removes the read of tail->len in unix_stream_data_wait(); apply your distribution's kernel update once it ships the corresponding commit (26342087fac9 / 38bccb927d83 / acdff9907478 / 5f162f95a958 / be309f8eae8b, see https://git.kernel.org/stable/c/). No standalone configuration workaround fully neutralizes the flaw because it is inherent to AF_UNIX stream/splice receive handling; as a compensating control on unpatched multi-tenant hosts, restrict the ability to run untrusted local code and consider containment (per-tenant VMs or seccomp/namespace restrictions on untrusted workloads) to reduce who can trigger the race - with the trade-off that AF_UNIX stream sockets are ubiquitous and cannot practically be disabled. Prioritize patching over mitigation.

Vendor StatusVendor

SUSE

Severity: Important
Product Status
SUSE Linux Enterprise Desktop 15 SP7 Affected
SUSE Linux Enterprise Desktop 15 SP7 Affected
SUSE Linux Enterprise High Availability Extension 15 SP7 Affected
SUSE Linux Enterprise High Availability Extension 15 SP7 Affected
SUSE Linux Enterprise High Availability Extension 16.0 Affected

Share

CVE-2026-64109 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy