Android obsługuje wiele narzędzi do debugowania błędów pamięci. Każda z nich ma swoje zalety i wady. Poniżej znajdziesz informacje, które pomogą Ci wybrać najlepszą opcję. Ten dokument zawiera omówienie dostępnych narzędzi, dzięki czemu możesz zdecydować, które z nich chcesz dokładniej poznać. Aby uzyskać więcej informacji, zapoznaj się z dokumentami dotyczącymi poszczególnych narzędzi.
tl;dr
- W miarę możliwości używaj języka bezpiecznego dla pamięci, aby uniknąć błędów pamięci.
- Zawsze używaj PAC/BTI, aby ograniczyć ataki ROP/JOP
- Zawsze używaj GWP-ASan do wykrywania rzadkich błędów pamięci w produkcji.
- Używanie HWASan do wykrywania błędów pamięci podczas testowania
- Urządzenia obsługujące MTE nie są ogólnie dostępne. Dopóki to się nie zmieni, nie będziemy mogli Ci pomóc.
- Podczas testowania używaj Asana tylko w ostateczności.
Języki obsługiwane przez Memory Safe
Język bezpieczny dla pamięci to jedyny sposób na całkowite uniknięcie błędów pamięci i ich zminimalizowanie. Inne narzędzia na tej stronie mogą pomóc Ci w zwiększeniu bezpieczeństwa i niezawodności kodu z problemami z pamięcią, ale używanie języka bezpiecznego dla pamięci eliminuje cały rodzaj problemów.
Oficjalnie obsługiwane języki bezpieczne dla pamięci na Androidzie to Java i Kotlin. Większość aplikacji na Androida łatwiej jest tworzyć w jednym z tych języków.
Jednak niektórzy deweloperzy aplikacji dostarczają kod napisany w Rust, a jeśli czytasz tę stronę, prawdopodobnie masz dobry powód, aby używać kodu natywnego (ze względu na przenośność lub wydajność, a czasem z obu tych powodów). Rust to najlepszy wybór, jeśli chodzi o bezpieczeństwo pamięci w przypadku kodu natywnego na Androida. Zespół NDK niekoniecznie może pomóc Ci w rozwiązaniu problemów, które mogą się pojawić, jeśli zdecydujesz się na tę drogę, ale chcielibyśmy się o nich dowiedzieć.
PAC/BTI
Uwierzytelnianie wskaźnika i identyfikacja docelowych gałęzi, znane również jako PAC/BTI, to narzędzia do łagodzenia zagrożeń, które można stosować w produkcji. Chociaż są to osobne technologie, są kontrolowane przez ten sam parametr kompilatora, więc są zawsze używane razem.
Te funkcje są zgodne ze starszymi urządzeniami, na których nie są obsługiwane, ponieważ używane nowe instrukcje nie są wykonywane na starszych urządzeniach. Musisz też mieć odpowiednio nowe jądro i odpowiednio nową wersję systemu operacyjnego.
Szukanie paca
i bti
w /proc/cpuinfo
pozwala sprawdzić, czy masz wystarczająco nowy sprzęt i jądro. Android 12 (poziom API 31) zapewnia niezbędne wsparcie w przestrzeni użytkownika.
Zalety:
- Można włączyć we wszystkich wersjach bez powodowania problemów na starszych urządzeniach lub jądrach (ale upewnij się, że testujesz na kombinacji urządzenia, jądra i systemu operacyjnego, która obsługuje tę funkcję).
Wady:
- Dostępne tylko w przypadku aplikacji 64-bitowych
- Nie ogranicza błędów na urządzeniach, które nie obsługują tej funkcji.
- 1% narzut na rozmiar kodu
GWP-Asan
GWP-ASan może służyć do wykrywania błędów pamięci w polu, ale częstotliwość próbkowania jest zbyt niska, aby skutecznie ograniczyć błędy.
Zalety:
- Nie obciąża procesora ani pamięci.
- Łatwe w wdrożeniu: nie wymaga ponownego kompilowania kodu natywnego.
- Działa w przypadku aplikacji 32-bitowych
Wady:
- Niska częstotliwość próbkowania wymaga dużej liczby użytkowników, aby skutecznie znajdować błędy
- wykrywa tylko błędy stosu, a nie błędy stosu,
HWASan
Sanitizer adresów sprzętowych, znany też jako HWASan, najlepiej nadaje się do wykrywania błędów pamięci podczas testowania. Jest ona najbardziej przydatna w ramach testów automatycznych, zwłaszcza jeśli przeprowadzasz testy fuzz, ale w zależności od wymagań dotyczących wydajności aplikacji może być też przydatna na telefonach wysokiej klasy w trybie dogfood.
Zalety:
- Brak wyników fałszywie pozytywnych
- Wykrywa dodatkowe klasy błędów, których ASan nie może wykryć (użycie stosu po powrocie).
- Mniejszy odsetek wyników fałszywie negatywnych niż w przypadku MTE (1 na 256 vs. 1 na 16)
- Mniejsze obciążenie pamięci niż w przypadku ASan, który jest najbliższą alternatywą
Wady:
- Znaczące obciążenie procesora (~100%), rozmiar kodu (~50%) i pamięci (10–35%)
- Do wersji API 34 i NDK r26 wymagane jest zaflashowanie obrazu zgodnego z HWASan
- Działa tylko w przypadku aplikacji 64-bitowych.
MTE
Rozszerzenie z tagowaniem pamięci, zwane też MTE, to tańsza alternatywa dla HWASan. Oprócz funkcji debugowania i testowania można go używać do wykrywania i łagodzenia uszkodzeń pamięci w wersji produkcyjnej. Jeśli masz sprzęt do testowania kompilacji MTE, włącz go.
Zalety:
- Niski nakład pracy, który jest akceptowalny w przypadku wielu aplikacji w wersji produkcyjnej.
- Brak wyników fałszywie pozytywnych
- Nie wymaga ponownego skompilowania kodu w celu wykrywania błędów stosu (ale wymaga tego w przypadku błędów stosu)
Wady:
- W 2024 r. nie ma dostępnych na rynku urządzeń z domyślnie włączoną technologią MTE, ale dokumentacja firmy Arm zawiera informacje o włączaniu MTE na potrzeby testowania na Pixelu 8 lub Pixelu 8 Pro.
- Współczynnik wyników fałszywie negatywnych wynosi 1 na 16, a w przypadku HWASan – 1 na 256.
- Dostępne tylko w przypadku aplikacji 64-bitowych
- Wymaga tworzenia osobnych bibliotek na potrzeby kierowania na urządzenia z włączoną i bez włączonej obsługą MTE
ASan
Sanitizer adresów, znany też jako ASan, jest najstarszym i najbardziej dostępnym narzędziem. Jest on przydatny do wykrywania błędów pamięci podczas testowania i debugowania problemów, które występują tylko na starszych urządzeniach, na których nie można użyć innych narzędzi. W miarę możliwości preferuj HWASan.
Zalety:
- powszechnie dostępne, Może działać na urządzeniach z Androidem KitKat lub starszym.
- nie powoduje fałszywie pozytywnych ani fałszywie negatywnych wyników,
Wady:
- trudności z prawidłowym skompilowaniem i zapakowaniem aplikacji;
- Największy narzut ze wszystkich opcji: około 100% wykorzystania procesora, około 50% rozmiaru kodu, około 100% wykorzystania pamięci.
- Nie jest już obsługiwana
- zawiera znane błędy, które nie zostaną naprawione;