La memoria no inicializada en C y C++ es una causa común de problemas de confiabilidad, errores de seguridad de la memoria y fugas de información. Para evitar estos problemas, Android inicializa tanta memoria como sea posible.
Memoria de espacio de usuario inicializada cero
Desde Android 12, la memoria de pila se inicializa a cero en todos los códigos nativos de la plataforma (incluido JNI) y la memoria de pila se inicializa a cero en todos los procesos nativos de la plataforma (como netd
), pero no en el zygote
ni en las aplicaciones.
Se recomienda encarecidamente que las aplicaciones propias y de terceros creadas con el NDK utilicen el indicador del compilador -ftrivial-auto-var-init=zero
para inicializar a cero sus variables locales de pila. El compilador optimiza cualquier puesta a cero que sea innecesaria. Por ejemplo, cuando una variable local se inicializa explícitamente (como, int x = 123;
la variable x
se inicializa solo una vez). Si el programa tiene un búfer de pila grande en un punto de rendimiento, el desarrollador puede deshabilitar la inicialización usando un atributo del compilador:
__attribute__((__uninitialized__)) char buf[BUFSIZ];
Las aplicaciones también pueden optar por la inicialización del montón cero mediante el atributo de manifiesto android:nativeHeapZeroInitialized
. Alternativamente, la inicialización del montón cero se puede controlar en tiempo de ejecución con:
int mallopt(M_BIONIC_ZERO_INIT, level)
Donde el nivel es 0 o 1.
Memoria del kernel inicializada cero
La pila y el montón del kernel están inicializados en cero para los kernels GKI, lo cual es altamente recomendado por el CDD .
Para la inicialización de la pila, GKI usa la configuración CONFIG_INIT_STACK_ALL_ZERO
, lo que da como resultado la construcción del kernel usando el indicador del compilador -ftrivial-auto-var-init=zero
. Para la inicialización del montón, GKI utiliza CONFIG_INIT_ON_ALLOC_DEFAULT_ON
, lo que hace que todas las asignaciones del montón de páginas, SLAB y SLUB se inicialicen en cero cuando se crean. Esta opción es efectivamente similar a pasar init_on_alloc=1
como una opción de tiempo de arranque del kernel.
Informes de errores
Nuestras herramientas generan informes de errores detallados que contienen información adicional para ayudar con la depuración. El seguimiento adicional de la pila de asignación y desasignación ayuda a comprender mejor el ciclo de vida de una asignación determinada y conduce a errores de seguridad de la memoria que causan raíz mucho más rápido.
Durante el desarrollo, los proveedores deben monitorear la presencia de errores verificando /data/tombstones
y logcat
para detectar fallas nativas. Para obtener más información sobre la depuración del código nativo de Android, consulte la información aquí .