HWAddressSanitizer

Informationen zum Lesen von HWASan-Abstürzen finden Sie unter „HWASan-Berichte verstehen“ !

Der hardwareunterstützte AddressSanitizer (HWASan) ist ein Tool zur Speicherfehlererkennung, das dem AddressSanitizer ähnelt. HWASan benötigt im Vergleich zu ASan viel weniger RAM, wodurch es sich für die Sanierung des gesamten Systems eignet. HWASan ist nur auf Android 10 und höher und nur auf AArch64-Hardware verfügbar.

Obwohl HWASan hauptsächlich für C/C++-Code nützlich ist, kann es auch beim Debuggen von Java-Code helfen, der Abstürze in C/C++ verursacht, das zur Implementierung von Java-Schnittstellen verwendet wird. Dies ist hilfreich, da es Speicherfehler erkennt, wenn sie auftreten, und Sie direkt auf den verantwortlichen Code verweist.

Sie können vorgefertigte HWASan-Bilder von ci.android.com auf unterstützte Pixel-Geräte flashen ( ausführliche Einrichtungsanweisungen ).

Im Vergleich zum klassischen ASan bietet HWASan:

  • Ähnlicher CPU-Overhead (~2x)
  • Ähnlicher Codegrößen-Overhead (40 – 50 %)
  • Viel geringerer RAM-Overhead (10 % – 35 %)

HWASan erkennt die gleichen Fehler wie ASan:

  • Stapel- und Heap-Pufferüberlauf/-unterlauf
  • Heap-Nutzung nach dem kostenlosen
  • Stack-Nutzung außerhalb des Geltungsbereichs
  • Doppelt frei/wild frei

Darüber hinaus erkennt HWASan die Stack-Nutzung nach der Rückgabe.

HWASan (wie ASan) ist mit UBSan kompatibel, beide können gleichzeitig auf einem Ziel aktiviert werden.

Implementierungsdetails und Einschränkungen

HWASan basiert auf dem Speicher-Tagging- Ansatz, bei dem ein kleiner zufälliger Tag-Wert sowohl mit Zeigern als auch mit Bereichen von Speicheradressen verknüpft wird. Damit ein Speicherzugriff gültig ist, müssen Zeiger und Speicher-Tags übereinstimmen. HWASan nutzt die ARMv8-Funktion Top Byte Ignore (TBI), auch Virtual Address Tagging genannt, um das Zeiger-Tag in den höchsten Bits der Adresse zu speichern.

Weitere Informationen zum Design von HWASan finden Sie auf der Clang-Dokumentationsseite.

HWASan verfügt konstruktionsbedingt nicht über die Redzones mit begrenzter Größe von ASan zum Erkennen von Überläufen oder über die Quarantäne mit begrenzter Kapazität von ASan zum Erkennen einer Nutzung nach dem Freiwerden. Aus diesem Grund kann HWASan einen Fehler erkennen, unabhängig davon, wie groß der Überlauf ist oder wie lange die Freigabe des Speichers zurückliegt. Dies verschafft HWASan einen großen Vorteil gegenüber ASan.

HWASan verfügt jedoch über eine begrenzte Anzahl möglicher Tag-Werte (256), was bedeutet, dass die Wahrscheinlichkeit, dass bei einer Ausführung des Programms ein Fehler übersehen wird, bei 0,4 % liegt.

Anforderungen

Aktuelle Versionen (4.14+) des gängigen Android-Kernels unterstützen HWASan sofort. Die Android 10-spezifischen Zweige unterstützen HWASan nicht.

Userspace-Unterstützung für HWASan ist ab Android 11 verfügbar.

Wenn Sie mit einem anderen Kernel arbeiten, erfordert HWASan, dass der Linux-Kernel markierte Zeiger in Systemaufrufargumenten akzeptiert. Die Unterstützung hierfür wurde in den folgenden Upstream-Patchsets implementiert:

Wenn Sie mit einer benutzerdefinierten Toolchain erstellen, stellen Sie sicher, dass diese alles bis zum LLVM-Commit c336557f enthält.

Verwendung von HWASan

Verwenden Sie die folgenden Befehle, um die gesamte Plattform mit HWASan zu erstellen:

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

Der Einfachheit halber können Sie die Einstellung SANITIZE_TARGET zu einer Produktdefinition hinzufügen, ähnlich wie bei aosp_coral_hwasan .

Für Benutzer, die mit AddressSanitizer vertraut sind, entfällt ein Großteil der Build-Komplexität:

  • Sie müssen make nicht zweimal ausführen.
  • Inkrementelle Builds funktionieren sofort.
  • Es ist nicht erforderlich, Benutzerdaten zu flashen.

Einige AddressSanitizer-Einschränkungen sind ebenfalls weggefallen:

  • Statische ausführbare Dateien werden unterstützt.
  • Es ist in Ordnung, die Bereinigung eines anderen Ziels als libc zu überspringen. Anders als bei ASan gibt es keine Anforderung, dass, wenn eine Bibliothek bereinigt wird, auch alle ausführbaren Dateien, die sie verknüpfen, bereinigt werden müssen.

Der Wechsel zwischen HWASan und regulären Images mit derselben (oder höheren) Build-Nummer ist frei möglich. Ein Abwischen des Geräts ist nicht erforderlich.

Um die Bereinigung eines Moduls zu überspringen, verwenden Sie LOCAL_NOSANITIZE := hwaddress (Android.mk) oder sanitize: { hwaddress: false } (Android.bp).

Desinfizieren einzelner Ziele

HWASan kann pro Ziel in einem regulären (nicht bereinigten) Build aktiviert werden, solange libc.so ebenfalls bereinigt wird. Fügen Sie hwaddress: true zum Sanitize-Block in "libc_defaults" in bionic/libc/Android.bp hinzu. Machen Sie dann dasselbe in dem Ziel, an dem Sie arbeiten.

Beachten Sie, dass die Bereinigung von libc das systemweite Markieren von Heap-Speicherzuweisungen sowie die Überprüfung der Tags auf Speicheroperationen in libc.so ermöglicht. Dadurch können Fehler auch in Binärdateien auftreten, für die HWASan nicht aktiviert wurde, wenn der fehlerhafte Speicherzugriff in libc.so erfolgt (z. B. pthread_mutex_unlock() bei einem delete() ed-Mutex).

Wenn die gesamte Plattform mit HWASan erstellt wird, müssen keine Build-Dateien geändert werden.

Flashstation

Zu Entwicklungszwecken können Sie mit Flashstation einen HWASan-fähigen Build von AOSP auf ein Pixel-Gerät mit entsperrtem Bootloader flashen. Wählen Sie das _hwasan-Ziel aus, z. B. aosp_flame_hwasan-userdebug. Weitere Einzelheiten finden Sie in der NDK-Dokumentation für HWASan für App-Entwickler.

Bessere Stapelspuren

HWASan verwendet einen schnellen, Frame-Pointer-basierten Unwinder, um einen Stack-Trace für jedes Speicherzuweisungs- und -freigabeereignis im Programm aufzuzeichnen. Android aktiviert standardmäßig Framezeiger im AArch64-Code, sodass dies in der Praxis hervorragend funktioniert. Wenn Sie die Abwicklung über verwalteten Code durchführen müssen, legen Sie in der Prozessumgebung HWASAN_OPTIONS=fast_unwind_on_malloc=0 fest. Beachten Sie, dass Stack-Traces bei fehlerhaftem Speicherzugriff standardmäßig den „langsamen“ Unwinder verwenden. Diese Einstellung wirkt sich nur auf Zuweisungs- und Freigabe-Traces aus. Diese Option kann je nach Auslastung sehr CPU-intensiv sein.

Symbolisierung

Siehe Symbolisierung im Abschnitt „HWASan-Berichte verstehen“.

HWASan in Apps

Ähnlich wie AddressSanitizer kann HWASan keinen Einblick in Java-Code haben, aber es kann Fehler in den JNI-Bibliotheken erkennen. Bis Android 14 wurde die Ausführung von HWASan-Apps auf einem Nicht-HWASan-Gerät nicht unterstützt.

Auf einem HWASan-Gerät können Apps mit HWASan überprüft werden, indem ihr Code mit SANITIZE_TARGET:=hwaddress in Make oder -fsanitize=hwaddress in Compiler-Flags erstellt wird. Auf einem Nicht-HWASan-Gerät (mit Android 14 oder neuer) muss eine wrap.sh-Dateieinstellung LD_HWASAN=1 hinzugefügt werden. Weitere Informationen finden Sie in der Dokumentation für App-Entwickler .