CVE-2026-98256
signal: Prevenir la condición de carrera en exec()
- Publicado
- 6 oct 2026
- Actualizado
- 19 oct 2026
- Asignación de CNA
- Linux
- Evidencia observada
- 4 nov 2026
CVSS primario
nvd · CVSS 3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HBajo · próximos 30 días
- Percentil
- 3,7 %
- Fecha del modelo
- 4 nov 2026
EPSS es una estimación estadística, no una certeza o una medida de impacto. Combínelo con CVSS, estado KEV, exposición y su entorno.
Resumen
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: signal: Prevenir la condición de carrera en exec() Hyunwoo depuró el siguiente volcado 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 Resultó que esto ocurre con un exec() no líder, como explicó Hyunwoo: de_thread() llama a exchange_tids() antes de release_task(leader), por lo que el struct pid retenido por un temporizador SIGEV_THREAD_ID creado contra el tid del líder ahora apunta al hilo que llamó a execve(). pid_task() devuelve ese hilo y lock_task_sighand() sobre él tiene éxito. Si la señal del temporizador está bloqueada, su sigqueue permanece en cola en task::pending del líder. La siguiente expiración de ese temporizador puede entonces ejecutarse mientras release_task() vacía la cola. posixtimer_send_sigqueue() comprueba si el sigqueue ya está en cola con un list_empty() simple, que solo lee list_head::next. list_del_init() no es atómico e INIT_LIST_HEAD() almacena list_head::next antes que list_head::prev, por lo que la comprobación puede pasar en medio. list_add_tail() encola la entrada en task::pending del hilo vivo, y el almacenamiento de list_head::prev del vaciado sobrescribe entonces el enlace list_head::prev que list_add_tail() acaba de establecer. __flush_itimer_signals() tampoco deshace eso. Con list_head::prev apuntando a la propia entrada, su list_del_init() solo almacena los mismos valores de nuevo, por lo que la entrada no se elimina de la lista. Sigue ahí después de que se suelte la última referencia y el temporizador sea liberado por RCU, y el list_add_tail() de un tgkill() posterior sigue ese list_head::prev hacia el temporizador liberado. Este problema surgió con el commit reciente que movió el vaciado del sigqueue fuera de la región protegida por el lock de sighand. Hyonwoo propuso corregir esto usando list_del_init_careful(), pero eso solo tapa el problema. Tras algunas discusiones y varios intentos de resolverlo, Eric señaló que no hay razón para vaciar task::pending tarde en release_task() y que ya debería hacerse en exit_signals(). Como nada puede recoger y entregar las señales que están en cola en la cola pendiente de una tarea moribunda, no hay razón para retrasarlo más. Pero hay que asegurarse de que no se puedan encolar señales en ella después de ese punto. exit_signals() establece PF_EXITING en task::flags, lo que puede usarse como indicador para esto. Se corrige mediante: - Impedir el encolado de señales para señales privadas de la tarea (PIDTYPE_PID) cuando la tarea tiene PF_EXITING establecido en __send_signal_locked() y en posixtimer_send_sigqueue(). - Proteger el establecimiento sin lock de PF_EXITING en exit_signals() para el caso de grupo de tareas vacío y el caso de salida del grupo con el lock de sighand - Vaciar las señales de task::pending justo ahí. Optimizar eso moviendo toda la lista pendiente a una cabeza de lista en la pila bajo el lock de sighand y liberar las señales sin el lock retenido. Ha habido bastante discusión sobre el vaciado sin lock y el caso de exec() no líder en sistemas con ordenamiento débil. El problema es que un tercero que intenta enviar una señal de temporizador posix depende de la búsqueda de PID para encontrar la tarea objetivo y esa búsqueda podría dar como resultado el nuevo líder cuando la señal estaba originalmente dirigida al antiguo líder. En caso de que la señal se encolara en el antiguo líder, entonces el vaciado sin lock suscitó una preocupación sobre la siguiente situación: old_leader new_leader third party A: flush_list() // list_del_in ---truncado---
Uso responsable
Utilice información sobre vulnerabilidades solo en sistemas de su propiedad o que esté autorizado a probar. Kitploit enlaza con metadatos de investigación pública y no almacena código de explotación ni cargas útiles maliciosas.