Android obsługuje wiele narzędzi do debugowania błędów pamięci. Każda z nich ma swoje zalety. Zapoznaj się z poniższymi wskazówkami, aby zdecydować, która z nich będzie najlepsza w Twoim przypadku. Ten dokument zawiera przegląd dostępnych narzędzi, co pozwala Ci podjąć decyzję o tym, które z nich warto zbadać. Jest on jednak zwięzły. Więcej informacji znajdziesz w dokumentacji poszczególnych narzędzi.
TL;DR
- Aby uniknąć błędów pamięci, w miarę możliwości używaj języka bezpiecznego dla pamięci.
- Zawsze używaj PAC/BTI do łagodzenia ataków ROP/JOP
- Zawsze używaj GWP-ASan do wykrywania rzadkich błędów pamięci w środowisku produkcyjnym
- Używanie HWASan do wykrywania błędów pamięci podczas testowania
- Urządzenia obsługujące MTE nie są ogólnie dostępne w 2023 r., ale warto z nich korzystać, jeśli wykrywasz błędy w środowisku produkcyjnym
- Używaj ASan podczas testowania tylko w ostateczności
Języki, w których dostępna jest pamięć
Użycie języka bezpiecznego dla pamięci to jedyny sposób, aby całkowicie uniknąć błędów związanych z pamięcią i ograniczyć ich skutki. Inne narzędzia na tej stronie mogą pomóc zwiększyć bezpieczeństwo i niezawodność kodu pamięci. Jednak użycie języka bezpiecznego dla pamięci eliminuje całą grupę problemów.
Oficjalnie obsługiwanymi językami bezpieczeństwa pamięci na Androidzie są Java i Kotlin. Większość aplikacji na Androida jest łatwiejsza w tworzeniu w jednym z tych języków.
Pamiętaj, że kod wysyłki dla deweloperów aplikacji jest napisany w Rust. Jeśli czytasz tę stronę, prawdopodobnie masz ku temu dobry powód, by potrzebować kodu natywnego (przenośność, wydajność lub jedno i drugie). Rust to najlepszy wybór w przypadku bezpiecznego dla pamięci kodu natywnego na Androida. Zespół NDK nie musi pomóc Ci z problemami, które napotkasz, jeśli się na to zdecydujesz, ale chętnie dowiemy się o nich.
PAC/BTI
Uwierzytelnianie wskaźnika oraz identyfikacja celu gałęzi (nazywane też PAC/BTI) to narzędzia do ograniczania ryzyka, odpowiednie do stosowania w środowisku produkcyjnym. Chociaż są to osobne technologie, są one kontrolowane przez tę samą flagę kompilatora, więc zawsze są używane razem.
Te funkcje są wstecznie zgodne z urządzeniami, które ich nie obsługują, ponieważ nowe instrukcje nie działają na wcześniejszych urządzeniach. Niezbędne jest również nowe jądro i wystarczająca wersja systemu operacyjnego.
Wyszukiwanie paca
i bti
w /proc/cpuinfo
pokaże Ci, czy masz wystarczająco dużo nowego sprzętu i nowe jądro. Android 12 (API 31) ma niezbędną obsługę przestrzeni użytkownika.
Zalety:
- Można ją włączyć we wszystkich kompilacjach, nie powodując problemów na starszych urządzeniach lub jądrach (ale upewnij się, że testujesz ją na takiej kombinacji urządzenia, jądra i systemu operacyjnego, która obsługuje tę funkcję).
Wady:
- Dostępne tylko w aplikacjach 64-bitowych
- Nie eliminuje błędów na urządzeniach, które ich nie obsługują
- Narzut na rozmiar kodu 1%
GWP-Asan
Do wykrywania błędów pamięci w polu można używać narzędzia GWP-ASan, ale częstotliwość próbkowania jest zbyt niska, aby skutecznie przeciwdziałać problemom.
Zalety:
- Brak znacznego obciążenia procesora i pamięci.
- Proste do wdrożenia: nie wymaga ponownego kompilowania kodu natywnego
- Działa w aplikacjach 32-bitowych
Wady:
- Niska częstotliwość próbkowania wymaga dużej liczby użytkowników, aby skutecznie znajdować błędy
- Wykrywanie tylko błędów sterty, a nie błędów stosu
HWASan
Sprzęt do dezynfekcji adresów (HWASan) najlepiej nadaje się do wykrywania błędów pamięci podczas testowania. Jest on najbardziej przydatny w przypadku testów automatycznych, zwłaszcza gdy przeprowadzasz testy z dużą szybkością. Jednak w zależności od potrzeb w zakresie wydajności aplikacji może być też używany w wersji testowej na zaawansowanych telefonach komórkowych.
Zalety:
- Brak wyników fałszywie pozytywnych
- Wykrywa dodatkowe klasy błędów, których ASan nie może używać (używanie stosu po zwróceniu)
- Niższy współczynnik wyników fałszywie negatywnych niż MTE (1 na 256 w porównaniu z 1 na 16)
- Mniejszy zużycie pamięci niż w przypadku ASan, jego najbliższa alternatywa
Wady:
- Znaczący (ok. 100%), rozmiar kodu (ok. 50%) i ilość pamięci (10%–35%)
- Do interfejsów API 34 i NDK r26 wymagane jest przeprowadzenie aktualizacji obrazu zgodnego z HWASan
- Działa tylko w aplikacjach 64-bitowych
MTE
Rozszerzenie do tagowania pamięci, znane też jako MTE, to tańsza alternatywa dla HWASan. Poza funkcjami debugowania i testowania można też używać jej do wykrywania i łagodzenia uszkodzeń pamięci w środowisku produkcyjnym. Jeśli masz sprzęt do testowania kompilacji MTE, włącz go.
Zalety:
- Na tyle niski koszt, że będzie tolerowany w przypadku wielu aplikacji w wersji produkcyjnej
- Brak wyników fałszywie pozytywnych
- Nie wymaga ponownego kompilowania kodu w celu wykrywania błędów sterty (ale robi to do wykrywania błędów stosu)
Wady:
- W 2024 r. nie ma dostępnych komercyjnie urządzeń z włączoną domyślnie obsługą MTE. Dokumentacja firmy Armer wyjaśnia, jak włączyć MTE do testów na Pixelu 8/Pixelu 8 Pro.
- Współczynnik wyników fałszywie ujemnych 1 na 16 w porównaniu do 1 HWASan na 256
- Dostępne tylko w aplikacjach 64-bitowych
- Wymaga utworzenia osobnych bibliotek do kierowania zarówno na urządzenia z obsługą MTE, jak i bez niego
ASan
Narzędzie do dezynfekcji adresów (ASan) to najstarsze i najpowszechniej dostępne narzędzie. Jest on przydatny w przypadku błędów pamięci podczas testowania i debugowania problemów, które mają wpływ tylko na stare urządzenia, na których nie ma żadnych innych narzędzi. Gdy tylko jest to możliwe, wybieraj HWASan.
Zalety:
- Powszechnie dostępne. Może działać na urządzeniach starszych niż KitKat
- Prawidłowo używane nie są wyniki fałszywie pozytywne ani negatywne
Wady:
- Trudności z prawidłowym stworzeniem i zapakowaniem
- Największy narzut spośród wszystkich opcji: ok. 100% procesora, rozmiar kodu ok. 50%, wykorzystanie pamięci ok. 100%
- Funkcja nie jest już obsługiwana
- Zawiera znane błędy, których nie naprawimy