Null initialisierter Speicher

Nicht initialisierter Speicher 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 Speicher wie möglich.

Null initialisierter Userspace-Speicher

Seit Android 12 ist der Stapelspeicher in allen plattformnativen Codes (einschließlich JNI) auf Null initialisiert und der Heapspeicher ist in allen plattformnativen Prozessen (z. B. netd ) auf Null initialisiert, jedoch nicht in der zygote oder in Apps.

Erst- und Drittanbieteranwendungen, die mit dem NDK erstellt wurden, wird dringend empfohlen, das Compiler-Flag -ftrivial-auto-var-init=zero zu verwenden, um ihre lokalen Stapelvariablen auf Null zu initialisieren. Der Compiler optimiert alle unnötigen Nullungen. Wenn beispielsweise eine lokale Variable explizit initialisiert wird (z. B. int x = 123; Variable x wird nur einmal initialisiert). Wenn das Programm über einen großen Stapelpuffer in einem Leistungs-Hotspot verfügt, kann der Entwickler die Initialisierung mithilfe eines Compiler-Attributs deaktivieren:

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

Anwendungen können sich auch für die Heap-Null-Initialisierung entscheiden, indem sie das Manifestattribut android:nativeHeapZeroInitialized verwenden. Alternativ kann die Heap-Null-Initialisierung zur Laufzeit gesteuert werden mit:

int mallopt(M_BIONIC_ZERO_INIT, level)

Wobei Level 0 oder 1 ist.

Null initialisierter Kernel-Speicher

Der Kernel-Stack und der Heap sind für GKI-Kernel auf Null initialisiert, was vom CDD dringend empfohlen wird.

Für die Stack-Initialisierung verwendet GKI die Konfiguration CONFIG_INIT_STACK_ALL_ZERO , was dazu führt, dass der Kernel mit dem Compiler-Flag -ftrivial-auto-var-init=zero erstellt wird. Für die Heap-Initialisierung verwendet GKI CONFIG_INIT_ON_ALLOC_DEFAULT_ON , wodurch alle Seiten-Heap-, SLAB- und SLUB-Zuweisungen bei ihrer Erstellung auf Null initialisiert werden. Diese Option ähnelt praktisch der Übergabe init_on_alloc=1 als Kernel-Bootzeitoption.

Fehlerberichte

Unsere Tools generieren aufschlussreiche Fehlerberichte, die zusätzliche Informationen enthalten, die beim Debuggen helfen. Die zusätzliche Zuordnungs- und Freigabe-Stack-Ablaufverfolgung trägt dazu bei, den Lebenszyklus einer bestimmten Zuordnung besser zu verstehen und führt viel schneller zu Root-verursachenden Speichersicherheitsfehlern.

Beispiel eines Fehlerberichts, der vom Speichersicherheitstool erstellt wurde
Abbildung 1 : Von Speichersicherheitstools generierte Fehlerberichte

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