El bit NX no es solo seguridad: una odisea de depuración en ARM64
The NX bit is not just about security
En esta historia de depuración de un hipervisor ARM64 para postmarketOS, la autora se enfrenta a un bloqueo aleatorio del sistema al interceptar el registro CTR_EL0. Tras descartar errores de código y sospechar de hardware fuera de especificación, descubre que el problema reside en la predicción de saltos: una llamada indirecta (blr) a una dirección que apunta a memoria no ejecutable causa un fallo de página especulativo, mientras que una llamada directa (bl) funciona. La solución final implica mapear la página física 0 para evitar el fallo, revelando una interacción sutil entre la seguridad de memoria y el rendimiento.
¿Cómo se diferencian los despachos dinámicos de las ramas estáticas? Los despachos dinámicos emplean predicción de saltos, las ramas estáticas saben a dónde llevan de antemano y no pueden fallar en la predicción.
- repiret
"La captación especulativa de instrucciones hacia memoria de dispositivo bloquea el dispositivo" está en mi lista de errores favoritos jamás encontrados. Me topé con él en un Cortex-M4 sin MPU, así que ni siquiera podía corregir los atributos de memoria; la única solución fue manipular el código compilado para evitar la captación especulativa.
Es una locura que Armv8/9-A permita captaciones especulativas de instrucciones hacia memoria de dispositivo. Tan loco que tuve que buscarlo para creerlo:
"El hardware no impide las captaciones especulativas de instrucciones desde una ubicación de memoria con cualquiera de los atributos de memoria Device, a menos que la ubicación de memoria también esté marcada como execute-never para todos los niveles de excepción." - ARM DDI 0487K.a § B2.15.2
La especificación Armv7-M es menos clara. Sí dice: "La arquitectura no permite accesos especulativos a memoria marcada como Device", en contraste con Armv8/9-A que califica una declaración similar con "accesos de datos". Pero luego dice más adelante: "Para garantizar la corrección, las ubicaciones sensibles a la lectura deben marcarse como no ejecutables". (Todo esto proviene de ARM DDI 0403E.e § A3.5.7)
No tengo a mano v7-A más antiguo para comparar lo que dicen.
- asveikau
Sobre este tema de que no se trata solo de seguridad: si tienes un error como un use after free y resulta que cubre un puntero a función, el bit NX puede asegurar que cuando sigues ese puntero a través de una llamada, obtienes una trampa limpia lo más cerca posible del punto de fallo. Si ejecutara ciegamente bytes obsoletos como código, tal vez el bloqueo y el seguimiento de pila no se verían tan bien.
Pero entonces, muchos errores de corrección como ese también son problemas de seguridad.
- mubbicles
Aprecié este artículo. Le he preguntado a nuestro encargado de CSP la diferencia, pero esto me ayuda a entender mejor device vs ns. También aprecio que no parezca escrito por IA.
- anyfoo
Hoy en día, se considera de mala educación mapear cualquier cosa en 0... ¡ya sabes una de las razones!
En el caso que conozco que tiene un mapeo de identidad 1:1 del espacio de direcciones, el espacio de direcciones físicas tampoco tiene realmente nada en 0, por lo que aún así no necesita estar mapeado.
- eqvinox
Sinceramente, parece un mal diseño en ARM. ¿Dónde tiene sentido que la memoria Device no pueda ser precargada por datos, pero sí permitir la precarga de instrucciones? Debería, en mi opinión, deshabilitar toda precarga...