AddressSanitizer (ASan) ist ein schnelles compilerbasiertes Tool zum Erkennen von Speicherfehlern in nativem Code.
ASan erkennt:
- Stack- und Heap-Pufferüberlauf/-unterlauf
- Heap-Nutzung nach dem Freigeben
- Stack außerhalb des Gültigkeitsbereichs verwendet
- Double Free/Wild Free
ASan wird sowohl auf 32-Bit- als auch auf 64-Bit-ARM sowie x86 und x86-64 ausgeführt. Der CPU-Overhead von ASan ist etwa doppelt so hoch, der Codegrößen-Overhead liegt zwischen 50 % und dem Doppelten und es gibt einen großen Arbeitsspeicher-Overhead (je nach Allokationsmuster, aber in der Größenordnung von 2 x).
Android 10 und der AOSP-Hauptzweig auf AArch64 unterstützen Hardware-assisted AddressSanitizer (HWASan), ein ähnliches Tool mit geringerem RAM-Overhead und einer größeren Bandbreite an erkannten Fehlern. HWASan erkennt zusätzlich zu den von ASan erkannten Fehlern die Verwendung des Stacks nach der Rückkehr.
HWASan hat einen ähnlichen CPU- und Codegröße-Overhead, aber einen viel geringeren RAM-Overhead (15%). HWASan ist nicht deterministisch. Es gibt nur 256 mögliche Tag-Werte, sodass es einen festen Wert von 0,4 % gibt, Wahrscheinlichkeit, dass Sie einen Fehler übersehen. HWASan hat nicht die begrenzten roten Zonen von ASan zur Erkennung von Überläufen und begrenzter Kapazität zur Erkennung von Use-After-Free-Angriffen, HWASan spielt also keine Rolle, wie groß der Überlauf ist oder wie lange wurde freigegeben. Dadurch ist HWASan besser als ASan. Weitere Informationen zum Design von HWASan oder zur Verwendung von HWASan auf Android-Geräten
ASan erkennt neben Heap-Overflows auch Stack-/globale Overflows und ist schnell mit minimalem Arbeitsspeicheraufwand.
In diesem Dokument wird beschrieben, wie Sie Teile oder das gesamte Android-System mit ASan erstellen und ausführen. Wenn Sie eine SDK/NDK-App mit ASan erstellen, lesen Sie Adressbereinigung .
Einzelne ausführbare Dateien mit ASan bereinigen
Fügen Sie der Build-Regel für die ausführbare Datei LOCAL_SANITIZE:=address
oder sanitize: { address: true }
hinzu. Sie können im Code nach vorhandenen Beispielen oder nach den anderen verfügbaren Sanitizern suchen.
Wenn ein Fehler erkannt wird, druckt ASan einen ausführlichen Bericht sowohl an die Standard-
in logcat
und stürzt dann den Prozess ab.
Gemeinsam genutzte Bibliotheken mit ASan bereinigen
Aufgrund der Funktionsweise von ASan kann eine mit ASan erstellte Bibliothek nur von einer mit ASan erstellten ausführbaren Datei verwendet werden.
Wenn Sie eine freigegebene Bibliothek, die in mehreren ausführbaren Dateien verwendet wird, die nicht alle mit ASan erstellt wurden, bereinigen möchten, benötigen Sie zwei Kopien der Bibliothek. Wir empfehlen, Folgendes zu Android.mk
für das betreffende Modul hinzuzufügen:
LOCAL_SANITIZE:=address LOCAL_MODULE_RELATIVE_PATH := asan
Dadurch wird die Bibliothek in /system/lib/asan
statt in /system/lib
platziert. Führen Sie dann die ausführbare Datei mit folgendem Befehl aus:
LD_LIBRARY_PATH=/system/lib/asan
Fügen Sie für Systemdaemons Folgendes in den entsprechenden Abschnitt von /init.rc
oder /init.$device$.rc
ein.
setenv LD_LIBRARY_PATH /system/lib/asan
Prüfen Sie, ob der Prozess Bibliotheken von /system/lib/asan
verwendet, falls vorhanden. Lesen Sie dazu /proc/$PID/maps
. Ist dies nicht der Fall, müssen Sie
, um SELinux zu deaktivieren:
adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID # if it is a system service, or may be adb shell stop; adb shell start.
Bessere Stacktraces
ASan verwendet eine schnelle, auf Framepointer basierende Abwicklung, um einen Stack aufzuzeichnen. für jedes Arbeitsspeicherzuweisungs- und Deallocation-Ereignis im Programm. Meiste von Android ohne Frame-Pointer. Daher erhalten Sie oft nur ein oder zwei aussagekräftige Frames. Um dieses Problem zu beheben, erstellen Sie die Bibliothek neu mit ASan (empfohlen!) oder mit:
LOCAL_CFLAGS:=-fno-omit-frame-pointer LOCAL_ARM_MODE:=arm
Sie können auch ASAN_OPTIONS=fast_unwind_on_malloc=0
in der Prozessumgebung festlegen. Letztere kann sehr CPU-intensiv sein, je nachdem,
die Last.
Symbolisierung
Ursprünglich enthalten ASan-Berichte Verweise auf Abweichungen in Binärdateien und freigegebenen Bibliotheken. Es gibt zwei Möglichkeiten, Informationen zu Quelldatei und -zeile abzurufen:
- Prüfen Sie, ob die
llvm-symbolizer
-Binärdatei in/system/bin
vorhanden ist.llvm-symbolizer
basiert auf Quellen inthird_party/llvm/tools/llvm-symbolizer
. - Filtern Sie den Bericht mit dem
external/compiler-rt/lib/asan/scripts/symbolize.py
-Script.
Bei der zweiten Methode können mehr Daten bereitgestellt werden (d. h. file:line
Standorte), weil
Verfügbarkeit von symbolisierten Bibliotheken auf dem Host
ASan in Apps
ASan kann keinen Java-Code sehen, aber Fehler in der JNI erkennen.
Bibliotheken. Dazu müssen Sie die ausführbare Datei mit ASan erstellen, in diesem Fall /system/bin/app_process(32|64)
. Dieses
aktiviert ASan in allen Apps auf dem Gerät gleichzeitig, was eine
aber ein Gerät mit 2 GB RAM sollte damit umgehen können.
Fügen Sie LOCAL_SANITIZE:=address
zur app_process
-Build-Regel in frameworks/base/cmds/app_process
hinzu. Ignorieren
das app_process__asan
-Ziel vorerst in derselben Datei (falls es
als Sie dies gelesen haben).
Bearbeiten Sie den Abschnitt service zygote
der entsprechenden system/core/rootdir/init.zygote(32|64).rc
-Datei, um dem Block mit den eingerückten Zeilen, die class main
enthalten, die folgenden Zeilen hinzuzufügen, die ebenfalls um denselben Betrag eingerückt sind:
setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib setenv ASAN_OPTIONS allow_user_segv_handler=true
Build, ADB-Synchronisierung, Fastboot Flash Boot und Neustart.
Attribut „wrap“ verwenden
Beim Ansatz im vorherigen Abschnitt wird ASan in jede in jeden Nachfolger der Zygote- Prozess). Es ist möglich, nur eine (oder mehrere) Apps mit ASan, und einen Teil des Arbeitsspeicher- aufwands gegen einen langsameren Start der App.
Sie können dazu die Property wrap.
verwenden.
Im folgenden Beispiel wird die Gmail App unter ASan ausgeführt:
adb root
adb shell setenforce 0 # disable SELinux
adb shell setprop wrap.com.google.android.gm "asanwrapper"
In diesem Zusammenhang schreibt asanwrapper
/system/bin/app_process
in /system/bin/asan/app_process
um, das mit ASan erstellt wurde. Außerdem wird /system/lib/asan
am Anfang von
dynamischen Bibliothekssuchpfad hinzu. So werden ASan-instrumentierte Bibliotheken aus /system/lib/asan
bei der Ausführung mit asanwrapper
normalen Bibliotheken in /system/lib
vorgezogen.
Wird ein Fehler gefunden, stürzt die App ab und der Bericht wird Protokoll.
SANITIZE_ZIEL
Android 7.0 und höher unterstützt die Entwicklung der gesamten Android-Plattform mit ASan auf einmal. (Wenn Sie eine höhere Version als Android 9 entwickeln, ist HWASan die bessere Wahl.)
Führen Sie die folgenden Befehle in derselben Build-Struktur aus.
make -j42
SANITIZE_TARGET=address make -j42
In diesem Modus enthält userdata.img
zusätzliche Bibliotheken und muss ebenfalls auf das Gerät geflasht werden. Verwenden Sie die folgende Befehlszeile:
fastboot flash userdata && fastboot flashall
Dadurch werden zwei gemeinsam genutzte Bibliotheken erstellt: eine normale in /system/lib
(die erste make-Aufruf) und eine mit ASan instrumentierte in /data/asan/lib
(die zweite make-Aufruf). Ausführbare Dateien aus dem zweiten Build überschreiben die aus dem ersten Build. ASan-instrumentierte ausführbare Dateien erhalten einen anderen Bibliothekssuchpfad, der /data/asan/lib
vor /system/lib
enthält, da /system/bin/linker_asan
in PT_INTERP
verwendet wird.
Das Build-System überschreibt Zwischenobjektverzeichnisse, wenn sich der Wert von $SANITIZE_TARGET
geändert hat. Dadurch wird ein Neuaufbau aller Ziele erzwungen, während die installierten Binärdateien unter /system/lib
erhalten bleiben.
Einige Ziele können nicht mit ASan erstellt werden:
- Statisch verknüpfte ausführbare Dateien
LOCAL_CLANG:=false
ZieleLOCAL_SANITIZE:=false
werden fürSANITIZE_TARGET=address
nicht genehmigt
Ausführbare Dateien dieser Art werden im SANITIZE_TARGET
-Build übersprungen und der
Die Version vom ersten Aufruf wird in /system/bin
beibehalten.
Solche Bibliotheken werden ohne ASan erstellt. Sie können ASan-Code aus den statischen Bibliotheken enthalten, von denen sie abhängen.