CVE-2026-64109 in Linux
Sumário
de VulDB • 20/07/2026
No kernel do Linux, a seguinte vulnerabilidade foi resolvida:
af_unix: Corrige leitura UAF de tail->len em unix_stream_data_wait()
unix_stream_data_wait() executa skb_peek_tail(&sk->sk_receive_queue) sem segurar nenhum lock que impeça o dequeue e liberação dos SKBs nessa fila. Esse era o caso desde o commit 79f632c71bea ("unix/stream: fix peeking with an offset larger than data in queue"). A primeira consequência disso é que a comparação de ponteiros `tail != last` pode ser falsa mesmo se `last` semanticamente se referir a um SKB já liberado, enquanto `tail` for um novo SKB alocado no mesmo endereço; o que pode fazer com que unix_stream_data_wait() bloqueie erroneamente após a chegada de novos dados, mas apenas em um cenário estranho onde uma recv() com peek e uma recv() normal no mesmo socket estão concorrendo (race condition), o que provavelmente não é um problema real.
Mas desde o commit 2b514574f7e8 ("net: af_unix: implement splice for stream af_unix sockets"), `tail` é efetivamente desreferenciado, o que pode causar UAF no seguinte cenário de race condition (onde test_setup() executa em thread única e, posteriormente, test_thread1() e test_thread2() executam concorrentemente em dois 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);
} ```
quando concorrendo desta forma: ``` 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) [libera o SKB]
`tail != last`: false `tail`: true `tail->len != last_len` ***UAF*** ```
Corrige-se o UAF removendo a leitura de tail->len; verificar tail->len só faria sentido se os SKBs na fila de recebimento de um socket UNIX pudessem crescer, o que já não pode acontecer.
Kuniyuki explicou:
> Quando o commit 869e7c62486e ("net: af_unix: implement stream sendpage support") adicionou suporte a sendpage(), os dados podiam ser anexados ao último skb na fila do receptor. > > É por isso que precisávamos verificar se o comprimento do último skb havia mudado enquanto aguardava novos dados
If you want to get best quality of vulnerability data, you may have to visit VulDB.