AddressSanitizer-Runtime

Die AddressSanitizer-Laufzeitbibliothek fängt allgemeine Speicherbelegungsfunktionen und -vorgänge ab, um die Überprüfung von Arbeitsspeicherzugriffen zu ermöglichen. Es gibt mehrere verschiedene Laufzeitbibliotheken, die die verschiedenen Typen von ausführbaren Dateien unterstützen, die der Compiler generieren kann. Compiler und Linker verknüpfen automatisch die entsprechenden Laufzeitbibliotheken, solange Sie die /fsanitize=address Option zur Kompilierzeit übergeben. Sie können das Standardverhalten überschreiben, indem Sie die /NODEFAULTLIB Option zur Linkzeit verwenden. Weitere Informationen finden Sie im Abschnitt zum Verknüpfen in der AddressSanitizer-Sprach-, Build- und Debugreferenz.

Im Folgenden finden Sie eine Inventur der Laufzeitbibliotheken für die Verknüpfung mit der AddressSanitizer-Runtime, wobei {arch} entweder i386 oder x86_64 ist.

Hinweis

Diese Bibliotheken behalten die Clang-Konventionen für Architekturnamen bei. Die MSVC Konventionen sind normalerweise x86 und x64 anstelle von i386 und x86_64. Sie verweisen auf die gleichen Architekturen.

CRT-Option DLL oder EXE DEBUGGEN? Binärbibliotheken der AddressSanitizer-Runtime
MT EXE Nein clang_rt.asan-{arch}, clang_rt.asan_cxx-{arch}
MT DLL Nein clang_rt.asan_dll_thunk-{arch}
MD ENTWEDER Nein clang_rt.asan_dynamic-{arch}, clang_rt.asan_dynamic_runtime_thunk-{arch}
MT EXE YES clang_rt.asan_dbg-{arch}, clang_rt.asan_dbg_cxx-{arch}
MT DLL YES clang_rt.asan_dbg_dll_thunk-{arch}
MD ENTWEDER YES clang_rt.asan_dbg_dynamic-{arch}, clang_rt.asan_dbg_dynamic_runtime_thunk-{arch}

Beim Kompilieren mit cl /fsanitize=address generiert der Compiler Anweisungen zum Verwalten und Überprüfen der cl /fsanitize=address Ihr Programm verwendet diese Instrumentierung, um Speicherzugriffe auf dem Stapel, im Heap oder im globalen Bereich zu überprüfen. Der Compiler erzeugt auch Metadaten, die Stapel- und globale Variablen beschreiben. Mit diesen Metadaten kann die Laufzeit präzise Fehlerdiagnosen generieren: Funktionsnamen, Zeilen und Spalten im Quellcode. Zusammen können die Compilerüberprüfungen und Laufzeitbibliotheken viele Arten von Speichersicherheitsfehlern genau diagnostizieren, wenn sie zur Laufzeit auftreten.

Abfangen von Funktionen

AddressSanitizer erreicht das Abfangen von Funktionen durch viele Hotpatchingtechniken. Diese Techniken sind am besten im Quellcode selbst dokumentiert.

Die Laufzeitbibliotheken fangen viele allgemeine Funktionen zur Speicherverwaltung und Speicherbearbeitung ab. Eine Liste finden Sie unter AddressSanitizer list of intercepted functions (AddressSanitizer-Liste der abgefangenen Funktionen). Die Zuordnungsinterzeptoren verwalten Metadaten und Schattenbytes im Zusammenhang mit jedem Zuordnungsaufruf. Jedes Mal, wenn eine CRT-Funktion wie malloc oder aufgerufen delete wird, legen die Interceptors bestimmte Werte im Schattenspeicherbereich von AddressSanitizer fest, um anzugeben, ob auf diese Heapspeicherorte derzeit zugegriffen werden kann und welche Begrenzungen der Zuordnung bestehen. Diese Schattenbytes ermöglichen es den vom Compiler generierten Überprüfungen der Schattenbytes, zu bestimmen, ob eine Last oder ein Speicher gültig ist.

Das Abfangen ist nicht garantiert erfolgreich. Wenn ein Funktionsprolog zu kurz ist, damit ein jmp geschrieben werden kann, kann das Abfangen fehlschlagen. Wenn ein Abfangfehler auftritt, löst das Programm eine aus debugbreak und hält an. Wenn Sie einen Debugger anfügen, wird die Ursache des Abfangproblems deutlich. Wenn sie dieses Problem haben, melden Sie einen Fehler.

Hinweis

Benutzer können optional versuchen, nach einem fehlgeschlagenen Abfangen fortzufahren, indem sie die Umgebungsvariable ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE auf einen beliebigen Wert festlegen. Das Fortsetzen nach einem Abfangfehler kann zu fehlenden Fehlerberichten für diese Funktion führen.

Benutzerdefinierte Zuweisungen und die AddressSanitizer-Runtime

Die AddressSanitizer-Runtime stellt Interceptors für allgemeine Zuweisungsschnittstellen bereit, malloc/free , new/deleteHeapAlloc/HeapFree , (über RtlAllocateHeap/RtlFreeHeap ). Viele Programme verwenden aus einem oder mehreren Gründen benutzerdefinierte Zuweisungen. Ein Beispiel wäre jedes Programm, das dlmalloc verwendet, oder eine Projektmappe, die die std::allocator -Schnittstelle und VirtualAlloc() verwendet. Der Compiler kann einer benutzerdefinierten Zuweisung nicht automatisch Schattenspeicherverwaltungsaufrufe hinzufügen. Es liegt in der Verantwortung des Benutzers, die bereitgestellte benutzeroberfläche für manuelle Gasezu verwenden. Diese API ermöglicht es diesen Zuweisungen, ordnungsgemäß mit der vorhandenen AddressSanitizer-Runtime und Schatten bytekonventionen zu funktionieren.

Manuelle AddressSanitizer-Vergasungsschnittstelle

Die Benutzeroberfläche für das Aufklären ist einfach, erzwingt jedoch Ausrichtungseinschränkungen für den Benutzer. Benutzer können diese Prototypen importieren, indem sie sanitizer/asan_interface.h importieren. Hier sind die Schnittstellenfunktionsprototypen:

void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);

Der Einfachheit halber stellt die AddressSanitizer-Schnittstellenheaderdatei Wrappermakros bereit. Diese Makros überprüfen, ob die AddressSanitizer-Funktionalität während der Kompilierung aktiviert ist. Sie ermöglichen es Ihrem Quellcode, die Gasfunktionsaufrufe auszulassen, wenn sie nicht benötigt werden. Diese Makros sollten gegenüber dem direkten Aufrufen der oben genannten Funktionen bevorzugt werden:

#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)

Ausrichtungsanforderungen für AddressSanitizer-Gabe

Bei manuellen Schäden durch Schattenbytes müssen die Ausrichtungsanforderungen berücksichtigt werden. Der Benutzer muss bei Bedarf Auffüllung hinzufügen, damit die Schattenbytes an einer Bytegrenze im Schattenspeicher enden. Jedes Bit im AddressSanitizer-Schattenspeicher codiert den Zustand eines einzelnen Byte im Speicher der Anwendung. Diese Codierung bedeutet, dass die Gesamtgröße jeder Zuordnung, einschließlich aller Auffüllungen, an einer 8-Byte-Grenze ausgerichtet werden muss. Wenn die Ausrichtungsanforderung nicht erfüllt wird, kann dies zu einer falschen Fehlerberichterstattung führen. Die falsche Berichterstellung kann sich als fehlende Berichte (false negatives Ergebnis) oder Berichte zu Nichtfehlern (falsch positive Ergebnisse) manifestieren.

Eine Abbildung der Ausrichtungsanforderungen und potenziellen Probleme finden Sie in den bereitgestellten ASan-Ausrichtungsbeispielen. Eine ist ein kleines Programm, um zu zeigen, was bei manueller Schattenspeicher-Auslastung schief gehen kann. Die zweite ist eine Beispielimplementierungen der manuellen Gasung mithilfe der std::allocator -Schnittstelle.

Laufzeitoptionen

Microsoft C/C++ (MSVC) verwendet eine Runtime, die auf der Clang AddressSanitizer-Runtime aus dem llvm-project-Repositorybasiert. Aus diesem Grund werden die meisten Laufzeitoptionen von den beiden Versionen gemeinsam genutzt. Eine vollständige Liste der öffentlichen Clang-Laufzeitoptionen finden Sie hier. Wir dokumentieren einige Unterschiede in den folgenden Abschnitten. Wenn Sie Optionen ermitteln, die nicht wie erwartet funktionieren, melden Sie einen Fehler.

Nicht unterstützte AddressSanitizer-Optionen

  • detect_container_overflow
  • unmap_shadow_on_exit

Hinweis

Die Runtimeoption AddressSanitizer halt_on_error funktioniert nicht wie erwartet. Sowohl in Clang als auch in den MSVC Laufzeitbibliotheken werden viele Fehlertypen als nicht zusammenhängendbetrachtet, einschließlich der meisten Speicherbeschädigungsfehler.

Weitere Informationen finden Sie im Abschnitt Unterschiede mit Clang 12.0.

MSVC-spezifischen AddressSanitizer-Laufzeitoptionen

  • windows_hook_legacy_allocators Boolescher Wert, auf festgelegt, true um das Abfangen von GlobalAlloc - und LocalAlloc -Zuweisungen zu ermöglichen.

Hinweis

Die Option windows_hook_legacy_allocators war in der öffentlichen llvm-project-Runtime nicht verfügbar, als dieser Artikel geschrieben wurde. Die Option kann schließlich wieder zum öffentlichen Projekt beitragen. dies hängt jedoch von der Codeüberprüfung und der Akzeptanz durch die Community ab.

Die Option windows_hook_rtl_allocators , zuvor eine Aktivierungsfunktion, während AddressSanitizer experimentell war, ist jetzt standardmäßig aktiviert.

AddressSanitizer-Liste abgefangener Funktionen (Windows)

Die AddressSanitizer-Runtime patcht viele Funktionen, um Speichersicherheitsprüfungen zur Laufzeit zu ermöglichen. Hier ist eine nicht vollständige Liste der Funktionen, die von der AddressSanitizer-Laufzeit überwacht werden.

Standard-Interceptors

Optionale Interceptors

Die hier aufgeführten Interceptors werden nur installiert, wenn eine AddressSanitizer-Runtimeoption aktiviert ist. Legen Sie windows_hook_legacy_allocators diese Option true auf fest, um das Abfangen von Legacyzuweisungen zu aktivieren. set ASAN_OPTIONS=windows_hook_legacy_allocators=true

Siehe auch

Übersicht über AddressSanitizer
Bekannte Probleme von AddressSanitizer
Kompilierungs- und Sprachreferenz für AddressSanitizer
AddressSanitizer-Schattenbytes
AddressSanitizer-Tests in der Cloud oder verteilten Umgebungen
Integration des AddressSanitizer-Debuggers
AddressSanitizer-Fehlerbeispiele