Was macht AddressSanitizer (ASan)?
AddressSanitizer (ASan) ist ein weit verbreitetes Tool zur Erkennung von Speicherfehlern, das intensiv beim Testen von Software, insbesondere beim Fuzzing, eingesetzt wird. Es hilft, Speicherkorruptionsfehler aufzuspüren, die sonst unbemerkt bleiben könnten, wie z. B. Pufferüberläufe, Use-After-Free-Fehler und andere Verstöße gegen die Speichersicherheit.
Überblick
ASan ist aufgrund seiner Effektivität bei der Identifizierung von Speicherschwachstellen eine Standardpraxis beim Fuzzing. Es instrumentiert Code zur Kompilierzeit, um Speicherzuweisungen und -zugriffe zu verfolgen und illegale Operationen zur Laufzeit zu erkennen.
Schlüsselkonzepte
| Konzept | Beschreibung |
|---|---|
| Instrumentierung | ASan fügt während der Kompilierung Laufzeitprüfungen für Speicheroperationen hinzu |
| Schattenspeicher | Bildet 20 TB virtuellen Speicher ab, um den Zuweisungsstatus zu verfolgen |
| Leistungskosten | Etwa 2- bis 4-fache Verlangsamung im Vergleich zu nicht instrumentiertem Code |
| Erkennungsumfang | Findet Pufferüberläufe, Use-After-Free, Double-Free und Speicherlecks |
Wann anwenden
Wenden Sie diese Technik an, wenn:
- Sie C/C++-Code auf Speichersicherheitslücken fuzzen
- Sie Rust-Code mit unsicheren Blöcken testen
- Sie Abstürze im Zusammenhang mit Speicherkorruption debuggen
- Sie Komponententests ausführen, bei denen Speicherfehler vermutet werden
Überspringen Sie diese Technik, wenn:
- Sie Produktionscode ausführen (ASan kann die Sicherheit verringern)
- Die Plattform Windows oder macOS ist (eingeschränkte ASan-Unterstützung)
- Der Leistungsaufwand für Ihren Anwendungsfall inakzeptabel ist
- Sie reine sichere Sprachen ohne FFI fuzzen (z. B. reines Go, reines Java)
Kurzreferenz
| Aufgabe | Befehl/Muster |
|---|---|
| ASan aktivieren (Clang/GCC) | -fsanitize=address |
| Ausführlichkeit aktivieren | ASAN_OPTIONS=verbosity=1 |
| Leckerkennung deaktivieren | ASAN_OPTIONS=detect_leaks=0 |
| Abbruch bei Fehler erzwingen | ASAN_OPTIONS=abort_on_error=1 |
| Mehrere Optionen | ASAN_OPTIONS=verbosity=1:abort_on_error=1 |
Schritt-für-Schritt-Anleitung
Schritt 1: Mit ASan kompilieren
Kompilieren und linken Sie Ihren Code mit dem Flag -fsanitize=address:
clang -fsanitize=address -g -o my_program my_program.c
Das Flag -g wird empfohlen, um bessere Stack-Traces zu erhalten, wenn ASan Fehler erkennt.
Schritt 2: ASan-Optionen konfigurieren
Setzen Sie die Umgebungsvariable ASAN_OPTIONS, um das Verhalten von ASan zu konfigurieren:
export ASAN_OPTIONS=verbosity=1:abort_on_error=1:detect_leaks=0
Schritt 3: Programm ausführen
Führen Sie das mit ASan instrumentierte Binary aus. Wenn Speicherfehler erkannt werden, gibt ASan detaillierte Berichte aus:
./my_program
Schritt 4: Speicherlimits des Fuzzers anpassen
ASan benötigt ca. 20 TB virtuellen Speicher. Deaktivieren Sie die Speicherbeschränkungen des Fuzzers:
- libFuzzer:
-rss_limit_mb=0 - AFL++:
-m none
Häufige Muster
Muster: Grundlegende ASan-Integration
Anwendungsfall: Standard-Fuzzing-Setup mit ASan
Vorher:
clang -o fuzz_target fuzz_target.c
./fuzz_target
Nachher:
clang -fsanitize=address -g -o fuzz_target fuzz_target.c
ASAN_OPTIONS=verbosity=1:abort_on_error=1 ./fuzz_target
Muster: ASan mit Komponententests
Anwendungsfall: Aktivieren von ASan für eine Testsuite
Vorher:
gcc -o test_suite test_suite.c -lcheck
./test_suite
Nachher:
gcc -fsanitize=address -g -o test_suite test_suite.c -lcheck
ASAN_OPTIONS=detect_leaks=1 ./test_suite
Erweiterte Nutzung
Tipps und Tricks
| Tipp | Warum es hilft |
|---|---|
-g-Flag verwenden | Bietet detaillierte Stack-Traces zum Debuggen |
verbosity=1 setzen | Bestätigt, dass ASan aktiviert ist, bevor das Programm startet |
| Lecks während des Fuzzings deaktivieren | Leckerkennung verursacht keine sofortigen Abstürze und überlädt die Ausgabe |
abort_on_error=1 aktivieren | Einige Fuzzer benötigen abort() anstelle von _exit() |
ASan-Berichte verstehen
Wenn ASan einen Speicherfehler erkennt, gibt es einen detaillierten Bericht aus, der Folgendes enthält:
- Fehlertyp: Pufferüberlauf, Use-After-Free usw.
- Stack-Trace: Wo der Fehler aufgetreten ist
- Allokations-/Freigabe-Traces: Wo Speicher zugewiesen/freigegeben wurde
- Speicherkarte: Schattenspeicherstatus um den Fehler herum
Beispiel für einen ASan-Bericht:
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000eff4 at pc 0x00000048e6a3
READ of size 4 at 0x60300000eff4 thread T0
#0 0x48e6a2 in main /path/to/file.c:42
Sanitizer kombinieren
ASan kann mit anderen Sanitizern kombiniert werden, um eine umfassende Erkennung zu erreichen:
clang -fsanitize=address,undefined -g -o fuzz_target fuzz_target.c
Plattformspezifische Überlegungen
Linux: Volle ASan-Unterstützung mit bester Leistung macOS: Eingeschränkte Unterstützung, einige Funktionen funktionieren möglicherweise nicht Windows: Experimentelle Unterstützung, nicht für das Produktions-Fuzzing empfohlen
Anti-Patterns
| Anti-Pattern | Problem | Korrekter Ansatz |
|---|---|---|
| ASan in der Produktion verwenden | Kann Anwendungen weniger sicher machen | ASac nur zum Testen verwenden |
| Speicherlimits nicht deaktivieren | Fuzzer kann Prozess aufgrund von 20 TB virtuellem Speicher beenden | -rss_limit_mb=0 oder -m none setzen |
| Leckberichte ignorieren | Speicherlecks weisen auf Probleme der Ressourcenverwaltung hin | Leckberichte am Ende der Fuzzing-Kampagne überprüfen |
Werkzeugspezifische Anleitungen
libFuzzer
Kompilieren Sie sowohl mit Fuzzer als auch mit Adress-Sanitizer:
clang++ -fsanitize=fuzzer,address -g harness.cc -o fuzz
Ausführen mit unbegrenztem RSS:
./fuzz -rss_limit_mb=0
Integrationstipps:
- Immer
-fsanitize=fuzzermit-fsanitize=addresskombinieren -gfür detaillierte Stack-Traces in Absturzberichten verwenden- Erwägen Sie
ASAN_OPTIONS=abort_on_error=1für eine bessere Absturzbehandlung
Siehe: libFuzzer: AddressSanitizer
AFL++
Verwenden Sie die Umgebungsvariable AFL_USE_ASAN:
AFL_USE_ASAN=1 afl-clang-fast++ -g harness.cc -o fuzz
Ausführen mit unbegrenztem Speicher:
afl-fuzz -m none -i input_dir -o output_dir ./fuzz
Integrationstipps:
AFL_USE_ASAN=1fügt automatisch die richtigen Kompilierungsflags hinzu-m noneverwenden, um die Speicherbegrenzung von AFL++ zu deaktivieren- Erwägen Sie
AFL_MAP_SIZEfür Programme mit großen Coverage Maps
Siehe: AFL++: AddressSanitizer
cargo-fuzz (Rust)
Verwenden Sie das Flag --sanitizer=address:
cargo fuzz run fuzz_target --sanitizer=address
Oder konfigurieren Sie es in fuzz/Cargo.toml:
[profile.release]
opt-level = 3
debug = true
Integrationstipps:
- ASan ist nützlich zum Fuzzen von unsicherem Rust-Code oder FFI-Grenzen
- Sicherer Rust-Code profitiert möglicherweise weniger (der Compiler verhindert bereits viele Fehler)
- Konzentrieren Sie sich auf unsichere Blöcke, rohe Zeiger und C-Bibliotheksbindungen
Siehe: cargo-fuzz: AddressSanitizer
honggfuzz
Kompilieren Sie mit ASan und linken Sie mit honggfuzz:
honggfuzz -i input_dir -o output_dir -- ./fuzz_target_asan
Kompilieren des Ziels:
hfuzz-clang -fsanitize=address -g target.c -o fuzz_target_asan
Integrationstipps:
- honggfuzz funktioniert standardmäßig gut mit ASan
- Verwenden Sie den feedbackgesteuerten Modus für eine bessere Abdeckung mit Sanitizern
- Überwachen Sie die Speichernutzung, da ASan den Speicherverbrauch erhöht
Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
| Fuzzer beendet Prozess sofort | Speicherlimit zu niedrig für ASans 20 TB virtuellen Speicher | -rss_limit_mb=0 (libFuzzer) oder -m none (AFL++) verwenden |
| "ASan runtime not initialized" | Falsche Link-Reihenfolge oder fehlende Laufzeit | Sicherstellen, dass -fsanitize=address sowohl beim Kompilieren als auch beim Linken verwendet wird |
| Leckberichte überladen Ausgabe | LeakSanitizer ist standardmäßig aktiviert | ASAN_OPTIONS=detect_leaks=0 setzen |
| Schlechte Leistung (>4x Verlangsamung) | Debug-Modus oder nicht optimierter Build | Mit -O2 oder -O3 zusammen mit -fsanitize=address kompilieren |
| ASan erkennt offensichtliche Fehler nicht | Binary nicht instrumentiert | Mit ASAN_OPTIONS=verbosity=1 überprüfen, ob ASan Startinformationen ausgibt |
| Falschpositive | Interceptor-Konflikte | Überprüfen Sie die ASan-FAQ auf bekannte Probleme mit bestimmten Bibliotheken |
Verwandte Fähigkeiten
Werkzeuge, die diese Technik verwenden
| Fähigkeit | Wie es angewendet wird |
|---|---|
| libfuzzer | Kompilieren mit -fsanitize=fuzzer,address für integriertes Fuzzing mit Speicherfehlererkennung |
| aflpp | Umgebungsvariable AFL_USE_ASAN=1 während der Kompilierung verwenden |
| cargo-fuzz | Flag --sanitizer=address verwenden, um ASan für Rust-Fuzz-Targets zu aktivieren |
| honggfuzz | Ziel mit -fsanitize=address für ASan-instrumentiertes Fuzzing kompilieren |
Verwandte Techniken
| Fähigkeit | Beziehung |
|---|---|
| undefined-behavior-sanitizer | Wird oft zusammen mit ASan verwendet, um eine umfassende Fehlererkennung zu erreichen (undefiniertes Verhalten + Speicherfehler) |
| fuzz-harness-writing | Harness muss so ausgelegt sein, dass es ASan-erkannte Abstürze behandelt und falschpositive vermeidet |
| coverage-analysis | Abdeckungsgesteuertes Fuzzing hilft, Codepfade auszulösen, in denen ASan Speicherfehler erkennen kann |
Ressourcen
Wichtige externe Ressourcen
AddressSanitizer auf Google Sanitizers Wiki
Die offizielle ASan-Dokumentation behandelt:
- Algorithmus und Implementierungsdetails
- Vollständige Liste der erkannten Fehlertypen
- Leistungsmerkmale und Overhead
- Plattformspezifisches Verhalten
- Bekannte Einschränkungen und Inkompatibilitäten
Allgemeine Konfigurationsflags, die von allen Sanitizern gemeinsam genutzt werden:
verbosity: Steuerung der Diagnoseausgabestufelog_path: Umleitung der Sanitizer-Ausgabe in Dateiensymbolize: Aktivieren/Deaktivieren der Symbolauflösung in Berichtenexternal_symbolizer_path: Benutzerdefinierten Symbolizer verwenden
ASan-spezifische Konfigurationsoptionen:
detect_leaks: Steuerung der Speicherleckerfassungabort_on_error:abort()vs._exit()bei Fehler aufrufendetect_stack_use_after_return: Erkennung von Use-After-Return-Fehlern auf dem Stackcheck_initialization_order: Fehler in der Initialisierungsreihenfolge finden
Häufige Fallstricke und Lösungen:
- Probleme mit der Link-Reihenfolge
- Konflikte mit anderen Tools
- Plattformspezifische Probleme
- Tipps zur Leistungsoptimierung
Clang AddressSanitizer Dokumentation
Clang-spezifische Anleitung:
- Kompilierungsflags und Optionen
- Interaktion mit anderen Clang-Funktionen
- Unterstützte Plattformen und Architekturen
GCC-spezifische ASan-Dokumentation:
- GCC-spezifische Flags und Verhalten
- Unterschiede zur Clang-Implementierung
- Plattformunterstützung in GCC
AddressSanitizer: A Fast Address Sanity Checker (USENIX Paper)
Original-Forschungspapier mit technischen Details:
- Algorithmus für Schattenspeicher
- Anforderungen an virtuellen Speicher (historisch 16 TB, heute ca. 20 TB)
- Leistungsbenchmarks
- Designentscheidungen und Abwägungen