Compilar el kernel sin soporte de virtualización KVM bastaba para que la protección contra Branch History Injection quedara desactivada, aunque los vectores de ataque siguieran abiertos en la misma máquina. El fallo lo detectó Breno Leitao, desarrollador de Debian, y el envío de arreglos x86 del 8 de noviembre de 2026, lo corrige antes de que Linux 7.4-rc2 saliera. Las configuraciones afectadas no eran exóticas: la mitigación no se aplicaba como era necesario en muchas generaciones de procesadores Intel y en ciertas CPUs ARM y AMD.
BHI pertenece a la familia de la ejecución especulativa y hereda el linaje de Spectre, la vulnerabilidad que en 2018 obligó a rediseñar medio kernel. El procesador guarda un historial de bifurcaciones para adivinar por dónde seguirá el código, y ese historial se puede contaminar desde un proceso sin privilegios para que la predicción acabe saltando a un fragmento del kernel que filtra memoria. La mitigación existe desde 2022 y cuesta rendimiento, así que el kernel la activa solo cuando la necesita.
El problema no fue un agujero nuevo ni un fallo de hardware. Fue una condición mal escrita en la función que elige qué mitigación toca, y el efecto es incómodo: dos kernels idénticos sobre el mismo procesador pueden acabar con niveles de protección distintos según cómo se compilaron. La corrección hace que la elección dependa de los vectores que siguen abiertos.
¿Qué es mitigación BHI y por qué sigue importando?
La idea detrás de BHI es incómoda porque no depende de un error concreto en el código. Depende de cómo decide el procesador, antes de saberlo, cuál será la siguiente instrucción que ejecute.
El historial de bifurcaciones (BHB) es un búfer donde el procesador apunta el patrón de saltos recientes para anticipar el destino de una llamada indirecta. Si un atacante con ejecución local consigue escribir en ese historial, puede empujar la predicción hacia una dirección que le interese, y esa dirección se ejecuta de forma especulativa con privilegios del kernel. El resultado es el de siempre en esta familia: el dato no se lee, se deduce midiendo el tiempo que tarda en llegar a la caché.
La mitigación tiene dos formas. Una es de hardware, con el bit BHI_DIS_S que apaga la especulación sobre ese historial; la otra es un bucle de software que limpia el BHB en cada transición entre modos. El kernel documenta ambas en la mitigación de BHI y solo recurre a la segunda cuando el procesador no ofrece la primera.
El error, la mitigación se apagaba sola sin KVM
La función bhi_select_mitigation() tomaba la decisión con un solo dato: si el vector invitado a anfitrión estaba habilitado. Cuando no lo estaba, elegía BHI_MITIGATION_OFF y no consultaba nada más, ni las capacidades del procesador ni el resto de vectores abiertos.
Y no lo estaba en muchos equipos. En un kernel compilado sin KVM, la marca CPU_MITIGATE_GUEST_HOST arranca apagada porque no hay invitados capaces de atacar al anfitrión, de modo que la protección quedaba fuera incluso en máquinas donde un proceso normal podía lanzar el ataque desde espacio de usuario. Leitao lo resumió en su explicación del parche: esos kernels pierden BHI_DIS_S o el bucle de limpieza del BHB por defecto, y arrancar con mitigations=auto,no_guest_host produce el mismo efecto.
El detalle que convierte el caso en algo más que una anécdota es la asimetría. El vector invitado a anfitrión desaparece sin KVM, pero el vector usuario a kernel sigue en pie, y es justo el que la documentación del kernel también asocia a esta técnica.
El arreglo entró en el lote de arreglos x86 fusionado antes de Linux 7.4-rc2, que llegó el 8 de noviembre de 2026, y sus responsables lo marcaron para volver a los kernels estables soportados desde 2022, cuando esta mitigación aterrizó en el árbol principal. Nadie tiene que esperar a la versión 7.4 si su distribución arrastra parches de estabilidad.
User a kernel y guest a host, la documentación que el código contradecía
La tabla de vectores del kernel indica qué protecciones hacen falta para cada camino de ataque. BHI aparece en dos columnas y el código solo miraba una. Esa distancia entre lo escrito y lo ejecutado es el fallo entero, sin nada más detrás.
Usuario a kernel es el ataque de manual: un programa sin privilegios provoca un salto indirecto mal predicho y el procesador ejecuta de forma especulativa código del kernel con datos que no debería ver. Invitado a anfitrión es la versión con hipervisor, donde una máquina virtual contamina el historial y la predicción se desvía dentro del anfitrión. La tabla de vectores de ataque recoge ambos escenarios bajo BHI desde que el mecanismo quedó documentado.
En un servidor sin KVM el segundo vector no existe, y de ahí salió la lógica original de la función. El error fue asumir que la ausencia de uno implicaba la ausencia del otro. Leitao lo planteó como una incoherencia entre la documentación y el código, y esa es la descripción correcta: no faltaba una mitigación, faltaba una condición.
¿Qué CPUs están afectadas y cómo saber si tu kernel lo aplica?
El alcance depende del silicio. Intel aporta muchas generaciones afectadas, y a la lista se suman algunos procesadores ARM y ciertos AMD que comparten la misma debilidad en el historial de bifurcaciones.
En Intel conviven las dos formas de protección: los chips que exponen BHI_DIS_S resuelven el problema en hardware y los que no dependen del bucle de software que este parche vuelve a activar. Esa diferencia es la que convierte al fallo en algo tangible para quien administra servidores con unos años encima, porque son justo los equipos donde la mitigación por software es la única disponible y donde el kernel estaba apagándola.
| Valor de BHI en spectre_v2 |
Qué significa |
| BHI: Not affected |
El procesador no es vulnerable |
| BHI: BHI_DIS_S |
El hardware apaga la especulación sobre el historial |
| BHI: SW loop |
El kernel limpia el BHB con un bucle de software |
| BHI: Vulnerable |
No hay protección activa |
La comprobación cabe en un comando. El archivo /sys/devices/system/cpu/vulnerabilities/spectre_v2 devuelve una línea BHI con el estado real del equipo, y ahí se ve si el kernel aplica BHI_DIS_S, el bucle de software o ninguna de las dos cosas. También conviene saber que el parámetro spectre_bhi= de la línea de arranque permite forzar la decisión, aunque rara vez sea la vía recomendable.
Si el valor dice Vulnerable en un equipo de escritorio con un procesador de 2019, la causa probable es la configuración del kernel y no el silicio. Actualizar el paquete de la distribución debería bastar una vez que el parche aterrice en la rama estable de cada proyecto.
La deuda técnica de las mitigaciones especulativas
Cada vulnerabilidad de este tipo deja una capa de código condicional que se queda para siempre, porque el parque de procesadores no se jubila al ritmo de los parches. Spectre se hizo público en enero de 2018 y el kernel sigue arrastrando código de ese tipo.
El resultado es una matriz de configuraciones que nadie prueba entera. El soporte de BHI depende de una opción de compilación que a su vez exige soporte de CPU Intel, y encima interactúa con KVM, con los controles de vectores y con los parámetros de arranque. Un fallo como este no aparece en una prueba unitaria, aparece cuando alguien compara el código con la documentación y descubre que no cuentan lo mismo. La avalancha de CVE que recibe el kernel hace que esas comparaciones sean cada vez más caras.
La otra mitad del problema es el calendario. Un parche en el árbol principal tarda en llegar a las distribuciones, y ahí está el caso de CVE-2026-98432, que siguió sin parche en Ubuntu y RHEL semanas después de hacerse público. Con BHI el riesgo es menor porque hace falta ejecución local, pero la lección sobre los tiempos de adopción se repite igual.
El árbol tampoco ayuda a bajar el ritmo. La ventana de fusión de Linux 7.4 fue la mayor de la historia, y cada ciclo añade código que después hay que revisar también en la dimensión de seguridad. Que un desarrollador de Debian encontrara esta condición dice menos del descuido y más del tamaño de lo que se mantiene.
La corrección es pequeña y el efecto es grande, que suele ser el mejor tipo de parche. También es un recordatorio de que la seguridad de la ejecución especulativa no se resuelve con un anuncio, sino revisando cada cierto tiempo si el código sigue haciendo lo que la documentación promete.