CVE-2026-98256 in Linuxinformação

Sumário

de VulDB • 06/10/2026

No kernel do Linux, a seguinte vulnerabilidade foi resolvida:

signal: Previne race condition no exec()

Hyunwoo depurou o seguinte erro KASAN UAF (Use-After-Free):

BUG: KASAN: slab-use-after-free em __send_signal_locked+0xb27/0xba0 Escrita de tamanho 8 no endereço ffff888007ed80c8 pela tarefa poc/79 ... Rastreamento da chamada (Call Trace): __send_signal_locked+0xb27/0xba0 do_send_sig_info+0xa7/0x160 do_send_specific+0x76/0xa0 __x64_sys_tgkill+0x193/0x270 ... Alocado pela tarefa 80: do_timer_create+0x1a4/0x1030 __x64_sys_timer_create+0x145/0x190 ... Liberado pela tarefa 12: kmem_cache_free_bulk+0x1f8/0x4a0 kvfree_rcu_bulk+0x14f/0x1c0 kfree_rcu_work+0x128/0x1a0 ... Última criação de trabalho potencialmente relacionada: kvfree_call_rcu+0x39/0x390 __flush_itimer_signals+0x211/0x320 flush_itimer_signals+0x47/0x90 begin_new_exec+0xa6b/0x28c0

Verificou-se que isso ocorre com um exec() não líder, conforme explicado por Hyunwoo:

de_thread() chama exchange_tids() antes de release_task(leader), então a struct pid mantida por um timer SIGEV_THREAD_ID criado contra o tid do líder agora aponta para a thread que chamou execve(). pid_task() retorna essa thread e lock_task_sighand() nela tem sucesso.

Se o sinal do timer estiver bloqueado, seu sigqueue permanece enfileirado no task::pending do líder. A próxima expiração desse timer pode então ocorrer enquanto release_task() esvazia a fila.

posixtimer_send_sigqueue() verifica se o sigqueue já está enfileirado com uma simples list_empty(), que apenas lê list_head::next. list_del_init() não é atômico e INIT_LIST_HEAD() armazena list_head::next antes de list_head::prev, então a verificação pode ser bem-sucedida no intervalo entre essas operações. list_add_tail() enfileira a entrada no task::pending da thread ativa, e o armazenamento em list_head::prev feito pelo flush sobrescreve o link list_head::prev que list_add_tail() acabou de definir.

__flush_itimer_signals() também não desfaz isso. Com list_head::prev apontando para a própria entrada, sua list_del_init() apenas armazena os mesmos valores novamente, então a entrada não é removida da lista. Ela ainda está presente após o último referencial ser descartado e o timer ser liberado por RCU, e o list_add_tail() de um tgkill posterior segue esse list_head::prev para dentro do timer já liberado.

Este problema surgiu com o commit recente que moveu a limpeza (flush) do sigqueue fora da região trancada pelo sighand lock.

Hyunwoo propôs corrigir isso usando list_del_init_careful(), mas isso apenas mascara o problema. Após algumas discussões e várias tentativas de resolvê-lo, Eric apontou que não há motivo para limpar task::pending tarde em release_task() e deveria ser feito já em exit_signals().

Como nada pode coletar e entregar sinais que estão enfileirados na fila pending de uma tarefa moribunda, não há motivo para adiar isso ainda mais.

Mas é necessário garantir que nenhum sinal possa ser enfileirado nela após esse ponto. exit_signals() define PF_EXITING em task::flags, o que pode ser usado como um indicador para isso.

Corrija-o por:

- Prevenir a enfileiramento de sinais para sinais privados da tarefa (PIDTYPE_PID) quando a tarefa tem PF_EXITING definido em __send_signal_locked() e em posixtimer_send_sigqueue().

- Proteger o ajuste sem lock do PF_EXITING em exit_signals() para o caso de grupo de tarefas vazio e saída do grupo com sighand lock.

- Limpar (flush) os sinais task::pending imediatamente ali.

Otimize isso movendo toda a lista pending para uma cabeça de lista na pilha sob sighand lock e libere os sinais sem manter o lock.

Houve bastante discussão sobre a limpeza sem lock e o caso exec não-líder em sistemas com ordenação fraca (weakly ordered). O problema é que um terceiro, ao tentar enviar um sinal posix timer, depende da pesquisa de PID para encontrar a tarefa alvo e essa pesquisa pode resultar no novo líder quando o sinal foi originalmente direcionado ao antigo líder. Caso o sinal tenha sido enfileirado no antigo líder, então a limpeza sem lock levantou uma preocupação sobre a seguinte situação:

old_leader new_leader third party

A: flush_list() // list_del_in ---truncado---

Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

Responsável

Linux

Reservar

25/09/2026

Divulgação

06/10/2026

Moderação

aceite

Entrada

VDB-414050

EPSS

0.00000

KEV

não

Atividades

muito baixo

Fontes

Interested in the pricing of exploits?

See the underground prices here!