Instituto Nacional de ciberseguridad. Sección Incibe
Instituto Nacional de Ciberseguridad. Sección INCIBE-CERT

Vulnerabilidad en kernel de Linux (CVE-2025-38170)

Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
03/07/2025
Última modificación:
03/07/2025

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: arm64/fpsimd: Descartar estado de CPU obsoleto al manejar trampas de SME La lógica para manejar trampas de SME manipula incorrectamente el estado FPSIMD/SVE/SME guardado, y una ejecución con preempción puede dar como resultado que una tarea tenga TIF_SME establecido y TIF_FOREIGN_FPSTATE borrado incluso si el estado de CPU en vivo está obsoleto (por ejemplo, con trampas de SME habilitadas). Esto puede dar como resultado advertencias de do_sme_acc() donde no se esperan trampas de SME mientras TIF_SME esté establecido: | /* Con TIF_SME, el espacio de usuario no debería generar ninguna trampa */ | if (test_and_set_thread_flag(TIF_SME)) | WARN_ON(1); Esto es muy similar al problema de SVE que corregimos en el commit: 751ecf6afd6568ad ("arm64/sve: descartar estado de CPU obsoleto al manejar trampas de SVE") La ejecución puede ocurrir cuando el controlador de trampas de SME se interrumpe antes y después de manipular el estado FPSIMD/SVE/SME guardado, comenzando y terminando en la misma CPU, por ejemplo, | void do_sme_acc(unsigned long esr, struct pt_regs *regs) | { | // Trampa en la CPU 0 con TIF_SME limpio, trampas de SME habilitadas | // task->fpsimd_cpu es 0. | // per_cpu_ptr(&fpsimd_last_state, 0) es la tarea. | | ... | | // Interrumpido; migrado de la CPU 0 a la CPU 1. | // TIF_FOREIGN_FPSTATE está configurado. | | get_cpu_fpsimd_context(); | | /* Con TIF_SME el espacio de usuario no debería generar ninguna trampa */ | if (test_and_set_thread_flag(TIF_SME)) | WARN_ON(1); | | if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) { | unsigned long vq_minus_one = | sve_vq_from_vl(task_get_sme_vl(current)) - 1; | sme_set_vq(vq_minus_one); | | fpsimd_bind_task_to_cpu(); | } | | put_cpu_fpsimd_context(); | | // Interrumpido; migrado de la CPU 1 a la CPU 0. | // task->fpsimd_cpu sigue siendo 0 | // Si per_cpu_ptr(&fpsimd_last_state, 0) sigue siendo tarea, entonces: | // - Se reutiliza el estado de hardware obsoleto (con las trampas de SME habilitadas) | // - Se borra TIF_FOREIGN_FPSTATE | // - Al regresar al espacio de usuario, se omite la restauración del estado de hardware | } Se soluciona el caso en el que el estado no está activo y TIF_FOREIGN_FPSTATE se establece llamando a fpsimd_flush_task_state() para separarlo del estado de CPU guardado. Esto garantiza que un cambio de contexto posterior no reutilice el estado de CPU obsoleto, sino que establezca TIF_FOREIGN_FPSTATE, forzando la recarga del nuevo estado desde la memoria antes de regresar al espacio de usuario. Nota: esto se publicó originalmente como [1]. [Rutland: reescribir el mensaje de confirmación]

Impacto