¿Mitigando Meltdown comprobando la dirección de falla en cada falla de página?

7

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?

    
pregunta forest 09.01.2018 - 08:49
fuente

1 respuesta

4

Esto evitará dos de las tres formas de ejecutar un ataque de Meltdown. Desafortunadamente para ti, no hace nada para el tercero.

La forma más sencilla de realizar un ataque de Meltdown es realizar una lectura ilegal con un retraso en la tubería lo suficientemente largo como para que la CPU actúe de forma especulativa en la lectura antes de que se active el error de página, luego detecte el error. Su propuesta detectará y detendrá eso antes de que el atacante pueda realizar más de unas pocas lecturas.

La forma más rápida es utilizar TSX para suprimir la falla, pero ha especificado que TSX no está presente en el sistema.

La tercera forma es combinar Meltdown con la predicción errónea de rama de Spectre: entrenar al predictor de rama para que tome la rama de "memoria de lectura" con direcciones inocuas, luego bifurque la otra forma mientras especifica una dirección protegida. Esto es mucho más lento que cualquiera de las otras formas de leer la memoria protegida, pero como la lectura ilegal se descarta cuando se detecta la predicción errónea de la rama, nunca se genera un error de página. Como resultado, las lecturas son completamente invisibles para el código propuesto.

    
respondido por el Mark 09.01.2018 - 11:06
fuente

Lea otras preguntas en las etiquetas