Pregunta corta
¿Verificando si la dirección de fallas para cada punto de falla de la página en la memoria del kernel detectaría de manera confiable un intento de Explotación en Meltdown, en sistemas que carecen de Intel TSX (y por lo tanto no pueden suprimir las excepciones)? La función kernel do_page_fault()
de Linux se ejecuta en cada error de página, y la dirección del acceso a la memoria con fallas está disponible en esa función, por lo que debería ser posible verificar si esa dirección apunta a un rango de memoria específico del kernel. Para un modelo de amenaza en el que KPTI no es una opción y donde se acepte el intercambio de disponibilidad (DoS sin privilegios) por confidencialidad, ¿es correcta esta idea?
Pregunta larga
La vulnerabilidad Meltdown recientemente revelada en los procesadores Intel aprovecha la propiedad de ejecución fuera de orden de todos los procesadores modernos para leer memoria física arbitraria. Esto se basa en la capacidad de intentar acceder de forma repetida a la memoria del kernel, a pesar de que los intentos de acceso fallarán. Estos intentos de acceso fallidos desencadenan #PF
o error de página, lo que provoca que el proceso del espacio de usuario se envíe SIGSEGV
debido a su intento de acceder a la memoria del núcleo. El ataque Meltdown se aprovecha del hecho de que la memoria caché todavía se llena con la memoria privilegiada a pesar del acceso denegado. La siguiente etapa del ataque es usar un ataque de tiempo para recuperar el contenido del caché. Sin embargo, sin el soporte de TSX, parece imposible (por lo que yo sé) inhibir estos errores de página. En tales sistemas, Meltdown necesariamente desencadena un gran número de fallas de página causadas por intentos de acceso a la memoria del kernel. Esto puede ser detectado por el núcleo.
Desde el documento , se describen tres pasos para realizar el ataque:
Meltdown combines the two building blocks discussed in Section 4. First, an attacker makes the CPU execute a transient instruction sequence which uses an inacces- sible secret value stored somewhere in physical memory (cf. Section 4.1). The transient instruction sequence acts as the transmitter of a covert channel (cf. Section 4.2), ultimately leaking the secret value to the attacker. Meltdown consists of 3 steps: Step 1 The content of an attacker-chosen memory loca- tion, which is inaccessible to the attacker, is loaded into a register. Step 2 A transient instruction accesses a cache line based on the secret content of the register. Step 3 The attacker uses Flush+Reload to determine the accessed cache line and hence the secret stored at the chosen memory location. By repeating these steps for different memory locations, the attacker can dump the kernel memory, including the entire physical memory.
Después de leer sobre supuesta mitigación utilizando el subsistema de rastreo del kernel, tiene sentido que la detección de un número anormalmente grande de fallos de página debido al acceso a la memoria del kernel pueda detectar de manera confiable el Meltdown. ¿Mi pensamiento es correcto? Dicha mitigación simplemente verificará en cada fallo de la página si CR2
(el registro que contiene la dirección de falla) es mayor o no que 0xffff000000000000
, lo que indicaría que se intentó acceder a la memoria del núcleo. El sistema podría inducir un pánico en el núcleo, evitando que el ataque continúe.
De la fuente del kernel , el do_page_fault()
La función se define como:
dotraplinkage void notrace
do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
unsigned long address = read_cr2(); /* Get the faulting address */
enum ctx_state prev_state;
prev_state = exception_enter();
if (trace_pagefault_enabled())
trace_page_fault_entries(address, regs, error_code);
__do_page_fault(regs, error_code, address);
exception_exit(prev_state);
}
NOKPROBE_SYMBOL(do_page_fault);
Esta función se llama cada vez que hay un error de página, con la dirección de error guardada en address
. Sin el soporte de TSX, a mi entender, es imposible que el ataque evite ingresar a esta función. Me parece que es como agregar una simple comprobación para ver si la dirección está en un rango peligroso, por lo que algo similar a BUG_ON(address > 0xffff000000000000)
detectaría de forma confiable el 100% de los ataques de Meltdown bajo estas restricciones. Esto podría hacerse más confiable (es menos probable que provoque falsos positivos) solo provocando un pánico cuando se produzca un número suficiente de violaciones e ignorar una violación si address
es menor que mmap_min_addr
(lo que implicaría una desreferencia de puntero NULA benigna ), pero eso solo sería necesario si una carga de trabajo determinada desencadena falsos positivos.
Esta mitigación no funcionaría si se cumple alguna de las siguientes condiciones:
- Specter, que no causa fallos de página, puede realizar Meltdown sin abusar de eBPF.
- Hay otra forma de usar Meltdown sin activar un error de página, en sistemas sin TSX.
- La función
do_page_fault()
se puede evitar cuando se produce un error de página.
Al volver a leer el documento, menciona la supresión de excepciones con otros métodos distintos de TSX, pero no está del todo claro. Hace que parezca que una falla de página podría evitarse así:
if (condition_mispredicted_as_false)
access_kernel_memory();
Si esto es cierto, entonces este mecanismo de detección (y el de Capsule8) no funcionará.
¿Funcionaría esta mitigación en sistemas sin TSX, asumiendo que los falsos positivos naturales no son un problema e ignorando el hecho de que abriría errores DoS sin privilegios?