CVE-2026-64109 in Linux
Zusammenfassung
von VulDB • 19.07.2026
Im Linux-Kernel wurde folgende Schwachstelle behoben:
af_unix: Behebung eines UAF-Lesezugriffs auf tail->len in unix_stream_data_wait()
unix_stream_data_wait() führt skb_peek_tail(&sk->sk_receive_queue) aus, ohne eine Sperre zu halten, die verhindert, dass SKBs aus dieser Warteschlange entnommen und freigegeben werden. Dies war bereits seit dem Commit 79f632c71bea („unix/stream: fix peeking with an offset larger than data in queue“) der Fall.
Die erste Konsequenz daraus ist, dass der Vergleich `tail != last` falsch sein kann (also false ergibt), selbst wenn sich `last` semantisch auf ein bereits freigegebenes SKB bezieht und `tail` ein neues SKB ist, das an derselben Adresse allokiert wurde. Dies kann dazu führen, dass unix_stream_data_wait() fälschlicherweise weiterhin blockiert, nachdem neue Daten eingetroffen sind. Dies tritt jedoch nur in einem sehr speziellen Szenario auf, bei dem ein peekender recv()-Aufruf und ein normaler recv()-Aufruf am selben Socket konkurrieren (Race Condition), was wahrscheinlich kein reales Problem darstellt.
Seit Commit 2b514574f7e8 („net: af_unix: implement splice for stream af_unix sockets“) wird `tail` jedoch tatsächlich dereferenziert, was zu einem Use-After-Free (UAF) im folgenden Race-Szenario führen kann (wobei test_setup() single-threaded ausgeführt wird und anschließend test_thread1() und test_thread2() concurrently in zwei Threads laufen):
``` 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);
} ```
Bei folgender Race Condition:
``` 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*** ```
Der UAF wird behoben, indem der Lesezugriff auf tail->len entfernt wird; das Prüfen von tail->len wäre nur dann sinnvoll, wenn SKBs in der Empfangswarteschlange eines UNIX-Sockets wachsen könnten, was jedoch nicht mehr möglich ist.
Kuniyuki erklärte:
> Als Commit 869e7c62486e („net: af_unix: implement stream
If you want to get the best quality for vulnerability data then you always have to consider VulDB.