Fortalecimiento del sistema en Android 11


En Android 11 seguimos aumentando la seguridad de la plataforma Android. Pasamos a configuraciones predeterminadas más seguras, migramos a un asignador de memoria reforzado y expandimos el uso de mitigaciones de compilación que defienden contra clases de vulnerabilidades y frustran las técnicas de explotación.

Inicializando memoria

Hemos habilitado formas de inicialización automática de memoria tanto en el espacio de usuario de Android 11 como en el kernel de Linux. Los errores de memoria no inicializados ocurren en C / C ++ cuando la memoria se united states of america sin haber sido inicializada primero a un valor seguro conocido. Estos tipos de errores pueden ser confusos, e incluso el término «no inicializado» es engañoso. No inicializado puede parecer que implica que una variable tiene un valor aleatorio. En realidad no es al azar. Tiene cualquier valor previamente colocado allí. Este valor puede ser predecible o incluso controlado por el atacante. Lamentablemente, este comportamiento puede provocar una vulnerabilidad grave, como errores de divulgación de información como ASLR evita, o controla el secuestro de flujo a través de un pila o spray de montón. Otro posible efecto secundario del uso de valores no inicializados es que las optimizaciones avanzadas del compilador pueden transformar el código de manera impredecible, ya que esto se considera comportamiento indefinido por los estándares C relevantes.

En la práctica, los usos de la memoria no inicializada son difíciles de detectar. Dichos errores pueden pasar desapercibidos en la base de código durante años si la memoria se inicializa con algún valor «seguro» la mayor parte del tiempo. Cuando la memoria no inicializada make un error, a menudo es difícil identificar la fuente del mistake, especialmente si rara vez se activa.

Eliminar una clase completa de tales errores es mucho más efectivo que cazarlos individualmente. La inicialización automática de variables de pila se basa en una característica del compilador de Clang que permite elegir inicializar variables locales con ceros o un patrón.

La inicialización a cero proporciona valores predeterminados más seguros para cadenas, punteros, índices y tamaños. Las desventajas de zero init son valores predeterminados menos seguros para los valores de retorno y exponen menos errores donde el código subyacente se basa en la inicialización cero. La inicialización del patrón tiende a exponer más errores y, en normal, es más seguro para los valores de retorno y menos seguro para cadenas, punteros, índices y tamaños.

Inicializando el espacio de usuario:

La inicialización automática de variables de pila está habilitada en todo el espacio de usuario de Android. Durante el desarrollo de Android 11, inicialmente seleccionamos el patrón para descubrir errores basados ​​en zero init y luego pasamos a zero-init después de unos meses para mayor seguridad. Los desarrolladores de SO de plataforma pueden construir con `AUTO_Sample_INITIALIZE=genuine m` si quieren ayuda para descubrir errores confiando en zero init.

Inicializando el Kernel:

Automático apilar y montón La inicialización se fusionó recientemente en el núcleo de Linux ascendente. Hemos puesto a disposición estas funciones en versiones anteriores del kernel de Android, incluidas 4.14, 4.19y 5.4. Estas características imponen la inicialización de variables locales y asignaciones de almacenamiento dinámico con valores conocidos que los atacantes no pueden controlar y que son inútiles cuando se filtran. Ambas características dan como resultado una sobrecarga de rendimiento, pero también evitan comportamientos indefinidos que mejoran tanto la estabilidad como la seguridad.

Para la inicialización de la pila del núcleo, adoptamos el CONFIG_INIT_STACK_ALL del upstream Linux. Actualmente se basa en la inicialización del patrón Clang para las variables de la pila, aunque esto está sujeto a cambios en el futuro.

La inicialización del montón está controlada por dos indicadores de tiempo de arranque, init_on_alloc e init_on_cost-free, y el primero borra los objetos del montón recién asignados con ceros (piense s/kmalloc/kzalloc en todo el núcleo) y este último hace lo mismo antes de que se liberen los objetos (esto ayuda a reducir la vida útil de los datos sensibles a la seguridad). init_on_alloc es mucho más amigable con el caché y tiene un menor impacto en el rendimiento (dentro del 2%), por lo tanto, se ha elegido para proteger los núcleos de Android.

Scudo es ahora el asignador nativo predeterminado de Android

En Android 11, Scudo reemplaza jemalloc como el asignador nativo predeterminado para Android. Scudo es un asignador de memoria reforzado diseñado para ayudar a detectar y mitigar errores de corrupción de memoria en el montón, como:

Scudo no previene completamente la explotación, pero agrega una serie de controles de sanidad que son efectivos para fortalecer el montón contra algunos errores de corrupción de memoria.

También organiza proactivamente el montón de una manera que dificulta la explotación de la corrupción de la memoria, al reducir la previsibilidad de los patrones de asignación y al separar las asignaciones por tamaños.

En nuestras pruebas internas, Scudo ya ha demostrado su valía al descubrir errores de seguridad y estabilidad que antes no se detectaban.

Encontrar errores de seguridad de la memoria del montón en la naturaleza (GWP-ASan)

Android 11 presenta GWP-ASan, una herramienta de detección de errores de seguridad de memoria de almacenamiento dinámico en producción que está integrada directamente en el asignador nativo Scudo. GWP-ASan detecta y proporciona probabilísticamente informes procesables para errores de seguridad de la memoria de almacenamiento dinámico cuando ocurren, funciona en procesos de 32 bits y 64 bits, y está habilitado de forma predeterminada para procesos y aplicaciones del sistema.

GWP-ASan es también disponible para aplicaciones de desarrollador a través de una opción de una línea en el AndroidManifest.xml de una aplicación, sin necesidad de compilar o compilar compilaciones de bibliotecas precompiladas complicadas.

Computer software basado en etiquetas KASAN

Trabajo continuo en adoptando la extensión de etiquetado de memoria de brazo (MTE) en Android, Android 11 incluye soporte para kernel HWASAN, también conocido como Software package basado en etiquetas KASAN. Espacio de usuario HWASAN es suitable desde Android 10.

KernelAddressSANitizer (KASAN) es un detector dinámico de errores de memoria diseñado para encontrar errores fuera de límite y sin uso en el kernel de Linux. Sus Modo basado en etiquetas de computer software es una implementación de program del concepto de etiquetado de memoria para el núcleo. El program KASAN basado en etiquetas está disponible en 4.14, 4.19 y 5.4 núcleos de Android, y se puede habilitar con la opción de configuración de kernel CONFIG_KASAN_SW_TAGS. Actualmente, KASAN basado en etiquetas solo admite el etiquetado de la memoria de losa En el futuro se agregará soporte para otros tipos de memoria (como stack y globals).

Comparado con KASAN genérico, KASAN basado en etiquetas tiene requisitos de memoria significativamente menores (ver esta confirmación del núcleo para más detalles), lo que lo hace utilizable en dispositivos de prueba de alimentos para perros. Otro caso de uso para Application Tag-Primarily based KASAN es verificar la compatibilidad del código de kernel existente con el etiquetado de memoria. Dado que KASAN basado en etiquetas se basa en conceptos similares al futuro soporte de MTE en el núcleo, asegurarse de que el código del núcleo funcione con KASAN basado en etiquetas facilitará la integración de MTE en el núcleo en el futuro.

Expandir las mitigaciones existentes del compilador

Continuamos expandiendo las mitigaciones del compilador que se han implementado en anterior lanzamientos también. Esto incluye agregar desinfectantes tanto enteros como de límites a algunas bibliotecas centrales que les faltaban. Por ejemplo, la biblioteca de fuentes libminikin y la biblioteca de renderizado libui ahora están desinfectadas. Hemos fortalecido la pila de NFC mediante la implementación de desinfectante de desbordamiento de enteros y desinfectante de límites en esos componentes.

Además de las mitigaciones difíciles como los desinfectantes, también continuamos expandiendo nuestro uso de CFI como una mitigación de exploits. CFI se ha habilitado en Android demonio de redes, DNS resolvery más de nuestras bibliotecas principales de javascript, como libv8 y PacProcessor.

La efectividad de nuestro sandbox de códec de software package

Antes del lanzamiento de Android 10, nosotros anunció un nuevo entorno limitado limitado para códecs de program. Estamos realmente satisfechos con los resultados. Hasta ahora, Android 10 es la primera versión de Android desde las infames vulnerabilidades de StageFright en Android 5. con cero vulnerabilidades de gravedad crítica en los marcos de medios.

Gracias a Jeff Vander Stoep, Alexander Potapenko, Stephen Hines, Andrey Konovalov, Mitch Phillips, Ivan Lozano, Kostya Kortchinsky, Christopher Ferris, Cindy Zhou, Evgenii Stepanov, Kevin Deus, Peter Collingbourne, Elliott Hughes, Kees Cook y Ken Chen por su contribuciones a esta publicación.



Enlace a la noticia initial