Nicht initialisierter Arbeitsspeicher in C und C++ ist eine häufige Ursache für Zuverlässigkeitsprobleme, Speichersicherheitsfehler und Informationslecks. Um diese Probleme zu vermeiden, initialisiert Android so viel Arbeitsspeicher wie möglich.
Mit Null initialisierter Nutzerbereichsspeicher
Seit Android 12 wird der Stack-Speicher in allen nativen Plattformcodes (einschließlich JNI) auf null initialisiert und der Heap-Speicher in allen nativen Plattformprozessen (z. B. netd
) auf null initialisiert, aber nicht im zygote
oder in Apps.
Wir empfehlen Ihnen dringend, das -ftrivial-auto-var-init=zero
-Compiler-Flag zu verwenden, um die lokalen Stackvariablen Ihrer eigenen Apps und Drittanbieter-Apps, die mit dem NDK erstellt wurden, auf null zu initialisieren. Der Compiler entfernt alle unnötigen Nullsetzungen.
Beispielsweise, wenn eine lokale Variable explizit initialisiert wird (z. B. int x = 123;
-Variable x
wird nur einmal initialisiert).
Wenn das Programm einen großen Stack-Puffer in einem Leistungshotspot hat, kann der Entwickler die Initialisierung mit einem Compilerattribut deaktivieren:
__attribute__((__uninitialized__)) char buf[BUFSIZ];
Apps können die Null-Initialisierung des Heaps auch mit dem Manifestattribut android:nativeHeapZeroInitialized
aktivieren.
Alternativ kann die Initialisierung des Null-Heaps zur Laufzeit mit folgenden Befehlen gesteuert werden:
int mallopt(M_BIONIC_ZERO_INIT, level)
Dabei ist „level“ 0 oder 1.
Mit Null initialisierter Kernelspeicher
Der Kernelstack und der Heap werden für GKI-Kernel auf Null initialisiert, was dringend vom CDD empfohlen wird.
Für die Stack-Initialisierung verwendet GKI die CONFIG_INIT_STACK_ALL_ZERO
-Konfiguration, wodurch der Kernel mit dem -ftrivial-auto-var-init=zero
-Compilerflag erstellt wird.
Für die Heap-Initialisierung verwendet GKI den CONFIG_INIT_ON_ALLOC_DEFAULT_ON
, wodurch alle Page-Heap-, SLAB- und SLUB-Zuweisungen beim Erstellen auf Null initialisiert werden. Diese Option entspricht im Grunde dem Übergeben von init_on_alloc=1
als Kerneloption zur Bootzeit.
Fehlerberichte
Unsere Tools generieren aussagekräftige Fehlerberichte mit zusätzlichen Informationen, die bei der Fehlerbehebung helfen. Der zusätzliche Stack-Trace für die Zuweisung und Deaktivierung hilft, den Lebenszyklus einer bestimmten Zuweisung besser zu verstehen und die Ursache von Speichersicherheitsfehlern viel schneller zu ermitteln.

Während der Entwicklung sollten Anbieter das Vorhandensein von Fehlern prüfen, indem sie /data/tombstones
und logcat
auf native Abstürze prüfen. Weitere Informationen zum Debuggen von nativem Android-Code finden Sie hier.