Android unterstützt mehrere Tools zur Fehlerbehebung bei Speicherfehlern. Jede Methode hat ihre Vor- und Nachteile. Lesen Sie unten, welche für Ihren Anwendungsfall am besten geeignet ist. In diesem Dokument finden Sie eine Übersicht über die verfügbaren Tools, damit Sie entscheiden können, welche Sie genauer untersuchen möchten. Es soll jedoch kurz und bündig sein. Lesen Sie daher die toolspezifischen Dokumente, um weitere Informationen zu erhalten.
Kurzfassung
- Verwenden Sie nach Möglichkeit eine speichersichere Sprache, um Speicherfehler zu vermeiden.
- Verwenden Sie immer PAC/BTI, um ROP-/JOP-Angriffe abzuwehren.
- Verwenden Sie immer GWP-ASan, um seltene Arbeitsspeicherfehler in der Produktion zu erkennen.
- HWASan verwenden, um Speicherfehler während des Tests zu erkennen
- MTE ist auf ausgewählten Geräten als Option verfügbar.
- ASan während des Tests nur als letztes Mittel verwenden
Speichersichere Sprachen
Speichersichere Sprachen sind die einzige Möglichkeit, Speicherfehler vollständig zu vermeiden und zu beheben. Die anderen Tools auf dieser Seite können Ihnen helfen, speichersicheren Code sicherer und zuverlässiger zu machen. Wenn Sie jedoch eine speichersichere Sprache verwenden, werden alle Probleme dieser Art vermieden.
Die offiziell unterstützten speichersicheren Sprachen für Android sind Java und Kotlin. Die meisten Android-Anwendungen lassen sich einfacher in einer dieser Sprachen entwickeln.
Es gibt jedoch App-Entwickler, die in Rust geschriebenen Code ausliefern. Wenn Sie diese Seite lesen, haben Sie wahrscheinlich einen guten Grund, nativen Code zu benötigen (Portabilität, Leistung oder beides). Rust ist die beste Wahl für speichersicheren nativen Code auf Android. Das NDK-Team kann Ihnen bei Problemen, die Sie auf diese Weise haben, nicht unbedingt helfen, aber wir sind daran interessiert, davon zu erfahren.
PAC/BTI
Pointer Authentication and Branch Target Identification (PAC/BTI) sind Tools zur Risikominderung, die sich für den Einsatz in der Produktion eignen. Obwohl es sich um separate Technologien handelt, werden sie durch dasselbe Compiler-Flag gesteuert und daher immer zusammen verwendet.
Diese Funktionen sind abwärtskompatibel mit Geräten, die sie nicht unterstützen, da die neuen Anweisungen auf älteren Geräten keine Auswirkungen haben. Außerdem ist ein aktueller Kernel und eine aktuelle Version des Betriebssystems erforderlich. Wenn Sie in /proc/cpuinfo
nach paca
und bti
suchen, sehen Sie, ob Sie neue Hardware und einen neuen Kernel haben. Android 12 (API 31) bietet die erforderliche Unterstützung im Userspace.
Vorteile:
- Kann in allen Builds aktiviert werden, ohne Probleme auf älteren Geräten oder Kernels zu verursachen (aber stellen Sie sicher, dass Sie tatsächlich auf einer Geräte-/Kernel-/Betriebssystemkombination getestet haben, die sie unterstützt).
Nachteile:
- Nur für 64‑Bit-Apps verfügbar
- Fehler auf Geräten, die die Funktion nicht unterstützen, werden dadurch nicht behoben.
- 1% Overhead bei der Codegröße
GWP-Asan
GWP-ASan kann verwendet werden, um Arbeitsspeicherfehler im Feld zu erkennen, aber die Samplingrate ist zu niedrig, um eine effektive Gegenmaßnahme zu sein.
Vorteile:
- Kein signifikanter CPU- oder Arbeitsspeicheraufwand
- Einfache Bereitstellung: Der native Code muss nicht neu erstellt werden.
- Funktioniert für 32-Bit-Apps
Nachteile:
- Bei einer niedrigen Stichprobenrate ist eine große Anzahl von Nutzern erforderlich, um Fehler effektiv zu finden.
- Es werden nur Heap-Fehler erkannt, keine Stack-Fehler.
HWASan
Hardware Address Sanitizer (HWASan) ist die beste Option, um Speicherfehler während des Tests zu erkennen. Die Funktion ist am nützlichsten in Verbindung mit automatisierten Tests, insbesondere wenn Sie Fuzz-Tests durchführen. Je nach den Leistungsanforderungen Ihrer App kann sie aber auch auf High-End-Smartphones in einer Dogfood-Umgebung verwendet werden.
Vorteile:
- Keine falsch positiven Ergebnisse
- Erkennt zusätzliche Fehlerklassen, die ASan nicht erkennen kann (Stack-Nutzung nach Rückgabe).
- Geringere Rate an falsch negativen Ergebnissen als bei MTE (1 von 256 im Vergleich zu 1 von 16)
- Geringerer Arbeitsspeicheraufwand als bei ASan, der nächstbesten Alternative
Nachteile:
- Erheblicher Overhead bei CPU (~100 %), Codegröße (~50 %) und Arbeitsspeicher (10–35 %)
- Bis API 34 und NDK r26 ist das Flashen eines HWASan-kompatiblen Images erforderlich.
- Funktioniert nur bei 64‑Bit-Apps
MTE
Die Memory Tagging Extension (MTE), auch bekannt als „Memory Tagging“, ist eine kostengünstigere Alternative zu HWASan. Neben den Debugging- und Testfunktionen kann es auch verwendet werden, um Speicherbeschädigungen in der Produktion zu erkennen und zu beheben. Wenn Sie die Hardware zum Testen von MTE-Builds haben, sollten Sie die Funktion aktivieren.
Vorteile:
- Geringer Overhead, der für viele Apps in der Produktion tolerierbar ist
- Keine falsch positiven Ergebnisse
- Für die Erkennung von Heap-Fehlern ist kein erneutes Erstellen von Code erforderlich (für die Erkennung von Stack-Fehlern jedoch schon).
Nachteile:
- Im Jahr 2024 sind keine kommerziell erhältlichen Geräte mit standardmäßig aktivierter MTE verfügbar. In der Dokumentation von Arm wird jedoch beschrieben, wie MTE für Tests auf dem Pixel 8/Pixel 8 Pro aktiviert wird.
- Falsch-Negativ-Rate von 1 zu 16 im Vergleich zu 1 zu 256 bei HWASan
- Nur für 64‑Bit-Apps verfügbar
- Erfordert die Entwicklung separater Bibliotheken für das Targeting von Geräten mit und ohne MTE
ASan
Address Sanitizer (ASan) ist das älteste und am weitesten verbreitete der verfügbaren Tools. Es ist nützlich, um Speicherfehler während des Testens zu erkennen und Probleme zu beheben, die nur alte Geräte betreffen, auf denen keines der anderen Tools verfügbar ist. Verwenden Sie nach Möglichkeit HWASan.
Vorteile:
- Weit verbreitet. Funktioniert möglicherweise auf Geräten mit KitKat
- Bei korrekter Verwendung keine falsch positiven oder negativen Ergebnisse
Nachteile:
- Schwierig zu erstellen und richtig zu verpacken
- Höchster Overhead aller Optionen: ~100% CPU, ~50% Codegröße, ~100% Arbeitsspeicher
- Nicht mehr unterstützt
- Bekannte Fehler, die nicht behoben werden