�Qué hay detrás de la falla de diseño de Intel ? numerosos parches?

¿Qué hay detrás de la falla de diseño de Intel que obliga a numerosos parches?Intel

Tanto Windows como Linux están recibiendo una seguridad significativa actualizaciuno s que pueden, en el peor de los casos, hacer que el rendimiento disminuya mitad, para defenderse de un problema que aún no ha sido completamente divulgado.

Los parches para el kernel de Linux han estado apareciendo en el pasado pocas semanas. Microsoft ha estado probando las actualizaciones de Windows en el Programa de información privilegiada desde noviembre, y se espera que modificaciones en las versiones principales de Windows en Patch Tuesday el próximo semana. Azure de Microsoft ha programado mantenimiento la próxima semana, y El AWS de Amazon está programado para mantenimiento el viernes, presumiblemente relacionado.

Desde que salieron a la luz los parches de Linux, una imagen más clara de lo que parece estar mal ha surgido. Mientras Linux y Windows difieren en muchos aspectos, los elementos básicos de cómo estos dos sistemas operativos, y de hecho, cualquier otro sistema operativo x86 como como FreeBSD y macOS: manejar la memoria del sistema es lo mismo, porque estas partes del sistema operativo están tan fuertemente unidas a capacidades del procesador.

Seguimiento de direcciones

Cada byte de memoria en un sistema está numerado implícitamente, esos los números son la dirección de cada byte. La primera operación sistemas operados usando direcciones de memoria física, pero físicas Las direcciones de memoria son inconvenientes por muchas razones. Por ejemplo, a menudo hay lagunas en las direcciones y (particularmente en 32 bits sistemas), las direcciones físicas pueden ser difíciles de manipular, que requieren números de 36 bits, o incluso números más grandes.

En consecuencia, todos los sistemas operativos modernos dependen de un amplio concepto llamado memoria virtual. Los sistemas de memoria virtual permiten ambos programas y los núcleos mismos para operar de una manera simple, limpia, ambiente uniforme En lugar de las direcciones físicas con sus vacíos y otras rarezas, cada programa, y ​​el núcleo en sí, usa direcciones virtuales para acceder a la memoria. Estas direcciones virtuales son contiguo, sin necesidad de preocuparse por las brechas, y dimensionado convenientemente para hacerlos fáciles de manipular. Los programas de 32 bits solo ven 32 bits direcciones, incluso si la dirección física requiere 36 bits o más numeración

Si bien este direccionamiento virtual es transparente para casi todos pieza de software, el procesador finalmente necesita saber qué memoria física a la que se refiere una dirección virtual. Hay un mapeo de direcciones virtuales a direcciones físicas, y eso se almacena en un estructura de datos grande llamada tabla de páginas. Construcción de sistemas operativos la tabla de páginas, usando un diseño determinado por el procesador, y el procesador y sistema operativo en conjunto usan la tabla de páginas siempre que necesiten convertir entre virtual y físico direcciones.

Todo este proceso de mapeo es tan importante y fundamental para modernos sistemas operativos y procesadores que tiene el procesador caché dedicada (el búfer lookaside de traducción, o TLB) que almacena un cierto número de asignaciones de virtual a físico para que puede evitar usar la tabla de página completa cada vez.

El uso de la memoria virtual nos brinda una serie de características útiles. más allá de la simplicidad de direccionamiento. El principal de ellos es que cada el programa individual recibe su propio conjunto de direcciones virtuales, con su propio conjunto de mapeos virtuales a físicos. Este es el técnica fundamental utilizada para proporcionar “memoria protegida”; oneel programa no puede corromper o alterar la memoria de otro programa, porque la memoria del otro programa simplemente no es parte de El primer mapeo del programa.

Pero estos usos de un mapeo individual por proceso, y por lo tanto tablas de páginas adicionales, ejercen presión sobre el caché TLB. El TLB no es muy grande, típicamente unos cientos de asignaciones en total, y cuanto más tablas de páginas que utiliza un sistema, es menos probable que el TLB incluir cualquier traducción particular de virtual a física.

Mitad y mitad

Para aprovechar al máximo el TLB, todos los sistemas operativos principales El sistema divide el rango de direcciones virtuales en dos. La mitad de las direcciones se usan para cada programa; la otra mitad se usa para el grano Al cambiar entre procesos, solo la mitad de la página las entradas de la tabla cambian: las que pertenecen al programa. El núcleo la mitad es común a todos los programas (porque solo hay un núcleo), y así puede usar la misma asignación de tabla de páginas para cada proceso. Esto ayuda enormemente al TLB; mientras todavía tiene que descartar asignaciones que pertenecen a la mitad del proceso de direcciones de memoria, puede mantener las asignaciones para la mitad del núcleo.

Este diseño no está completamente escrito en piedra. Se trabajó en Linux para hacer posible dar un proceso de 32 bits a todo el rango de direcciones, sin compartir entre la tabla de páginas del núcleo y el de cada programa. Si bien esto le dio a los programas más dirección espacio, tenía un costo de rendimiento, porque el TLB tuvo que volver a cargar las entradas de la tabla de páginas del núcleo cada vez que el código del núcleo necesita correr. En consecuencia, este enfoque nunca se usó ampliamente en x86 sistemas.

Una desventaja de la decisión de dividir el espacio de direcciones virtuales entre el núcleo y cada programa es que la protección de la memoria está debilitado Si el núcleo tenía su propio conjunto de tablas de páginas y direcciones virtuales, se le otorgaría la misma protección que diferentes programas tienen uno del otro; la memoria del núcleo sería ser simplemente invisible Pero con el direccionamiento dividido, los programas de usuario y el núcleo utiliza el mismo rango de direcciones y, en principio, un El programa de usuario podría leer y escribir la memoria del núcleo.

Para evitar esta situación obviamente indeseable, el procesador y el sistema de direccionamiento virtual tienen un concepto de “anillos” o “modos”. Los procesadores x86 tienen muchos anillos, pero para este problema, solo dos son relevante: “usuario” (anillo 3) y “supervisor” (anillo 0). Cuando se ejecuta programas de usuario normales, el procesador se pone en modo de usuario, anillo 3. Al ejecutar el código del kernel, el procesador está en el anillo 0, supervisor modo, también conocido como modo kernel.

Estos anillos se utilizan para proteger la memoria del núcleo del usuario programas Las tablas de páginas no son solo mapas de virtual a direcciones físicas también contienen metadatos sobre esos direcciones, incluida información sobre qué anillos pueden acceder a un habla a. Las entradas de la tabla de páginas del núcleo están marcadas solo como ser accesible para sonar 0; las entradas del programa están marcadas como siendo accesible desde cualquier anillo. Si se intenta acceder anillo 0 memoria mientras que en el anillo 3, el procesador bloquea el acceso y genera una excepción El resultado de esto es que los programas de usuario, corriendo en el ring 3, no debería poder aprender nada sobre el kernel y su anillo 0 memoria.

Al menos, esa es la teoría. La avalancha de parches y actualizaciones muestra que en algún lugar esto se ha roto. Aquí es donde los grandes El misterio miente.

Moviéndose entre anillos

Esto es lo que sabemos. Cada procesador moderno realiza un cierta cantidad de ejecución especulativa. Por ejemplo, dado algunos instrucciones que agregan dos números y luego almacenan el resultado en memoria, un procesador podría hacer la adición especulativamente antes determinar si el destino en memoria es realmente accesible y escribible. En el caso común, donde la ubicación es escribible, el procesador logró ahorrar algo de tiempo, como lo hizo el aritmética en paralelo con averiguar cuál es el destino en la memoria era Si descubre que la ubicación no es accesible, por ejemplo, un programa que intenta escribir en una dirección que no tiene mapeo y ninguna ubicación física en absoluto, entonces generará un excepción y la ejecución especulativa se desperdicia.

Los procesadores Intel, específicamente, aunque no los AMD, permiten ejecución especulativa de código de anillo 3 que escribe en la memoria de anillo 0. Los procesadores bloquean correctamente la escritura, pero lo especulativo la ejecución perturba minuciosamente el estado del procesador, porque ciertos los datos se cargarán en la memoria caché y el TLB para determinar si se debe permitir la escritura. Esto a su vez significa que algunos las operaciones serán unos ciclos más rápidos o unos ciclos más lentos, dependiendo de si sus datos todavía están en caché o no. También Como esto, los procesadores de Intel tienen características especiales, como el Software Guard Extensions (SGX) introducido con los procesadores Skylake, que cambian ligeramente la forma en que se manejan los intentos de acceder a la memoria. Nuevamente, el procesador todavía protege la memoria del anillo 0 del anillo 3 programas, pero de nuevo, sus cachés y otros estados internos son cambiado, creando diferencias medibles.

Lo que aún no sabemos es cuánta memoria del núcleo se puede filtrar información a los programas de usuario o con qué facilidad pueden ocurrir fugas �Y qué procesadores Intel están afectados? De nuevo no está del todo claro, pero hay indicios de que cada chip Intel con ejecución especulativa (que es todos los procesadores convencionales introducido desde el Pentium Pro, desde 1995) puede filtrar información de esta manera.

El primer viento de este problema provino de investigadores de Graz Universidad Técnica de Austria. La fuga de información que descubierto fue suficiente para socavar el modo kernel Diseño del espacio de direcciones Aleatorización (kernel ASLR o KASLR). ASLR es una especie de último esfuerzo para evitar la explotación de desbordamientos de búfer. Con ASLR, los programas y sus datos se colocan en memoria aleatoria direcciones, lo que dificulta un poco la explotación de los atacantes fallas de seguridad. KASLR aplica esa misma aleatorización al núcleo para que los datos del núcleo (incluidas las tablas de páginas) y el código sean Localizado al azar.

Los investigadores de Graz desarrollaron KAISER, un conjunto de kernel de Linux parches para defenderse del problema.

Si el problema fuera solo que permitía la desleatorización de ASLR, esto probablemente no sería un gran desastre. ASLR es un buen protección, pero se sabe que es imperfecto. Está destinado a ser un obstáculo para los atacantes, no una barrera impenetrable. La industria reacción: un cambio bastante importante para Windows y Linux, desarrollado con algo de secreto: sugiere que no es solo ASLR el que está derrotado y que una capacidad más general para filtrar información del núcleo ha sido desarrollado. De hecho, los investigadores han comenzado a tuitear eso pueden filtrar y leer datos arbitrarios del núcleo. Otro la posibilidad es que la falla se pueda usar para escapar de un virtual máquina y comprometer un hipervisor.

La solución que tienen los desarrolladores de Windows y Linux elegido es sustancialmente el mismo, y derivado de ese KAISER trabajo: las entradas de la tabla de la página del núcleo ya no se comparten con cada proceso. En Linux, esto se llama Aislamiento de tabla de página de kernel (KPTI)

Con los parches, la dirección de memoria todavía se divide en dos; sus solo la mitad del grano está casi vacía. No está del todo vacío, porque algunas piezas del núcleo deben asignarse permanentemente, ya sea que El procesador está funcionando en el anillo 3 o en el anillo 0, pero está casi vacío. Esto significa que incluso si un programa de usuario malintencionado intenta sondear memoria del núcleo e información de fugas, fallará, simplemente hay Nada que perder. Las tablas de páginas del núcleo real solo se usan cuando el núcleo en sí mismo se está ejecutando.

Esto socava la razón misma del espacio de direcciones dividido en El primer lugar. El TLB ahora necesita borrar cualquier entrada relacionada a las tablas de la página del núcleo real cada vez que cambia a un usuario programa, poniendo fin al rendimiento ahorrando esa división habilitado

El impacto de esto variará dependiendo de la carga de trabajo. Cada cada vez que un programa realiza una llamada al núcleo: para leer desde el disco, para enviar datos a la red, abrir un archivo, etc., esa llamada ser un poco más caro, ya que obligará a que el TLB sea enjuagado y la tabla de la página del núcleo real que se cargará. Programas que no use mucho el kernel, podría ver un golpe de quizás 2-3 por ciento: todavía hay algo de sobrecarga porque el núcleo siempre tiene correr ocasionalmente, manejar cosas como la multitarea.

Pero las cargas de trabajo que llaman al núcleo una tonelada verán mucho mayor rendimiento caiga. En un punto de referencia, un programa que hace prácticamente nada más que llamar al núcleo vio su la caída del rendimiento en aproximadamente un 50 por ciento; en otras palabras, cada llamada en el núcleo tardó el parche el doble de lo que hizo sin. Los puntos de referencia que utilizan la red de bucle invertido de Linux también ven un gran éxito, como el 17 por ciento en este punto de referencia de Postgres. Real las cargas de trabajo de la base de datos que utilizan redes reales deberían tener un impacto menor, porque con redes reales, la sobrecarga de llamar al núcleo tiende a estar dominado por la sobrecarga de usar el actual red.

Si bien los sistemas Intel son los que se sabe que tienen el defecto, ellos Puede que no sean los únicos afectados. Algunas plataformas, como SPARC y S390 de IBM, son inmunes al problema, ya que su procesador la gestión de memoria no necesita el espacio de direcciones dividido y compartido tablas de páginas del núcleo; los sistemas operativos en esas plataformas tienen siempre aislaron sus tablas de páginas del núcleo de las del modo de usuario Pero otros, como ARM, pueden no ser tan afortunados; parches comparables para ARM Linux está en desarrollo.

Like this post? Please share to your friends:
Leave a Reply

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: