Fehlerbehebung und Minderung von Arbeitsspeicherfehlern

Android unterstützt mehrere Tools zur Behebung von Speicherfehlern. Jede Option hat Vor- und Nachteile. Lesen Sie weiter, um zu entscheiden, 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 ist jedoch prägnant gehalten. Weitere Informationen finden Sie in den toolspezifischen Dokumenten.

Kurzfassung

  • Verwenden Sie nach Möglichkeit eine speichersichere Sprache, um Speicherfehler zu vermeiden.
  • Verwenden Sie immer PAC/BTI, um ROP-/JOP-Angriffe abzumildern
  • Verwenden Sie immer GWP-ASan, um seltene Arbeitsspeicherfehler in der Produktion zu erkennen.
  • HWASan zum Erkennen von Speicherfehlern während des Tests verwenden
  • Geräte mit MTE sind nicht allgemein verfügbar. Das ist erst dann hilfreich, wenn sich das ändert.
  • Verwenden Sie ASan während der Tests nur als letztes Mittel.

Speichersichere Sprachen

Eine speichersichere Sprache ist die einzige Möglichkeit, Speicherfehler vollständig zu vermeiden und zu minimieren. Die anderen Tools auf dieser Seite können Ihnen helfen, Ihren speicherunsicheren Code sicherer und zuverlässiger zu machen. Mit einer speichersicheren Sprache können Sie jedoch eine ganze Reihe von Problemen vermeiden.

Die offiziell unterstützten speichersicheren Sprachen für Android sind Java und Kotlin. Die meisten Android-Anwendungen lassen sich in einer dieser Sprachen einfacher entwickeln.

Es gibt jedoch App-Entwickler, die Code in Rust 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 bei dieser Vorgehensweise auftreten, nicht unbedingt helfen. Wir sind aber interessiert an Ihren Erfahrungen.

PAC/BTI

Pointer Authentication and Branch Target Identification, auch als PAC/BTI bezeichnet, sind Minderungstools, die sich für die Produktion eignen. Obwohl es sich um separate Technologien handelt, werden sie durch dasselbe Compiler-Flag gesteuert und werden 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 nicht ausgeführt werden. Außerdem ist ein neuerer Kernel und eine neuere Version des Betriebssystems erforderlich. Wenn du in /proc/cpuinfo nach paca und bti suchst, siehst du, ob deine Hardware und dein Kernel neu genug sind. Android 12 (API 31) bietet die erforderliche Unterstützung für den Userspace.

Vorteile:

  • Kann in allen Builds aktiviert werden, ohne Probleme auf älteren Geräten oder Kerneln zu verursachen. Sie sollten die Funktion jedoch auf einer Geräte-/Kernel-/Betriebssystemkombination testen, die sie unterstützt.

Nachteile:

  • Nur für 64-Bit-Apps verfügbar
  • Fehler auf Geräten, die die Funktion nicht unterstützen, werden nicht vermieden.
  • 1% Overhead bei der Codegröße

GWP-Asan

GWP-ASan kann verwendet werden, um Arbeitsspeicherfehler im Feld zu erkennen, die Stichprobenrate ist jedoch zu niedrig, um eine effektive Risikominderung zu ermöglichen.

Vorteile:

  • Kein erheblicher CPU- oder Arbeitsspeicheraufwand
  • Einfache Bereitstellung: Es ist kein Neuaufbau des nativen Codes erforderlich.
  • Funktioniert für 32-Bit-Apps

Nachteile:

  • Bei einer niedrigen Stichprobenrate ist eine große Anzahl von Nutzern erforderlich, um Fehler effektiv zu finden.
  • Erkennt nur Heap-Fehler, keine Stack-Fehler

HWASan

Hardware Address Sanitizer, auch HWASan genannt, eignet sich am besten, um Arbeitsspeicherfehler während des Tests zu erkennen. Sie eignet sich am besten für automatisierte Tests, insbesondere für Fuzz-Tests. Je nach 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 (Stacknutzung nach Rückgabe)
  • Niedrigere Rate an falsch negativen Ergebnissen als MTE (1 zu 256 im Vergleich zu 1 zu 16)
  • Geringerer Arbeitsspeicheraufwand als ASan, die nächstgelegene 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

Memory Tagging Extension, auch MTE genannt, ist eine kostengünstigere Alternative zu HWASan. Neben den Funktionen zum Debuggen und Testen 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 diese Funktion aktivieren.

Vorteile:

  • Der Overhead ist niedrig genug, um für viele Apps in der Produktion tolerabel zu sein.
  • Keine falsch positiven Ergebnisse
  • Es ist nicht erforderlich, Code neu zu erstellen, um Heap-Fehler zu erkennen (aber Stack-Fehler).

Nachteile:

  • 2024 sind keine kommerziell erhältlichen Geräte mit standardmäßig aktivierter MTE verfügbar. In der Arm-Dokumentation wird jedoch erläutert, wie MTE für Tests auf Google Pixel 8/Google Pixel 8 Pro aktiviert wird.
  • Falsch-Negativ-Rate von 1:16 im Vergleich zu 1:256 bei HWASan
  • Nur für 64-Bit-Apps verfügbar
  • Erforderlich ist die Erstellung separater Bibliotheken für das Targeting auf Geräte mit und ohne MTE.

ASan

Address Sanitizer, auch ASan genannt, ist das älteste und am weitesten verfügbare Tool. Es ist nützlich, um Speicherfehler während des Tests zu erkennen und Probleme zu beheben, die nur auf alte Geräte zutreffen, 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 zu verpacken
  • Der höchste Overhead aller Optionen: ~100% CPU, ~50% Codegröße, ~100% Arbeitsspeichernutzung
  • Nicht mehr unterstützt
  • Es gibt bekannte Fehler, die nicht behoben werden