Informationen zum Lesen von HWASan-Abstürzen finden Sie unter HWASan-Berichte.
Hardware-assisted AddressSanitizer (HWASan) ist ein Tool zur Erkennung von Arbeitsspeicherfehlern, das dem AddressSanitizer ähnelt. HWASan benötigt im Vergleich zu ASan viel weniger RAM, was es für die Bereinigung des gesamten Systems geeignet macht. HWASan ist nur unter Android 10 und höher sowie nur auf AArch64-Hardware verfügbar.
HWASan ist zwar in erster Linie für C/C++-Code nützlich, kann aber auch beim Debuggen von Java-Code helfen, der Abstürze in C/C++ verursacht, die zur Implementierung von Java-Schnittstellen verwendet werden. Es ist hilfreich, weil es Speicherfehler erkennt, sobald sie auftreten, und Sie direkt auf den Code verweist, der dafür verantwortlich ist.
Sie können vorkonfigurierte HWASan-Images von ci.android.com auf unterstützte Pixel-Geräte flashen (detaillierte Einrichtungsanleitung).
Im Vergleich zur klassischen ASan bietet HWASan:
- Ähnlicher CPU-Overhead (~2x)
- Ähnlicher Overhead bei der Codegröße (40–50%)
- Viel geringerer RAM-Overhead (10 % bis 35%)
HWASan erkennt dieselben Fehler wie ASan:
- Stack- und Heap-Pufferüberlauf/-unterlauf
- Heap-Nutzung nach dem Freigeben
- Stack außerhalb des Gültigkeitsbereichs verwendet
- Double Free/Wild Free
Außerdem erkennt HWASan die Stacknutzung nach der Rückkehr.
HWASan (wie ASan) ist mit UBSan kompatibel und beide können gleichzeitig auf einem Ziel aktiviert werden.
Implementierungsdetails und Einschränkungen
HWASan basiert auf dem Ansatz des Speichersperrages, bei dem ein kleiner zufälliger Tagwert sowohl mit Pointern als auch mit Bereichen von Speicheradressen verknüpft wird. Damit ein Speicherzugriff gültig ist, müssen die Zeiger- und Speicher-Tags übereinstimmen. HWASan nutzt die ARMv8-Funktion „Top Byte Ignore“ (TBI), auch virtuelles Adress-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-Dokumentationswebsite.
HWASan hat keine Redzones mit begrenzter Größe wie ASan zum Erkennen von Überläufen und keine Quarantäne mit begrenzter Kapazität wie ASan zum Erkennen von „Use after free“-Fehlern. Aus diesem Grund kann HWASan einen Fehler erkennen, unabhängig davon, wie groß der Überlauf ist oder wie lange der Speicher zurückgegeben wurde. Das bietet HWASan einen großen Vorteil gegenüber ASan.
HWASan hat jedoch eine begrenzte Anzahl möglicher Tag-Werte (256), was bedeutet, dass bei einer Ausführung des Programms mit einer Wahrscheinlichkeit von 0,4% ein Fehler übersehen wird.
Voraussetzungen
Neuere Versionen (4.14 und höher) des gemeinsamen Android-Kernels unterstützen HWASan ohne weitere Maßnahmen. Die Android 10-spezifischen Branches unterstützen HWASan nicht.
Der Userspace-Support für HWASan ist ab Android 11 verfügbar.
Wenn Sie mit einem anderen Kernel arbeiten, muss der Linux-Kernel für HWASan getaggte Zeiger in Systemaufrufargumenten akzeptieren. Die Unterstützung dafür wurde in den folgenden Upstream-Patch-Sets implementiert:
- arm64-getaggte Adress-ABI
- arm64: Entfernen des Tags von Nutzerzeigern, die an den Kernel übergeben werden
- mm: Avoid creating virtual address aliases in brk()/mmap()/mremap()
- arm64: Getaggte Adressen in access_ok() prüfen, die von Kernel-Threads aufgerufen wird
Wenn Sie mit einer benutzerdefinierten Toolchain erstellen, muss diese alles bis zum LLVM-Commit c336557f enthalten.
HWASan verwenden
Mit den folgenden Befehlen können Sie die gesamte Plattform mit HWASan erstellen:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
Sie können die Einstellung „SANITIZE_TARGET“ einer Produktdefinition hinzufügen, ähnlich wie bei aosp_coral_hwasan.
Für Nutzer, die mit AddressSanitizer vertraut sind, ist die Build-Komplexität deutlich geringer:
- Sie müssen „make“ nicht zweimal ausführen.
- Inkrementelle Builds sind sofort einsatzbereit.
- Es ist nicht erforderlich, Nutzerdaten zu flashen.
Auch einige Einschränkungen von AddressSanitizer wurden aufgehoben:
- Statische ausführbare Dateien werden unterstützt.
- Sie können die Bereinigung aller Ziele außer libc überspringen. Im Gegensatz zu ASan ist es nicht erforderlich, dass eine ausführbare Datei, die mit einer Bibliothek verknüpft ist, ebenfalls bereinigt wird, wenn die Bibliothek bereinigt wird.
Der Wechsel zwischen HWASan- und regulären Images mit derselben (oder höheren) Build-Nummer ist jederzeit möglich. Das Gerät muss nicht gelöscht werden.
Wenn Sie die Bereinigung eines Moduls überspringen möchten, verwenden Sie LOCAL_NOSANITIZE := hwaddress
(Android.mk) oder sanitize: { hwaddress: false }
(Android.bp).
Einzelne Ziele bereinigen
HWASan kann in einem regulären (nicht bereinigten) Build pro Ziel aktiviert werden, solange auch libc.so
bereinigt wird. Fügen Sie hwaddress: true
dem Sanitizer-Block in "libc_defaults"
in bionic/libc/Android.bp hinzu. Wiederholen Sie dann den Vorgang im Ziel, an dem Sie gerade arbeiten.
Durch die Sanitierung von libc können Heap-Speicherzuordnungen systemweit getaggt und die Tags für Speichervorgänge in libc.so
geprüft werden. So lassen sich auch Fehler in Binärdateien finden, für die HWASan nicht aktiviert wurde, wenn der fehlerhafte Speicherzugriff in libc.so
liegt (z. B. pthread_mutex_unlock()
auf einem delete()
ed Mutex).
Es ist nicht erforderlich, Builddateien zu ändern, wenn die gesamte Plattform mit HWASan erstellt wird.
Flashstation
Für Entwicklungszwecke können Sie mit Flashstation ein HWASan-kompatibles AOSP-Build auf ein Pixel mit entsperrtem Bootloader flashen. Wählen Sie das _hwasan-Ziel aus, z.B. aosp_flame_hwasan-userdebug. Weitere Informationen finden Sie in der NDK-Dokumentation für HWASan für App-Entwickler.
Bessere Stacktraces
HWASan verwendet einen schnellen, frame-pointerbasierten Unwinder, um für jedes Ereignis der Speicherzuweisung und ‑entnahme im Programm einen Stack-Trace aufzuzeichnen. Android aktiviert Frame Pointer im AArch64-Code standardmäßig, sodass dies in der Praxis gut funktioniert. Wenn Sie verwalteten Code zurücknehmen müssen, legen Sie HWASAN_OPTIONS=fast_unwind_on_malloc=0
in der Prozessumgebung fest. Hinweis: Für Stack-Traces mit fehlerhaftem Speicherzugriff wird standardmäßig der „langsame“ Unwinder verwendet. Diese Einstellung wirkt sich nur auf die Traces für die Speicherzuweisung und -entnahme aus. Diese Option kann je nach Auslastung sehr CPU-intensiv sein.
Symbolisierung
Weitere Informationen finden Sie unter Symbolisierung im Hilfeartikel „HWASan-Berichte verstehen“.
HWASan in Apps
Ähnlich wie AddressSanitizer kann HWASan nicht in Java-Code eindringen, aber Fehler in den JNI-Bibliotheken erkennen. Bis Android 14 wurde das Ausführen von HWASan-Apps auf einem Gerät ohne HWASan nicht unterstützt.
Auf einem HWASan-Gerät können Apps mit HWASan geprüft werden, indem der Code mit SANITIZE_TARGET:=hwaddress
in Make oder -fsanitize=hwaddress
in Compiler-Flags erstellt wird.
Auf einem Gerät ohne HWASan (mit Android 14 oder höher) muss die Dateieinstellung „wrap.sh“ hinzugefügt werden.LD_HWASAN=1
Weitere Informationen finden Sie in der Entwicklerdokumentation für Apps.