AddressSanitizer (ASan) ist ein schnelles Compiler-basiertes Tool zur Erkennung in nativem Code nicht so schnell wie möglich.
ASan erkennt:
- Überlauf/Unterlauf für Stack- und Heap-Zwischenspeicher
- Heap-Nutzung nach kostenloser Nutzung
- Stack-Verwendung außerhalb des Zuständigkeitsbereichs
- Doppeltes Freibad/Wildtreffer
ASan wird sowohl auf 32-Bit- als auch auf 64-Bit-ARM sowie x86 und x86-64 ausgeführt. CPU-Overhead von ASan ungefähr doppelt so hoch, der Codegrößen-Overhead liegt zwischen 50 und 2-mal (abhängig von Ihren Zuweisungsmustern, aber in einer Größenordnung von 2x).
Android 10 und der AOSP-Hauptzweig auf AArch64 Hardware-Assisted AddressSanitizer (HWASan) unterstützt ein ähnliches Tool mit geringerem RAM-Overhead und der gefundenen Fehler. HWASan erkennt die Stack-Nutzung nach der Rückgabe sowie die Fehler die von ASan erkannt wurden.
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. Dies macht HWASan besser als ASan. Weitere Informationen zu den Design von HWASan oder zur Verwendung von HWASan unter Android
ASan erkennt Stack-/globale Überläufe und Heap-Overflows und ist bei minimalem Arbeitsspeicher-Overhead schnell.
In diesem Dokument wird beschrieben, wie Sie Android mit San Francisco. Wenn Sie eine SDK/NDK-App mit ASan erstellen, lesen Sie Adressbereinigung .
Einzelne ausführbare Dateien mit ASan bereinigen
LOCAL_SANITIZE:=address
oder sanitize: { address: true }
hinzufügen zu
die Build-Regel für die ausführbare Datei. Sie können im Code nach vorhandenen Beispielen suchen
den anderen verfügbaren Desinfektionsmitteln.
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 Bibliothek, die mit ASan gebaut wurde, nur von einem ausführbare Datei, die mit ASan erstellt wurde.
Um eine gemeinsam genutzte Bibliothek zu bereinigen, die in mehreren ausführbaren Dateien verwendet wird, nicht alle
die mit ASan erstellt wurden, benötigen Sie zwei Kopien der Bibliothek. Die
Wir empfehlen, dazu Folgendes zu Android.mk
hinzuzufügen:
für das betreffende Modul:
LOCAL_SANITIZE:=address LOCAL_MODULE_RELATIVE_PATH := asan
Dadurch wird die Bibliothek in /system/lib/asan
statt
/system/lib
. Führen Sie dann die ausführbare Datei mit folgendem Befehl aus:
LD_LIBRARY_PATH=/system/lib/asan
Für System-Daemons fügen Sie im entsprechenden Abschnitt
/init.rc
oder /init.$device$.rc
.
setenv LD_LIBRARY_PATH /system/lib/asan
Prüfen Sie, ob der Prozess Bibliotheken von /system/lib/asan
verwendet
wenn vorhanden, indem /proc/$PID/maps
gelesen wird. 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. Das führt dazu, dass nur ein oder zwei sinnvolle 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
Oder ASAN_OPTIONS=fast_unwind_on_malloc=0
während des Vorgangs festlegen
zu verbessern. Letztere kann sehr CPU-intensiv sein, je nachdem,
die Last.
Symbolisierung
Anfangs enthalten ASan-Berichte Verweise auf Offsets in Binärdateien und freigegebene Bibliotheken. Es gibt zwei Möglichkeiten, Informationen zu Quelldatei und -zeile abzurufen:
- Die Binärdatei
llvm-symbolizer
muss in/system/bin
vorhanden sein.llvm-symbolizer
basiert auf Quellen inthird_party/llvm/tools/llvm-symbolizer
. - Bericht nach
external/compiler-rt/lib/asan/scripts/symbolize.py
filtern .
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, die in
dieser Fall ist /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.
LOCAL_SANITIZE:=address
hinzufügen zu
die Build-Regel app_process
in frameworks/base/cmds/app_process
. Ignorieren
das app_process__asan
-Ziel vorerst in derselben Datei (falls es
als Sie dies gelesen haben).
Bearbeiten Sie den Abschnitt service zygote
des
entsprechende system/core/rootdir/init.zygote(32|64).rc
-Datei zum
bis zum Block eingerückter Zeilen mit class main
folgen, sowie
um den gleichen Betrag eingerückt:
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 den Arbeitsspeicher-Aufwand gegen einen langsameren Start der App.
Starte dazu deine App mit der Property wrap.
.
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 Kontext schreibt asanwrapper
/system/bin/app_process
um
an /system/bin/asan/app_process
, das mit
San Francisco. Außerdem wird /system/lib/asan
am Anfang von
dynamischen Bibliothekssuchpfad hinzu. Auf diese Weise instrumentierte ASan
Bibliotheken aus /system/lib/asan
werden normalen Bibliotheken vorgezogen
in /system/lib
bei Ausführung mit asanwrapper
.
Wird ein Fehler gefunden, stürzt die App ab und der Bericht wird des Protokolls.
SANITIZE_TARGET
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
auf das Gerät geflasht haben. Verwenden Sie die folgende Befehlszeile:
fastboot flash userdata && fastboot flashall
Dadurch werden zwei Sätze gemeinsam genutzter Bibliotheken erstellt: normal in
/system/lib
(der erste Aufruf) und ASan-instrumentiert in
/data/asan/lib
(der zweite Make-Aufruf). Ausführbare Dateien aus dem
des ersten Builds überschreiben. ASan-instrumentiert
ausführbaren Dateien erhalten einen anderen Bibliothekssuchpfad, der Folgendes enthält:
/data/asan/lib
vor dem /system/lib
durch die Verwendung von
„/system/bin/linker_asan
“ in „PT_INTERP
“.
Das Build-System clobbers sperrt Zwischenobjektverzeichnisse, wenn der
Der Wert von „$SANITIZE_TARGET
“ hat sich geändert. Dadurch wird eine Neuerstellung aller
Ziele unter Beibehaltung installierter Binärdateien unter /system/lib
beibehalten.
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 wie diese werden im Build SANITIZE_TARGET
übersprungen und der
Die Version vom ersten Aufruf wird in /system/bin
beibehalten.
Bibliotheken wie diese werden ohne ASan erstellt. Sie können einige ASan enthalten. Code aus den statischen Bibliotheken, von denen sie abhängig sind.
Zusätzliche Dokumentation
- Adressbereinigung
- AddressSanitizer (in englischer Sprache) und Chromium
- Andere Google-Desinfektionsmittel