← volver
CVE-2025-38352highbajo ataqueCWE-367

posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del()

76Vexday Risk Score

Prioriza la corrección. Ella está bajo explotación confirmada por CISA y tiene prueba de concepto pública.

ssvc Actcvss 7.8epss 1.3%
de la publicación al arma152 días
Publicada en NVD22 jul
1ª PoC+152d
CISA KEV+44d
probabilidad de explotación
1.3%top 33% de las CVE
explotación observada
CISA + VulnCheck
8 exploit(s) público(s)
Acción exigida por CISAplazo federal: 2025-09-25

Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.

Resumen

Race condition (CWE-362) no subsistema de temporizadores POSIX CPU do kernel Linux que pode degenerar em use-after-free (CWE-416) quando um processo em finalização, não autorreaping (ex.: sob ptrace ou aguardado por wait() controlado), é reaped pelo pai/debugger exatamente enquanto handle_posix_cpu_timers() ainda processa seus timers a partir de contexto IRQ. Importa porque há PoC pública funcional, exploração ativa registrada no catálogo KEV da CISA e o relato original veio do Google (Benoît Sevens), em contexto consistente com kernels Android da linha 5.10.x — mas a exploração exige ganhar uma corrida de timing fina (AC:H), não é trivial de disparar por acaso.

Detalle técnico

O código vive em kernel/time/posix-cpu-timers.c, nas funções run_posix_cpu_timers()/handle_posix_cpu_timers() e posix_cpu_timer_del(). O bug foi introduzido pelo commit 0bdd2ed4138e ('sched: run_posix_cpu_timers: Don't check ->exit_state, use lock_task_sighand()'), que removeu uma checagem de exit_state e passou a confiar apenas em lock_task_sighand() para serializar acesso à task.

A janela de corrida existe porque uma task exiting não-autorreaping pode já ter passado por exit_notify() e ainda assim ser chamada via handle_posix_cpu_timers() a partir de uma interrupção de timer. Depois que essa função executa unlock_task_sighand(), existe um intervalo em que o pai ou um debugger pode reap a task (release_task()) antes que o processamento do timer termine. Se, nesse intervalo, uma chamada concorrente a posix_cpu_timer_del() tentar remover o mesmo cpu timer, as funções auxiliares cpu_timer_task_rcu() e/ou lock_task_sighand() falham em localizar a task já liberada — e por isso não detectam que timer->it.cpu.firing != 0, ou seja, que o timer ainda está em uso por handle_posix_cpu_timers(). O delete prossegue como se fosse seguro, e a estrutura associada ao timer/sighand pode ser acessada depois de liberada.

A correção adiciona uma checagem explícita de tsk->exit_state no início de run_posix_cpu_timers(): se a task já está em processo de saída, a função retorna sem prosseguir, eliminando a janela em que release_task() poderia correr concorrentemente com o processamento do timer. O próprio patch observa que essa correção não é necessária quando CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, porque nesse modo exit_task_work() é executado antes de exit_notify(), o que já impede a ordem de eventos que gera a corrida — mas o autor manteve a checagem como defesa em profundidade, já que task_work_add() falharia de qualquer forma nesse caso.

Investigado y redactado con IA a partir del advisory del fabricante y análisis públicos, con las fuentes citadas. Verifica siempre la versión corregida en el advisory oficial antes de actuar.
In the Linux kernel, the following vulnerability has been resolved: posix-cpu-timers: fix race between handle_posix_cpu_timers() and posix_cpu_timer_del() If an exiting non-autoreaping task has already passed exit_notify() and calls handle_posix_cpu_timers() from IRQ, it can be reaped by its parent or debugger right after unlock_task_sighand(). If a concurrent posix_cpu_timer_del() runs at that moment, it won't be able to detect timer->it.cpu.firing != 0: cpu_timer_task_rcu() and/or lock_task_sighand() will fail. Add the tsk->exit_state check into run_posix_cpu_timers() to fix this. This fix is not needed if CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, because exit_task_work() is called before exit_notify(). But the check still makes sense, task_work_add(&tsk->posix_cputimers_work.work) will fail anyway in this case.
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Productos afectados
Linux · Linux
⚠ Recursos públicos, para evaluar la exposición de sistemas que controlas o estás autorizado a probar. Prueba solo con autorización.