CVE-2026-98256
signal: Prevenir corrida em exec()
- Publicado
- 6 de out. de 2026
- Atualizado
- 19 de out. de 2026
- Atribuindo CNA
- Linux
- Evidência observada
- 4 de nov. de 2026
CVSS primário
nvd · CVSS 3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HBaixo · próximos 30 dias
- Percentil
- 3,7%
- Data do modelo
- 4 de nov. de 2026
EPSS é uma estimativa estatística, não uma certeza ou uma medida de impacto. Combine-o com CVSS, status KEV, exposição e seu ambiente.
Resumo
No kernel Linux, a seguinte vulnerabilidade foi resolvida: signal: Prevenir corrida em exec() Hyunwoo depurou o seguinte splat de KASAN UAF: BUG: KASAN: slab-use-after-free in __send_signal_locked+0xb27/0xba0 Write of size 8 at addr ffff888007ed80c8 by task poc/79 ... Call Trace: __send_signal_locked+0xb27/0xba0 do_send_sig_info+0xa7/0x160 do_send_specific+0x76/0xa0 __x64_sys_tgkill+0x193/0x270 ... Allocated by task 80: do_timer_create+0x1a4/0x1030 __x64_sys_timer_create+0x145/0x190 ... Freed by task 12: kmem_cache_free_bulk+0x1f8/0x4a0 kvfree_rcu_bulk+0x14f/0x1c0 kfree_rcu_work+0x128/0x1a0 ... Last potentially related work creation: kvfree_call_rcu+0x39/0x390 __flush_itimer_signals+0x211/0x320 flush_itimer_signals+0x47/0x90 begin_new_exec+0xa6b/0x28c0 Descobriu-se que isso acontece com um exec() não-líder, como Hyunwoo explicou: de_thread() chama exchange_tids() antes de release_task(leader), então o struct pid mantido 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 é bem-sucedido. 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 ser executada enquanto release_task() esvazia a fila. posixtimer_send_sigqueue() verifica se o sigqueue já está enfileirado com um list_empty() simples, 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 passar no meio. list_add_tail() enfileira a entrada no task::pending da thread viva, e o armazenamento de list_head::prev do esvaziamento então 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, seu list_del_init() apenas armazena os mesmos valores novamente, então a entrada não é removida da lista. Ela ainda está lá depois que a última referência é descartada e o timer é liberado pelo RCU, e o list_add_tail() de um tgkill() posterior segue esse list_head::prev até o timer liberado. Esse problema surgiu com o commit recente que moveu o esvaziamento do sigqueue para fora da região protegida pelo lock do sighand. Hyonwoo 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á razão para esvaziar task::pending tardiamente em release_task() e isso já deveria ser feito em exit_signals(). Como nada pode coletar e entregar sinais que estão enfileirados na fila pendente de uma tarefa moribunda, não há razão para adiar isso ainda mais. Mas é preciso 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 indicador para isso. Corrija isso ao: - Impedir o 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 a definição sem lock de PF_EXITING em exit_signals() para o caso de grupo de tarefas vazio e de saída do grupo com o lock do sighand - Esvaziar os sinais de task::pending ali mesmo. Otimize isso movendo toda a lista pendente para um cabeçalho de lista na pilha sob o lock do sighand e libere os sinais sem o lock mantido. Houve bastante discussão sobre o esvaziamento sem lock e o caso de exec() não-líder em sistemas com ordenação fraca. O problema é que um terceiro que tenta enviar um sinal de timer posix depende da busca por PID para encontrar a tarefa alvo e essa busca pode resultar no novo líder quando o sinal foi originalmente direcionado ao antigo líder. No caso de o sinal ter sido enfileirado no antigo líder, então o esvaziamento sem lock levantou uma preocupação sobre a seguinte situação: old_leader new_leader third party A: flush_list() // list_del_in ---truncated---
Uso responsável
Use informações de vulnerabilidade apenas em sistemas que você possui ou está autorizado a testar. O Kitploit vincula-se a metadados de pesquisa pública e não armazena código de exploração ou cargas maliciosas.