HWAAddressSanitizer

Zobacz Omówienie raportów HWASan , aby uzyskać informacje na temat odczytywania awarii HWASan!

Wspomagany sprzętowo AddressSanitizer (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 do ASan, co czyni go odpowiednim do czyszczenia całego systemu. HWASan jest dostępny tylko na Androidzie 10 i nowszych wersjach oraz tylko na sprzęcie AArch64.

Chociaż HWASan jest przede wszystkim przydatny w przypadku kodu C/C++, może również pomóc w debugowaniu kodu Java, który powoduje awarie w języku C/C++ używanym do implementacji interfejsów Java. Jest to pomocne, ponieważ wychwytuje błędy pamięci, gdy się pojawią, wskazując bezpośrednio odpowiedzialny za to kod.

Możesz flashować gotowe obrazy HWASan na obsługiwanych urządzeniach Pixel ze strony ci.android.com ( szczegółowe instrukcje konfiguracji ).

W porównaniu do klasycznego ASan, HWASan posiada:

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

HWASan wykrywa ten sam zestaw błędów co ASan:

  • Przepełnienie/niedopełnienie bufora stosu i sterty
  • Użyj sterty po darmowym
  • Użycie stosu poza zakresem
  • Podwójnie wolny/dziki wolny

Dodatkowo HWASan wykrywa użycie stosu po powrocie.

HWASan (taki sam jak ASan) jest kompatybilny z UBSan , oba mogą być włączone na obiekcie docelowym w tym samym czasie.

Szczegóły implementacji i ograniczenia

HWASan opiera się na metodzie znakowania pamięci , w której mała losowa wartość znacznika jest powiązana zarówno ze wskaźnikami, jak i zakresami adresów pamięci. Aby dostęp do pamięci był ważny, wskaźnik i znaczniki pamięci muszą być zgodne. HWASan opiera się na funkcji ARMv8 ignorowania górnego bajtu (TBI), zwanej także tagowaniem adresu wirtualnego , do przechowywania znacznika wskaźnika w najwyższych bitach adresu.

Więcej informacji na temat projektu HWASan można znaleźć na stronie dokumentacji Clang.

Z założenia HWASan nie posiada czerwonych stref ASan o ograniczonym rozmiarze do wykrywania przepełnień ani kwarantanny o ograniczonej pojemności ASan do wykrywania użycia po czasie wolnym. Z tego powodu HWASan może wykryć błąd bez względu na to, jak duże jest przepełnienie i jak dawno temu pamięć została zwolniona. Daje to HWASan dużą przewagę nad ASan.

Jednak HWASan ma ograniczoną liczbę możliwych wartości znaczników (256), co oznacza, że ​​istnieje 0,4% prawdopodobieństwo pominięcia jakiegokolwiek błędu podczas jednego wykonania programu.

Wymagania

Najnowsze wersje (4.14+) wspólnego jądra Androida obsługują HWASan od razu po wyjęciu z pudełka. Gałęzie specyficzne dla Androida 10 nie obsługują HWASan.

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

Jeśli pracujesz z innym jądrem, HWASan wymaga, aby jądro Linuksa akceptowało oznaczone wskaźniki w argumentach wywołań systemowych. Obsługa tego została zaimplementowana w następujących zestawach poprawek:

Jeśli budujesz przy użyciu niestandardowego łańcucha narzędzi, upewnij się, że zawiera on wszystko, aż do zatwierdzenia LLVM c336557f .

Korzystanie z HWASan

Użyj następujących poleceń, aby zbudować całą platformę przy użyciu HWASan:

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, podobnie jak aosp_coral_hwasan .

Użytkownicy zaznajomieni z AddressSanitizer zniknęli z powodu dużej złożoności kompilacji:

  • Nie ma potrzeby dwukrotnie uruchamiać make.
  • Kompilacje przyrostowe działają od razu po wyjęciu z pudełka.
  • Nie ma potrzeby flashowania danych użytkownika.

Zniknęły również niektóre ograniczenia programu AddressSanitizer:

  • Obsługiwane są statyczne pliki wykonywalne.
  • Można pominąć oczyszczanie dowolnego celu innego niż libc. Inaczej niż w przypadku ASana, nie ma wymogu, że jeśli biblioteka zostanie oczyszczona, to musi to zrobić również każdy plik wykonywalny, który ją łączy.

Przełączanie pomiędzy HWASan i zwykłymi obrazami o tym samym (lub wyższym) numerze kompilacji może odbywać się swobodnie. Wycieranie urządzenia nie jest wymagane.

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

Dezynfekcja poszczególnych celów

HWASan można włączyć dla każdego celu w zwykłej (nie oczyszczonej) kompilacji, o ile libc.so również zostanie oczyszczone. Dodaj hwaddress: true do bloku sanitize w "libc_defaults" w bionic/libc/Android.bp. Następnie wykonaj to samo w przypadku celu, nad którym pracujesz.

Należy pamiętać, że oczyszczanie biblioteki libc umożliwia oznaczanie alokacji pamięci sterty w całym systemie, a także sprawdzanie znaczników pod kątem operacji na pamięci w libc.so Może to wychwycić błędy nawet w plikach binarnych, w których nie włączono HWASan, jeśli zły dostęp do pamięci jest w libc.so (np. pthread_mutex_unlock() w muteksie delete() ed).

Nie jest konieczna zmiana żadnych plików kompilacji, jeśli cała platforma jest zbudowana przy użyciu HWASan.

Flashstation

Do celów programistycznych możesz sflashować wersję AOSP z włączoną obsługą HWASan na urządzenie Pixel z odblokowanym programem ładującym za pomocą Flashstation . Wybierz cel _hwasan, np. aosp_flame_hwasan-userdebug. Więcej szczegółów można znaleźć w dokumentacji NDK dla HWASan dla twórców aplikacji.

Lepsze ślady stosu

HWASan używa szybkiego narzędzia odwijającego opartego na wskaźnikach klatek do rejestrowania śledzenia stosu dla każdego zdarzenia alokacji i zwolnienia pamięci w programie. Android domyślnie włącza wskaźniki ramek w kodzie AArch64, więc sprawdza się to świetnie w praktyce. Jeśli chcesz odpocząć w kodzie zarządzanym, ustaw HWASAN_OPTIONS=fast_unwind_on_malloc=0 w środowisku procesu. Należy pamiętać, że ślady stosu złego dostępu do pamięci domyślnie korzystają z „powolnego” rozwijacza; to ustawienie wpływa tylko na ślady alokacji i dezalokacji. Ta opcja może bardzo obciążać procesor, w zależności od obciążenia.

Symbolizowanie

Zobacz Symbolizację w „Zrozumienie raportów HWASan”.

HWASan w aplikacjach

Podobnie jak AddressSanitizer, HWASan nie może zajrzeć do kodu Java, ale może wykryć błędy w bibliotekach JNI. Do wersji Androida 14 uruchamianie aplikacji HWASan na urządzeniu innym niż HWASan nie było obsługiwane.

Na urządzeniu HWASan aplikacje można sprawdzać za pomocą HWASan, budując swój kod za pomocą SANITIZE_TARGET:=hwaddress w Make lub -fsanitize=hwaddress we flagach kompilatora. Na urządzeniu innym niż HWASan (z systemem Android 14 lub nowszym) należy dodać ustawienie pliku wrap.sh LD_HWASAN=1 . Więcej szczegółów znajdziesz w dokumentacji dla programistów aplikacji .