Description
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.
Published: 2026-07-19
Score: 8.8 High
EPSS: < 1% Very Low
KEV: No
Impact: n/a
Action: n/a
AI Analysis

Impact

A race condition between simultaneous recv calls on an AF_UNIX stream socket in earlier Linux kernel releases can cause unix_stream_data_wait() to dereference a freed socket buffer. The function performs skb_peek_tail without holding the lock protecting the receive queue, and then accesses the freed object's len field. This use‑after‑free triggers kernel memory corruption, which can lead to a system crash and denial of service. The CVE does not state that the flaw leaks data or enables arbitrary code execution.

Affected Systems

All Linux kernel implementations older than version 6.5 are impacted, including the widely deployed 5.x series and custom kernels that have not been upgraded to the 6.5 release. The flaw resides in the generic AF_UNIX stream socket handling path, so any system that employs this IPC mechanism with an older kernel is vulnerable.

Risk and Exploitability

The CVSS score of 8.8 classifies this as a high‑severity issue, while the EPSS score of less than 1% indicates that exploitation is unlikely at the moment. This flaw does not appear in CISA’s KEV catalog. Exploitation requires an attacker who can create or control an AF_UNIX socket pair and orchestrate a precise timing race between a peeked and a normal receive operation; such conditions make reliable exploitation challenging. If an attacker succeeds, the kernel memory corruption can cause a crash and denial of service. No evidence is provided that the flaw enables privilege escalation.

Generated by OpenCVE AI on August 4, 2026 at 06:06 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Upgrade the Linux kernel to version 6.5 or newer, which removes the vulnerable UAF logic.
  • If an immediate kernel upgrade is not possible, apply the upstream patch that eliminates the tail->len read in unix_stream_data_wait(), a fix for a race‑condition induced use‑after‑free (CWE‑366).
  • As a temporary safeguard, restrict or disable AF_UNIX socket usage on the affected kernel, or enforce strict permission checks to mitigate the race condition (CWE‑366).

Generated by OpenCVE AI on August 4, 2026 at 06:06 UTC.

Tracking

Sign in to view the affected projects.

Advisories
Source ID Title
Ubuntu USN Ubuntu USN USN-8593-1 Linux kernel vulnerabilities
Ubuntu USN Ubuntu USN USN-8603-1 Linux kernel (Azure) vulnerabilities
Ubuntu USN Ubuntu USN USN-8618-1 Linux kernel vulnerabilities
History

Mon, 20 Jul 2026 14:45:00 +0000

Type Values Removed Values Added
Metrics cvssV3_1

{'score': 7.0, 'vector': 'CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H'}

cvssV3_1

{'score': 8.8, 'vector': 'CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H'}


Mon, 20 Jul 2026 12:15:00 +0000

Type Values Removed Values Added
Weaknesses CWE-366
References
Metrics threat_severity

None

cvssV3_1

{'score': 7.0, 'vector': 'CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H'}

threat_severity

Moderate


Sun, 19 Jul 2026 16:15:00 +0000

Type Values Removed Values Added
Description 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.
Title af_unix: Fix UAF read of tail->len in unix_stream_data_wait()
First Time appeared Linux
Linux linux Kernel
CPEs cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Vendors & Products Linux
Linux linux Kernel
References

Subscriptions

Linux Linux Kernel
cve-icon MITRE

Status: PUBLISHED

Assigner: Linux

Published:

Updated: 2026-08-05T12:39:18.983Z

Reserved: 2026-07-19T07:54:57.034Z

Link: CVE-2026-64109

cve-icon Vulnrichment

No data.

cve-icon NVD

No data.

cve-icon Redhat

Severity : Moderate

Publid Date: 2026-07-19T00:00:00Z

Links: CVE-2026-64109 - Bugzilla

cve-icon OpenCVE Enrichment

Updated: 2026-08-04T06:15:04Z

Weaknesses
  • CWE-366

    Race Condition within a Thread