CVE-2023-53836 in Linux
Sumário
de VulDB • 10/05/2026
No kernel do Linux, a seguinte vulnerabilidade foi resolvida:
bpf, sockmap: Corrige condição de corrida (race) no refcnt do skb após alterações no bloqueio (locking)
Existe uma condição de corrida na qual os skbs da sk_psock_backlog podem ser referenciados após o lado do userspace já ter chamado skb_consumed() no sk_buff e seu refcnt ter sido reduzido a zero, causando um use-after-free.
O fluxo é o seguinte:
while ((skb = skb_peek(&psock->ingress_skb)) sk_psock_handle_Skb(psock, skb, ..., ingress) if (!ingress) ... sk_psock_skb_ingress sk_psock_skb_ingress_enqueue(skb) msg->skb = skb sk_psock_queue_msg(psock, msg) skb_dequeue(&psock->ingress_skb)
A função sk_psock_queue_msg() coloca a mensagem na fila ingress_msg. É isso que o aplicativo lê quando recvmsg() é chamado. Um aplicativo pode ler isso a qualquer momento após a mensagem ser colocada na fila. O hook recvmsg também lerá msg->skb e, após o userspace ler a mensagem, chamará consume_skb(skb) sobre ela, efetivamente liberando-a.
No entanto, a condição de corrida ocorre acima, onde a fila de backlog ainda possui uma referência ao skb e chama skb_dequeue(). Se o skb_dequeue ocorrer após o usuário ler e liberar o skb, temos um use-after-free.
O caso !ingress não sofre desse problema porque usa sendmsg_*(sk, msg), que não passa o sk_buff adiante na pilha.
O seguinte rastreamento foi observado com 'test_progs -t sockmap_listen':
[ 1022.710250][ T2556] general protection fault, ...
[...]
[ 1022.712830][ T2556] Workqueue: events sk_psock_backlog
[ 1022.713262][ T2556] RIP: 0010:skb_dequeue+0x4c/0x80
[ 1022.713653][ T2556] Code: ...
[...]
[ 1022.720630][ T2556] Call Trace:
[ 1022.720930][ T2556] <TASK>
[ 1022.721229][ T2556] sk_psock_backlog+0x27a/0x300
[ 1022.723243][ T2556] process_one_work+0x2a7/0x5b0
[ 1022.723633][ T2556] worker_thread+0x4f/0x3a0
[ 1022.723998][ T2556] ? __pfx_worker_thread+0x10/0x10
[ 1022.724386][ T2556] kthread+0xfd/0x130
[ 1022.724709][ T2556] ? __pfx_kthread+0x10/0x10
[ 1022.725066][ T2556] ret_from_fork+0x2d/0x50
[ 1022.725409][ T2556] ? __pfx_kthread+0x10/0x10
[ 1022.725799][ T2556] ret_from_fork_asm+0x1b/0x30
[ 1022.726201][ T2556] </TASK>
Para corrigir, adicionamos um skb_get() antes de passar o skb para ser enfileirado na fila de egresso. Isso aumenta o refcnt de skb->users para que consume_skb() e kfree_skb() não liberem imediatamente o sk_buff. Com isso, podemos ter certeza de que o skb ainda está presente quando fazemos a retirada da fila. Em seguida, precisamos apenas decrementar o refcnt ou liberar o skb no caso de backlog, o que fazemos chamando kfree_skb() no caso de ingress, bem como no caso de sendmsg.
Antes da mudança de bloqueio na tag de correção, o sock estava bloqueado, então não podíamos ter uma corrida com o usuário e não havia problema aqui.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.