Protección contra la reutilización de código en el kernel de Linux con Shadow Contact Stack


El kernel de Linux es responsable de hacer cumplir gran parte del modelo de seguridad de Android, por eso hemos hecho un gran esfuerzo para fortalecer el kernel de Android Linux contra la explotación. En Android 9, presentamos soporte para la vanguardia de Clang Integridad de flujo de handle (CFI) aplicación para proteger el núcleo de ataques de reutilización de código que modifican punteros de función almacenados. Este año, hemos agregado protección de vanguardia para las direcciones de retorno que usan Clang Pila de llamadas de sombra (SCS).

Los teléfonos Pixel 3 y 3a de Google tienen el kernel SCS habilitado en la actualización de Android 10, y Pixel 4 viene con esta protección lista para usar. Hemos puesto a disposición parches para todas las versiones compatibles del kernel de Android y también mantenemos un conjunto de parches contra Linux ascendente. Esta publicación explica cómo funciona el kernel SCS, los beneficios y las compensaciones, cómo habilitar la función y cómo depurar posibles problemas.

Programación orientada al retorno

A medida que las protecciones de memoria del kernel dificultan cada vez más la inyección de código, los atacantes suelen utilizar el secuestro de flujo de manage para explotar los errores del kernel. Programación orientada al retorno (ROP) es una técnica en la que el atacante obtiene el command de la pila del kernel para sobrescribir las direcciones de retorno de la función y redirige la ejecución a partes cuidadosamente seleccionadas del código del kernel existente, conocidas como gizmos ROP. Si bien la asignación al azar del espacio de direcciones y los canarios de la pila pueden hacer que este ataque sea más desafiante, las direcciones de retorno almacenadas en la pila siguen siendo vulnerables a muchos defectos de sobrescritura. La disponibilidad general de herramientas para generar automáticamente este tipo de explotación de kernel hace que la protección contra ella sea cada vez más importante.

Pila de llamadas de las sombras

Un método para proteger las direcciones de retorno es almacenarlas en una pila de sombra asignada por separado que no sea vulnerable a los desbordamientos de búfer tradicionales. Esto también puede ayudar a proteger contra ataques arbitrarios de sobrescritura.

Clang agregó el pase de instrumentación de Shadow Simply call Stack para arm64 en la versión 7. Cuando está habilitado, cada función que no sea hoja que empuja la dirección de retorno a la pila se instrumentará con un código que también guarda la dirección en una pila de sombra. Un puntero a la pila de sombra de la tarea actual siempre se mantiene en el registro x18, que está reservado para este propósito. Así es como se ve la instrumentación en una función típica del núcleo:



SCS no requiere manejo de errores, ya que utiliza la dirección de retorno de la pila de sombra incondicionalmente. La compatibilidad con el desbobinado de la pila para fines de depuración se mantiene manteniendo una copia de la dirección de retorno en la pila standard, pero este valor nunca se usa para las decisiones de regulate de flujo.

A pesar de requerir un registro dedicado, SCS tiene una sobrecarga de rendimiento mínima. La instrumentación en sí consiste en una instrucción de carga y una de almacenamiento por función, lo que resulta en un impacto en el rendimiento que está dentro del ruido en nuestra evaluación comparativa. La asignación de una pila de sombra para cada subproceso aumenta el uso de memoria del núcleo, pero como solo se almacenan las direcciones de retorno, el tamaño de la pila por defecto es de 1kB. Por lo tanto, la sobrecarga es una fracción de la memoria utilizada para las pilas de kernel regulares ya pequeñas.

Los parches SCS están disponibles para kernels de Android 4.14 y 4.19, y para upstream Linux. Se puede habilitar usando las siguientes opciones de configuración:

CONFIG_SHADOW_Contact_STACK=y
# CONFIG_SHADOW_Simply call_STACK_VMAP is not established
# CONFIG_DEBUG_STACK_Use is not established

De forma predeterminada, las pilas de sombra no están asignadas virtualmente para minimizar la sobrecarga de memoria, pero CONFIG_SHADOW_Call_STACK_VMAP se puede habilitar para una mejor protección del agotamiento de la pila. Con CONFIG_DEBUG_STACK_Utilization, el kernel también imprimirá el uso de la pila de sombra además del uso normal de la pila, lo que puede ser útil al depurar problemas.

Alternativas

Firma de direcciones de retorno utilizando Autenticación de puntero ARMv8.3 (PAC) es una alternativa a las pilas de sombras. PAC tiene propiedades de seguridad similares y un rendimiento similar a SCS pero sin la sobrecarga de asignación de memoria. Desafortunadamente, PAC requiere soporte de components, lo que significa que no se puede usar en dispositivos existentes, pero puede ser una opción viable para dispositivos futuros. Para x86, Intel&#39s Tecnología de aplicación de command de flujo (CET) La extensión ofrecerá un soporte nativo de stack de sombra, pero también requiere components compatible.

Conclusión

Hemos mejorado las protecciones contra ataques de reutilización de código de kernel de Linux en dispositivos Pixel que ejecutan Android 10. Los núcleos Pixel 3, 3a y 4 tienen CFI y SCS habilitados y hemos puesto a disposición parches para todos los OEM de Android.



Supply connection