AdresSanitizer wspomagany przez sprzęt

Aby dowiedzieć się, jak interpretować raporty HWASan, przeczytaj artykuł Informacje o raportach HWASan.

AdresSanitizer z obsługą sprzętową (HWASan) to narzędzie do wykrywania błędów pamięci podobne do AddressSanitizer. HWASan zużywa znacznie mniej pamięci RAM w porównaniu z ASan, co czyni go odpowiednim do sterylizacji całego systemu. HWASan jest dostępny tylko na Androidzie 10 lub nowszym i tylko na sprzęcie AArch64.

HWASan jest przydatny przede wszystkim w przypadku kodu C/C++, ale może też pomóc w debugowaniu kodu Java, który powoduje awarie kodu C/C++ używanego do implementowania interfejsów Java. Jest on przydatny, ponieważ wykrywa błędy pamięci w momencie ich wystąpienia i wskazuje kod, który je wywołuje.

Gotowe obrazy HWASan można wgrać na obsługiwane urządzenia Pixel ze strony ci.android.com (szczegółowe instrukcje konfiguracji).

W porównaniu z klasyczną funkcją ASan funkcja HWASan:

  • Podobny narzut procesora (~2x)
  • Nadmiarowy rozmiar kodu (40–50%)
  • Znacznie mniejsze obciążenie pamięci RAM (10–35%)

HWASan wykrywa te same błędy co ASan:

  • Przepełnienie/niedopełnienie bufora stosu i kupy
  • Użycie sterty po zwalnianiu
  • Użycie zasobów z poziomu zewnętrznego
  • podwójne wolne/bezpieczne

Dodatkowo HWASan wykrywa wykorzystanie stosu po powrocie.

HWASan (tak samo jak ASan) jest zgodny z UBSan. Oba mogą być włączone na tym samym celu jednocześnie.

Szczegóły implementacji i ograniczenia

HWASan opiera się na podejściu tagowania pamięci, w którym mała losowa wartość tagu jest powiązana zarówno z wskaźnikami, jak i z zakresami adresów pamięci. Aby dostęp do pamięci był prawidłowy, tagi wskaźnika i pamięci muszą być zgodne. HWASan korzysta z funkcji ARMv8, która ignoruje najwyższy bajt (TBI), czyli tagowanie adresów wirtualnych, aby przechowywać tag wskaźnika w najwyższych bitach adresu.

Więcej informacji o projektowaniu HWASan znajdziesz w dokumentacji Clang.

Z założenia HWASan nie ma czerwonych stref o ograniczonej wielkości w ASan na potrzeby wykrywania przepełnienia ani kwarantanny o ograniczonej pojemności w ASan na potrzeby wykrywania użycia po okresie bezpłatnym. Z tego powodu HWASan może wykryć błąd niezależnie od tego, jak duży jest przepełniony obszar lub jak dawno przydzielona pamięć została zwolniona. Daje to HWASan dużą przewagę nad ASan.

HWASan ma jednak ograniczoną liczbę możliwych wartości tagów (256), co oznacza, że podczas jednego uruchomienia programu istnieje 0,4% prawdopodobieństwo, że nie zostanie wykryty żaden błąd.

Wymagania

Najnowsze wersje (4.14+) wspólnego jądra Androida obsługują HWAS „z pudełka”. Gałęzie przeznaczone do Androida 10 nie obsługują HWASan.

Obsługa przestrzeni użytkownika dla HWASan jest dostępna od Androida 11.

Jeśli używasz innego jądra, HWASan wymaga, aby jądro Linuxa akceptowało otagowane wskaźniki w argumentach wywołania systemu. Obsługa tej funkcji została wdrożona w tych zbiorach poprawek upstream:

Jeśli kompilujesz za pomocą niestandardowego zestawu narzędzi, upewnij się, że zawiera on wszystko do commita LLVM c336557f.

Korzystanie z HWASan

Aby utworzyć całą platformę za pomocą HWASan, użyj tych poleceń:

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

Dla wygody możesz dodać ustawienie SANITIZE_TARGET do definicji produktu, na przykład aosp_coral_hwasan.

Użytkownicy znający narzędzie AddressSanitizer nie muszą już zajmować się wieloma złożonymi kwestiami związanymi z kompilacją:

  • Nie musisz uruchamiać make dwukrotnie.
  • Kompilacje przyrostowe działają od razu po zainstalowaniu.
  • Nie trzeba flashować danych użytkownika.

Usunięto też niektóre ograniczenia związane z AddressSanitizer:

  • Obsługiwane są statyczne pliki wykonywalne.
  • Możesz pominąć sterylizację dowolnego celu innego niż libc. W przeciwieństwie do ASan nie ma wymogu, aby biblioteka była skanowana, a wszystkie pliki wykonywalne, do których się odwołuje, również.

Przełączanie się między obrazami HWASan i zwykłymi obrazami o tym samym (lub wyższym) numerze kompilacji jest możliwe. Nie musisz czyścić urządzenia.

Aby pominąć sterylizację modułu, użyj opcji LOCAL_NOSANITIZE := hwaddress (Android.mk) lub sanitize: { hwaddress: false } (Android.bp).

Sanitize individual targets

HWASan można włączyć w ramach poszczególnych docelowych wersji w ramach zwykłej (nieoczyszczonej) wersji, o ile libc.so jest również oczyszczona. Dodaj hwaddress: true do bloku sanitize w "libc_defaults" w bionic/libc/Android.bp. Następnie zrób to samo w przypadku celu, nad którym pracujesz.

Pamiętaj, że sterylizacja biblioteki libc umożliwia oznaczanie przydziałów pamięci stosu w całym systemie, a także sprawdzanie tagów pod kątem operacji na pamięci w funkcji libc.so. Może to wykrywać błędy nawet w binarnych plikach, w których HWASan nie był włączony, jeśli dostęp do pamięci był nieprawidłowy w ramach libc.so(np. pthread_mutex_unlock() na zablokowanym delete().

Jeśli cała platforma jest kompilowana za pomocą HWASan, nie trzeba zmieniać żadnych plików kompilacji.

Flashstation

W celu ułatwienia procesu tworzenia możesz za pomocą Flashstation wgrać na urządzeniu Pixel z odblokowanym bootloaderem kompilację AOSP z obsługą HWASan. Wybierz obiekt _hwasan, np. aosp_flame_hwasan-userdebug. Więcej informacji znajdziesz w dokumentacji NDK dotyczącej HWASan dla deweloperów aplikacji.

Lepsze zrzuty stosu

HWASan używa szybkiego odwijacza opartego na wskazniku ramki do rejestrowania ścieżki stosu dla każdego zdarzenia przydzielenia i zwolnienia pamięci w programie. Android domyślnie włącza wskaźniki ramki w kodzie AArch64, dzięki czemu działa to świetnie w praktyce. Jeśli chcesz odtworzyć kod zarządzany, ustaw zmienną HWASAN_OPTIONS=fast_unwind_on_malloc=0 w środowisku procesu. Pamiętaj, że śledzenie błędów dostępu do pamięci w formie sterty jest domyślnie używane w ramach „wolnego” odwijania. To ustawienie dotyczy tylko śledzenia alokacji i zwolnienia alokacji. Ta opcja może mocno obciążać procesor, w zależności od obciążenia.

Symbolizacja

Zapoznaj się z sekcją Symbolizacja w artykule „Interpretowanie raportów HWASan”.

HWASan w aplikacjach

Podobnie jak narzędzie AddressSanitizer, HWASan nie może przeglądać kodu Java, ale może wykrywać błędy w bibliotekach JNI. Do Androida 14 uruchamianie aplikacji HWASan na urządzeniach innych niż HWASan było nieobsługiwane.

Na urządzeniu HWASan można sprawdzić aplikacje za pomocą HWASan, kompilując ich kod za pomocą parametru SANITIZE_TARGET:=hwaddress w Make lub -fsanitize=hwaddress w flagach kompilatora. Na urządzeniu, które nie jest urządzeniem HWASan (z Androidem 14 lub nowszym), należy dodać ustawienie pliku wrap.sh:LD_HWASAN=1. Więcej informacji znajdziesz w dokumentacji dla deweloperów aplikacji.