Zero zainicjowana pamięć

Częstą przyczyną problemów z niezawodnością jest niezainicjowana pamięć w językach C i C++. błędy związane z bezpieczeństwem pamięci i wyciekiem informacji. Aby uniknąć tych problemów, Android inicjuje jak najwięcej pamięci.

Zero zainicjowana pamięć w przestrzeni użytkownika

Od Androida 12 pamięć stosu nie jest inicjowana we wszystkich kodzie natywnym platformy (w tym JNI), a pamięć sterty ma wartość zero zainicjowane we wszystkich natywnych procesach platformy (takich jak netd) ale nie w zygote ani w aplikacjach.

Aplikacje własne i innych firm utworzone przy użyciu NDK są zdecydowanie zaleca się użycie flagi kompilatora -ftrivial-auto-var-init=zero do lokalnego inicjowania stosu na poziomie zero zmiennych. Kompilator optymalizuje wszystkie niepotrzebne zerowania. Jeśli na przykład zmienna lokalna została jawnie zainicjowana (np. zmienna int x = 123; x jest inicjowana tylko raz). Jeśli program ma duży bufor stosu podczas działania, jako hotspot, deweloper może wyłączyć inicjowanie za pomocą kompilatora :

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

Aplikacje mogą też włączyć inicjalizację sterty zerowy za pomocą android:nativeHeapZeroInitialized atrybut pliku manifestu. Inicjowanie sterty zerowe można też kontrolować w czasie działania z:

int mallopt(M_BIONIC_ZERO_INIT, level)

Gdzie poziom to 0 lub 1.

Zero zainicjowana pamięć jądra

Dla jądra GKI stos i sterta nie są zainicjowane zero, co jest silnie zalecane przez CDD.

Do inicjowania stosu GKI używa CONFIG_INIT_STACK_ALL_ZERO, co skutkuje utworzeniem jądra systemu operacyjnego przy użyciu flagi kompilatora -ftrivial-auto-var-init=zero. Do inicjowania sterty GKI używa metody CONFIG_INIT_ON_ALLOC_DEFAULT_ON – sterta wszystkich stron, SLAB i alokacje SLUB nie zainicjowane w momencie tworzenia. Ta opcja jest jest podobny do przekazywania interfejsu init_on_alloc=1 jako jądra systemu podczas uruchamiania.

Raporty o błędach

Nasze narzędzia generują szczegółowe raporty o błędach, które zawierają dodatkowe informacje który ułatwia debugowanie. Dodatkowy zrzut stosu alokacji i alokacji mogą pomóc w lepszym poznaniu cyklu życia danego przydziału i doprowadzeniu do powodująca o wiele szybsze występowanie błędów dotyczących bezpieczeństwa pamięci.

Przykład wygenerowanego raportu o błędzie
  narzędzie do bezpieczeństwa pamięci
Rysunek 1. Raporty o błędach generowane przez narzędzia do zapewniania bezpieczeństwa pamięci

W trakcie tworzenia aplikacji dostawcy powinni monitorować obecność błędów, sprawdzając /data/tombstones i logcat w przypadku awarii natywnych. Więcej informacji na temat: informacje na temat debugowania kodu natywnego na Androida znajdziesz tutaj.