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 używa znacznie mniej pamięci RAM w porównaniu do ASan, co sprawia, że nadaje się do czyszczenia całego systemu. HWASan jest dostępny tylko w systemie Android 10 i nowszych oraz tylko na sprzęcie AArch64.
Chociaż jest to przede wszystkim przydatne w przypadku kodu C/C++, HWASan może również pomóc w debugowaniu kodu Java, który powoduje awarie w C/C++ używanym do implementacji interfejsów Java. Jest to pomocne, ponieważ wyłapuje błędy pamięci, gdy się pojawią, wskazując bezpośrednio odpowiedzialny kod.
Możesz przesłać gotowe obrazy HWASan do obsługiwanych urządzeń Pixel ze strony ci.android.com ( szczegółowe instrukcje konfiguracji ).
W porównaniu do klasycznego ASan, HWASan ma:
- Podobne obciążenie procesora (~2x)
- Narzut o podobnym rozmiarze 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
- Wykorzystanie stosu po darmowym
- Stosowanie stosu poza zakresem
- Pokój za darmo/dziki za darmo
Dodatkowo HWASan wykrywa użycie stosu po zwrocie.
HWASan (tak samo jak ASan) jest kompatybilny z UBSan , oba mogą być włączone na celu w tym samym czasie.
Szczegóły i ograniczenia implementacji
HWASan opiera się na podejściu do oznaczania pamięci , w którym mała losowa wartość znacznika jest powiązana zarówno ze wskaźnikami, jak iz zakresami adresów pamięci. Aby dostęp do pamięci był prawidłowy, znaczniki wskaźnika i pamięci muszą być zgodne. HWASan opiera się na funkcji ignorowania górnego bajtu (TBI) ARMv8, zwanej również tagowaniem adresu wirtualnego , aby przechowywać znacznik wskaźnika w najwyższych bitach adresu.
Możesz przeczytać więcej o projekcie HWASan na stronie dokumentacji Clang.
Z założenia HWASan nie ma ograniczonych stref ASan do wykrywania przepełnień ani kwarantanny o ograniczonej pojemności ASan do wykrywania użycia po zwolnieniu. Z tego powodu HWASan może wykryć błąd bez względu na to, jak duże jest przepełnienie lub jak dawno pamięć została zwolniona. Daje to HWASan dużą przewagę nad ASan.
Jednak HWASan ma ograniczoną liczbę możliwych wartości tagów (256), co oznacza, że prawdopodobieństwo pominięcia jakiegokolwiek błędu podczas jednego wykonania programu wynosi 0,4%.
Wymagania
Najnowsze wersje (4.14+) popularnego jądra systemu Android obsługują standard HWASan od razu po zainstalowaniu. Konkretne gałęzie systemu Android 10 nie obsługują HWASan.
Obsługa HWASan w przestrzeni użytkownika jest dostępna począwszy od systemu Android 11 .
Jeśli pracujesz z innym jądrem, HWASan wymaga, aby jądro Linuksa akceptowało oznakowane wskaźniki w argumentach wywołań systemowych. Wsparcie dla tego zostało zaimplementowane w następujących zestawach poprawek:
- arm64 otagowany adres ABI
- arm64: odtaguj wskaźniki użytkownika przekazane do jądra
- mm: Unikaj tworzenia wirtualnych aliasów adresów w brk()/mmap()/mremap()
- arm64: Sprawdź poprawność otagowanych adresów w access_ok() wywoływanych z wątków jądra
Jeśli tworzysz z niestandardowym łańcuchem 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ę za pomocą HWASan:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
Dla wygody można dodać ustawienie SANITIZE_TARGET do definicji produktu, podobnie jak aosp_coral_hwasan .
Dla użytkowników zaznajomionych z AddressSanitizer, wiele złożoności kompilacji zniknęło:
- Nie trzeba uruchamiać make dwa razy.
- Kompilacje przyrostowe działają po wyjęciu z pudełka.
- Nie ma potrzeby flashowania danych użytkownika.
Zniknęły również niektóre ograniczenia AddressSanitizer:
- Obsługiwane są statyczne pliki wykonywalne.
- Można pominąć oczyszczanie dowolnego celu innego niż libc. W przeciwieństwie do ASan nie ma wymogu, że jeśli biblioteka jest oczyszczona, to każdy plik wykonywalny, który ją łączy, również musi być.
Przełączanie między HWASan i zwykłymi obrazami o tym samym (lub wyższym) numerze kompilacji można wykonać swobodnie. Nie jest wymagane wycieranie urządzenia.
Aby pominąć oczyszczanie modułu, użyj LOCAL_NOSANITIZE := hwaddress
(Android.mk) lub sanitize: { hwaddress: false }
(Android.bp).
Odkażanie poszczególnych celów
HWASan można włączyć na cel w zwykłej (nieodczyszczonej) kompilacji, o ile libc.so
jest również oczyszczony. Dodaj hwaddress: true
do bloku sanitize w "libc_defaults"
w bionic/libc/Android.bp. Następnie zrób to samo w celu, nad którym pracujesz.
Należy zauważyć, że oczyszczanie 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 wewnątrz libc.so
. Może to wyłapać błędy nawet w plikach binarnych, w których HWASan nie był włączony, jeśli zły dostęp do pamięci jest w libc.so
(np. pthread_mutex_unlock()
w muteksie delete()
ed).
Nie trzeba zmieniać żadnych plików kompilacji, jeśli cała platforma jest zbudowana przy użyciu HWASan.
Stacja Flash
Do celów programistycznych możesz sflashować kompilację AOSP z obsługą HWASan na urządzenie Pixel z odblokowanym bootloaderem za pomocą Flashstation . Wybierz cel _hwasan, np. aosp_flame_hwasan-userdebug. Zobacz dokumentację NDK dla HWASan dla deweloperów aplikacji, aby uzyskać więcej informacji.
Lepsze ślady stosu
HWASan używa szybkiego rozwijania opartego na wskaźniku ramki do rejestrowania śladu stosu dla każdego zdarzenia alokacji pamięci i cofnięcia alokacji w programie. Android domyślnie włącza wskaźniki ramek w kodzie AArch64, więc działa to świetnie w praktyce. Jeśli chcesz odprężyć się za pomocą kodu zarządzanego, ustaw HWASAN_OPTIONS=fast_unwind_on_malloc=0
w środowisku procesu. Zwróć uwagę, że złe śledzenie stosu dostępu do pamięci używa domyślnie „powolnego” rozwijania; to ustawienie ma wpływ tylko na ślady alokacji i cofnięcia alokacji. Ta opcja może bardzo mocno obciążać procesor, w zależności od obciążenia.
Symbolizowanie
Zobacz Symbolizacja w „Zrozumienie raportów HWASan”.
HWASan w aplikacjach
Podobnie jak AddressSanitizer, HWASan nie widzi kodu Java, ale może wykrywać błędy w bibliotekach JNI. W przeciwieństwie do ASan, uruchamianie aplikacji HWASan na urządzeniu innym niż HWASan nie jest obsługiwane.
Na urządzeniu HWASan aplikacje można sprawdzić za pomocą HWASan, budując ich kod z SANITIZE_TARGET:=hwaddress
w Make lub -fsanitize=hwaddress
w flagach kompilatora. Więcej informacji znajdziesz w dokumentacji dla programistów aplikacji .