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

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

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

Descripción

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: fbdev: hyperv_fb: Se corrige el bloqueo del kernel kdump en máquinas virtuales Hyper-V Gen 2. Las máquinas virtuales Hyper-V Gen 2 arrancan mediante EFI y tienen un dispositivo de búfer de trama EFI estándar. Cuando el kernel kdump se ejecuta en una máquina virtual de este tipo, la carga del controlador efifb puede bloquearse debido al acceso al búfer de trama en la dirección de memoria incorrecta. Esto ocurre cuando el controlador hyperv_fb del kernel original mueve el búfer de trama a una dirección MMIO diferente debido a conflictos con un controlador efifb o simplefb ya en ejecución. El controlador hyperv_fb informa a Hyper-V del cambio, permitido por el protocolo de dispositivo VMBus de Hyper-V FB. Sin embargo, cuando el comando kexec carga el kernel kdump en la memoria de fallos mediante la llamada al sistema kexec_file_load(), esta desconoce el desplazamiento del framebuffer y configura el screen_info de kdump con la dirección original del framebuffer. La transición al kernel kdump no pasa por el host de Hyper-V, por lo que Hyper-V no restablece la dirección del framebuffer como lo haría al reiniciar. Cuando efifb intenta ejecutarse, accede a una dirección de framebuffer inexistente, lo que redirige al host de Hyper-V. Tras varios accesos de este tipo, el host de Hyper-V considera que el invitado es malicioso y lo limita hasta el punto de que se ejecuta muy lentamente o parece haberse colgado. Cuando el kernel kdump se carga en la memoria de fallos mediante la llamada al sistema kexec_load(), el problema no se produce. En este caso, el comando kexec crea la tabla screen_info en el espacio de usuario a partir de los datos devueltos por el comando ioctl FBIOGET_FSCREENINFO contra /dev/fb0, lo que le asigna la nueva ubicación del framebuffer. Este problema se reportó originalmente en 2020 [1], lo que resultó en el commit 3cb73bc3fa2a ("hyperv_fb: Actualizar screen_info tras eliminar el framebuffer antiguo"). Esta confirmación solucionó el problema estableciendo orig_video_isVGA a 0, por lo que el kernel de kdump desconocía el framebuffer EFI. El controlador efifb no intentó cargarse y no se produjo ningún bloqueo. Sin embargo, en 2024, el commit c25a19afb81c ("fbdev/hyperv_fb: No borrar la información global del screen_info") revirtió eficazmente el problema 3cb73bc3fa2a. el commit c25a19afb81c no hace referencia a 3cb73bc3fa2a, por lo que quizás se realizó sin conocer las implicaciones reportadas con 3cb73bc3fa2a. En cualquier caso, a partir de el commit c25a19afb81c, el problema original reapareció. Curiosamente, el controlador hyperv_drm no presenta este problema porque nunca mueve el framebuffer. La diferencia radica en que el controlador hyperv_drm elimina cualquier framebuffer conflictivo *antes* de asignar una dirección MMIO, mientras que el controlador hyperv_fb lo hace *después* de asignar una dirección MMIO. Con la ordenación "después", hyperv_fb puede encontrar un conflicto y mover el framebuffer a una dirección MMIO diferente. Sin embargo, el conflicto es esencialmente falso porque se elimina unas líneas de código más adelante. En lugar de corregir el problema con el enfoque de 2020 en el commit 3cb73bc3fa2a, se recomienda reordenar ligeramente los pasos en hyperv_fb para eliminar los framebuffers conflictivos antes de asignar una dirección MMIO. De esta forma, la dirección MMIO predeterminada del framebuffer siempre estará disponible y nunca habrá confusión sobre qué dirección debe usar el kernel de kdump: siempre es la dirección original proporcionada por el host de Hyper-V. Este enfoque ya lo utiliza el controlador hyperv_drm y es coherente con las directrices de uso que se indican al principio del módulo con la función aperture_remove_conflicting_devices(). Este enfoque también resuelve un problema menor relacionado cuando se utiliza kexec_load() para cargar el kernel de kdump. Con el código actual, desvincular y volver a vincular el controlador hyperv_fb podría---truncado---

Impacto