Memoria inicializada en cero

La memoria no inicializada en C y C++ es una causa común de problemas de confiabilidad, errores de seguridad de la memoria y filtraciones de información. Para evitar estos problemas, Android inicializa la mayor cantidad de memoria posible.

Memoria del espacio de usuario inicializada en cero

A partir de Android 12, la memoria de pila se inicializa en cero en todo el código nativo de la plataforma (incluida la JNI) y la memoria del montón se inicializa en cero en todos los procesos nativos de la plataforma (como netd), pero no en zygote ni en las apps.

Se recomienda encarecidamente que las apps propias y de terceros compiladas con el NDK usen la marca del compilador -ftrivial-auto-var-init=zero para inicializar en cero sus variables locales de pila. El compilador optimiza cualquier puesta a cero innecesaria. Por ejemplo, cuando una variable local se inicializa de forma explícita (como la variable int x = 123; x, que se inicializa solo una vez). Si el programa tiene un búfer de pila grande en un punto de acceso de rendimiento, el desarrollador puede inhabilitar la inicialización con un atributo del compilador:

__attribute__((__uninitialized__)) char buf[BUFSIZ];

Las apps también pueden habilitar la inicialización del montón cero con el atributo del manifiesto android:nativeHeapZeroInitialized. Como alternativa, la inicialización del montón cero se puede controlar en el tiempo de ejecución con lo siguiente:

int mallopt(M_BIONIC_ZERO_INIT, level)

En el que el nivel es 0 o 1.

Memoria del kernel inicializada en cero

La pila y el montón del kernel se inicializan en cero para los kernels de GKI, lo que recomienda encarecidamente el CDD.

Para la inicialización de la pila, GKI usa la configuración de CONFIG_INIT_STACK_ALL_ZERO, lo que genera la compilación del kernel con la marca del compilador -ftrivial-auto-var-init=zero. Para la inicialización del montón, GKI usa CONFIG_INIT_ON_ALLOC_DEFAULT_ON, que hace que todas las asignaciones de montón de páginas, SLAB y SLUB se inicialicen en cero cuando se crean. Esta opción es similar a pasar init_on_alloc=1 como una opción de inicio del kernel.

Informes de errores

Nuestras herramientas generan informes de errores útiles que contienen información adicional para ayudar con la depuración. El seguimiento de pila de asignación y desasignación adicional ayuda a comprender mejor el ciclo de vida de una asignación determinada y a encontrar errores de seguridad de la memoria raíz mucho más rápido.

Ejemplo de un informe de errores generado por la herramienta de seguridad de la memoria
Figura 1: Informes de errores generados por herramientas de seguridad de la memoria

Durante el desarrollo, los proveedores deben supervisar la presencia de errores. Para ello, deben verificar si hay fallas nativas en /data/tombstones y logcat. Para obtener más información sobre la depuración de código nativo de Android, consulta la información aquí.