Memoria inizializzata a zero

La memoria non inizializzata in C e C++ è una causa comune di problemi di affidabilità, bug di sicurezza della memoria e fughe di informazioni. Per evitare questi problemi, Android inizializza quanta più memoria possibile.

Memoria dello spazio utente inizializzata a zero

Da Android 12, la memoria dello stack è inizializzata a zero in tutto il codice nativo della piattaforma (incluso JNI) e la memoria heap è inizializzata a zero in tutti i processi nativi della piattaforma (come netd) ma non in zygote o nelle app.

Per le app proprietarie e di terze parti create con l'NDK, è vivamente consigliato di utilizzare il -ftrivial-auto-var-init=zero flag del compilatore per inizializzare a zero le variabili locali dello stack. Il compilatore ottimizza l'eventuale azzeramento non necessario. Ad esempio, quando una variabile locale viene inizializzata esplicitamente (ad esempio, la variabile int x = 123; viene inizializzata solo una volta).x Se il programma ha un buffer dello stack di grandi dimensioni in un punto di hotspot delle prestazioni, lo sviluppatore può disattivare l'inizializzazione utilizzando un attributo del compilatore:

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

Le app possono anche attivare l'inizializzazione dell'heap zero utilizzando l'attributo manifest android:nativeHeapZeroInitialized. In alternativa, l'inizializzazione dell'heap zero può essere controllata in fase di esecuzione con:

int mallopt(M_BIONIC_ZERO_INIT, level)

dove il livello è 0 o 1.

Memoria del kernel inizializzata a zero

Lo stack e l'heap del kernel sono inizializzati a zero per i kernel GKI, fortemente consigliati dal CDD.

Per l'inizializzazione dello stack, GKI utilizza la configurazione CONFIG_INIT_STACK_ALL_ZERO, che comporta la compilazione del kernel utilizzando il flag del compilatore -ftrivial-auto-var-init=zero. Per l'inizializzazione dell'heap, GKI utilizza CONFIG_INIT_ON_ALLOC_DEFAULT_ON, che azzera tutte le allocazioni di heap di pagine, SLAB e SLUB al momento della loro creazione. Questa opzione è in pratica simile al passaggio di init_on_alloc=1 come opzione di caricamento del kernel.

Segnalazioni di bug

I nostri strumenti generano segnalazioni di bug dettagliate che contengono informazioni aggiuntive per facilitare il debug. La traccia dello stack di allocazione e deallocazione aggiuntiva consente di comprendere meglio il ciclo di vita di una determinata allocazione e di individuare molto più rapidamente i bug di sicurezza della memoria alla radice.

Esempio di segnalazione di bug generata
  dallo strumento di sicurezza della memoria
Figura 1: segnalazioni di bug generate dagli strumenti di sicurezza della memoria

Durante lo sviluppo, i fornitori devono monitorare la presenza di bug controllando se /data/tombstones e logcat presentano arresti anomali nativi. Per ulteriori informazioni sul debugging del codice nativo di Android, consulta le informazioni qui.