Comprensión del alcance de las erratas de hipervínculos de Intel KBL095

5

Recientemente, muchas placas base compatibles con skylake o kabylake obtuvieron una actualización de uefi descrita como actualización de seguridad de microcódigo de cpu para una errata de Intel específica, descrita por Intel como:

  

Los bucles cortos que utilizan los registros AH / BH / CH / DH pueden causar un comportamiento impredecible del sistema.

     

En condiciones de microarquitectura complejas, los bucles cortos de menos de 64 instrucciones que utilizan registros AH, BH, CH o DH, así como su registro más amplio correspondiente (por ejemplo, RAX, EAX o AX para AH) pueden causar un comportamiento impredecible del sistema. Esto solo puede suceder cuando ambos procesadores lógicos en el mismo procesador físico están activos.

Intel emite erratas frecuentes en la CPU que pueden causar la denegación de servicio, pero en este caso, el fabricante no creó una actualización específica de uefi para cada una de ellas.
Por supuesto, probé el siguiente código en varios núcleos lógicos que no bloquean nada (no entiendo si los 8 registros deben estar involucrados para desencadenar el error o solo uno de ellos es suficiente) :

48 ba ff 00 00 00 04    movabs $0x4000000ff,%rdx
00 00 00
.L5:
48 89 d0                movq    %rdx,%rax
48 2d fe 00 00 00       subq    $0xfe,%rax
08 f4                   orb     %dh,%ah
48 89 c3                movq    %rax,%rbx
48 81 eb fe 00 00 00    subq    $0xfe,%rbx
08 e7                   orb     %ah,%bh
48 89 d9                movq    %rbx,%rcx
48 81 e9 fe 00 00 00    subb    $0xfe,%rcx
08 fd                   orb     %bh,%ch
48 89 ca                movq    %rcx,%rdx
48 81 ea fe 00 00 00    subq    $0xfe,%rdx
08 ee                   orb     %ch,%dh
48 85 cb                test   %rcx,%rbx
75 cc                   jne    .L5
movq    %rcx, %rdx
movq    %rbx, %rax
movq    %rax, %rsi
leaq    .LC0(%rip), %rdi
movl    $0, %eax
call    printf@PLT

Entonces, unpredictable system behavior implica la ejecución remota de código (por ejemplo, porque tales bucles propagarían el cambio de registro al otro hilo que se ejecuta en el mismo núcleo) ?

Además, ¿qué tipo de bucles pueden desencadenar el error? ¿La simple modificación de algunos de los registros involucrados en menos de 64 instrucciones desencadena el error? ¿Los bucles deben ser diferentes (me refiero a que los subprocesos no deberían usar el mismo código) ?
Al menos puede ser posible tener un código Ocaml de ejemplo que pueda desencadenar el error ?
¿Cómo saber si se utiliza un microcódigo vulnerable al ejecutar qemu-kvm? (qemu -cpu host oculta el número de revisión del microcódigo)

    
pregunta user2284570 08.10.2017 - 20:22
fuente

3 respuestas

2

El rastreador de errores de ocaml todavía tiene el informe de error original: enlace

Utilizando la misma versión de ocaml (4.03) y siguiendo los pasos para reproducir, a saber: while ocamlfind opt -c -g -bin-annot -ccopt -g -ccopt -O2 -ccopt -Wextra -ccopt '-Wstrict-overflow=5' -thread -w +a-4-40..42-44-45-48-58 -w -27-32 -package extprot test.ml -o test.cmx; do echo "ok"; done , se indica que puede reproducirse dentro de ~ 30 m en una máquina sin parchear.

No pude encontrar ninguna información interna de Intel relacionada con las erratas. Supongo que se mantiene en secreto debido a la naturaleza delicada del problema.

La publicación debian ML ( enlace ) tiene más detalles sobre el tema en sí y Los tipos de procesadores afectados. Esto podría ser relevante para su investigación.

    
respondido por el Mathieu Mitchell 31.10.2017 - 06:05
fuente
1

Pidió muchas cosas que se responden de manera muy explícita en el informe Debian y también en la documentación de Intel ... De todos modos, ambos hilos de hardware deben estar ejecutando un bucle cerrado (que se ajusta a las condiciones para activar el detector de flujo de bucle en ambos subprocesos al mismo tiempo), que tocan esos registros y golpean otros detalles desconocidos del microprocesador interno, para que la errata se dispare.

Una de las personas de la OCAML informó públicamente de un solo caso de corrupción de la tabla de páginas, por lo que parece , a partir de esta evidencia, no debemos descartar que la errata pueda causar un daño que se escape. procesar el contexto y provocar un comportamiento impredecible en un proceso no relacionado.

Pero las pruebas estadísticamente relevantes deberían realizarse para estar seguros.

Disparar el error es difícil, pero el recolector de basura de OCAML se las arregla para hacerlo relativamente fácil (no está "bajo demanda"). Busque la cobertura de Hacker News para obtener detalles, básicamente, lo más probable es que el detector de flujo de bucle (una optimización de administración de energía) desencadene la errata, y haga que ese se ejecute en ambos subprocesos de la forma que sea necesaria. para que la errata se dispare a propósito no es trivial. Nadie ha publicado nada relacionado con eso, todavía.

El recolector de basura OCAML se las arregla para hacerlo con la frecuencia suficiente, y es el único reproductor conocido. Se informó que algunas muy buenas investigaciones de seguridad estaban interesadas, pero hasta el momento no surgió nada.

Mientras tanto, parche ese microcódigo. No podemos estar realmente seguros de que no sea explotable por la seguridad bajo demanda en este momento, pero incluso si estuviéramos seguros de que no fuera explotable para la escalada de privilegios, aún sería un bolsillo de maldad impredecible.

En cuanto a las distribuciones de Linux, incluso las más conservadoras ya han emitido paquetes actualizados, ya que ha habido suficientes pruebas y no surgieron problemas reales con estas rondas de actualizaciones [que de todas formas no estaban presentes en las actualizaciones anteriores].

En cuanto a los proveedores de placas base, a estas alturas ya debería saber cuáles debe evitar en el futuro.

    
respondido por el anonymous 10.10.2017 - 15:40
fuente
0

de este un caso de cambio parece haber causado el problema:

# The main loop condition
.L108:
    .loc 3 542 0
    testq   %r13, %r13
    jg  .L111
[...]

la comprobación de la condición if para cargar el siguiente fragmento de memoria en el límite del fragmento

.L103:
    .loc 3 567 0
    movq    chunk(%rip), %rax
    movq    -8(%rax), %rax
    movq    %rax, chunk(%rip)
    .loc 3 568 0

la condición de salida. Este código solo se toma una vez en exit y gcc insertó un salto de acceso directo a la función exit

    testq   %rax, %rax
    je  .L115
    .loc 3 575 0
    movq    %rax, caml_gc_sweep_hp(%rip)
    .loc 3 576 0
    addq    -16(%rax), %rax
    movq    %rax, limit(%rip)
.L111:
    .loc 3 543 0

La rama if. Este es probablemente el efecto directo de la propagación del rango de valores, saltando directamente dentro del bucle en lugar de ejecutar la verificación nuevamente

 movq    caml_gc_sweep_hp(%rip), %rbx
    cmpq    limit(%rip), %rbx
    jnb .L103
    .loc 3 545 0

La palabra de cabecera de descodificación de punto de entrada del conmutador

movq    (%rbx), %rax
.loc 3 546 0
movq    %rax, %rdx
shrq    $10, %rdx
movq    %rdx, %r13
notq    %r13
addq    %r12, %r13
movq    %r13, %r12
.loc 3 547 0
leaq    8(%rbx,%rdx,8), %rdx
movq    %rdx, caml_gc_sweep_hp(%rip)
.loc 3 548 0

la rama que maneja el color blanco, también conocido como bloques inalcanzables (dejado fuera de esta muestra)

movq    %rax, %rdx
andl    $768, %edx
je  .L105

la rama que maneja el color azul (dejado fuera de esta muestra)

cmpq    $512, %rdx
je  .L106

La rama predeterminada también conocida como bloques alcanzables

.loc 3 562 0

actualización de la parte de color del encabezado

andb    $252, %ah
movq    %rax, (%rbx)
.loc 3 563 0
jmp .L108 # jumping back to the loop condition to scan next block

específicamente este bloque de código causó el problema:

.L111:
   .loc 3 562 0
   movq    -16(%rbp), %rax
   andb    $252, %ah
   movq    %rax, %rdx
   movq    -8(%rbp), %rax
   movq    %rdx, (%rax)
   .loc 3 563 0
   nop
   jmp     .L102
    
respondido por el jtillman 04.11.2017 - 07:28
fuente

Lea otras preguntas en las etiquetas