Среда выполнения AddressSanitizer
Библиотека среды выполнения AddressSanitizer перехватывает общие функции выделения памяти и операции, чтобы обеспечить проверку доступа к памяти. Существует несколько различных библиотек среды выполнения, поддерживающих различные типы исполняемых файлов компилятора. Компилятор и компоновщик автоматически связывают соответствующие библиотеки среды выполнения, если вы передаете /fsanitize=address
параметр во время компиляции. Поведение по умолчанию можно переопределить с помощью /NODEFAULTLIB
параметра во время ссылки. Дополнительные сведения см. в разделе о связывании на языке AddressSanitizer, сборке и отладке.
При компиляции с cl /fsanitize=address
помощью компилятор создает инструкции по управлению и проверке теневых байтов. Программа использует эту инструментацию для проверки доступа к памяти в стеке, в куче или в глобальной области. Компилятор также создает метаданные, описывающие стек и глобальные переменные. Эти метаданные позволяют среде выполнения создавать точные диагностика ошибки: имена функций, строки и столбцы в исходном коде. В сочетании компилятор проверяет и библиотеки среды выполнения точно диагностировать многие типы ошибок безопасности памяти, если они обнаружены во время выполнения.
Список библиотек среды выполнения для связывания со средой выполнения AddressSanitizer по состоянию на Visual Studio 17.7( предварительная версия 3) следует. Дополнительные сведения о /MT
параметрах (статически связывая среду выполнения) и /MD
(динамически связывая редист в среде выполнения) см. в разделе /MD, /MT, /LD (использование библиотеки времени выполнения).
Примечание.
В следующей таблице имеет {arch}
значение i386
или x86_64
.
Эти библиотеки используют соглашения Clang для имен архитектуры. Соглашения MSVC обычно x86
и x64
не i386
x86_64
относятся к тем же архитектурам.
Параметр CRT | Библиотека среды выполнения AddressSanitizer (.lib) | Двоичный файл среды выполнения адресов (.dll) |
---|---|---|
/MT или /MTd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_static_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MD или /MDd |
clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
На следующей схеме показано, как библиотеки языковой среды выполнения связаны для /MT
параметров компилятора , /MD
а /MDd
также для параметров компилятора/MTd
:
На изображении показаны три сценария связывания библиотеки среды выполнения. Первый — /MT или /MTd. My_exe.exe и my_dll.dll отображаются с собственными копиями статически связанных сред выполнения VCRuntime, universal CRT и C++ . В сценариях показано значение /MD, в котором my_exe.exe и my_dll.dll совместно использовать vcruntime140.dll, ucrtbase.dll и msvcp140.dll. Последний сценарий показывает /MDd, в котором my_exe.exe и my_dll.dll совместно использовать отладочные версии сред выполнения: vcruntime140d.dll, ucrtbased.dll и msvcp140d.dll
На следующей схеме показано, как библиотека ASan связана для различных параметров компилятора:
На рисунке показаны четыре сценария связывания библиотеки среды выполнения ASan. Сценарии предназначены для /MT (статически связывающая среду выполнения), /MTd (статически связывающая среду выполнения отладки), /MD (динамически связывающая redist во время выполнения), /MDd (динамически связывает отладочный редист во время выполнения). Во всех случаях my_exe.exe ссылки и его связи my_dll.dll ссылку на один экземпляр clang-rt.asan-dynamix-x86_64.dll.
Даже при статической компоновке библиотека DLL среды выполнения ASan должна присутствовать во время выполнения, в отличие от других компонентов среды выполнения C.
предыдущих версий
До Предварительной версии 3 Visual Studio 17.7 статически связанные сборки (/MT
или /MTd
) не использовали зависимость DLL. Вместо этого среда выполнения AddressSanitizer была статически связана с EXE пользователя. Затем проекты DLL загружают экспорт из EXE пользователя для доступа к функциям ASan.
Динамически связанные проекты (/MD
или /MDd
) использовали разные библиотеки и библиотеки DLL в зависимости от того, настроен ли проект для отладки или выпуска. Дополнительные сведения об этих изменениях и их мотивациях см. в msVC Address Sanitizer — одна библиотека DLL для всех конфигураций среды выполнения.
В следующей таблице описано предыдущее поведение связывания библиотеки среды выполнения AddressSanitizer до Visual Studio 17.7 Preview 3:
Параметр CRT | DLL или EXE | ОТЛАЖИВАТЬ? | Библиотека ASan (.lib ) |
Двоичный файл среды выполнения ASan (.dll ) |
---|---|---|---|---|
/MT |
EXE | No | clang_rt.asan-{arch} , clang_rt.asan_cxx-{arch} |
нет |
/MT |
DLL-библиотеки | No | clang_rt.asan_dll_thunk-{arch} |
нет |
/MD |
Любой из | No | clang_rt.asan_dynamic-{arch} , clang_rt.asan_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dynamic-{arch} |
/MT |
EXE | Да | clang_rt.asan_dbg-{arch} , clang_rt.asan_dbg_cxx-{arch} |
нет |
/MT |
DLL-библиотеки | Да | clang_rt.asan_dbg_dll_thunk-{arch} |
Не допускается |
/MD |
Можно использовать | Да | clang_rt.asan_dbg_dynamic-{arch} , clang_rt.asan_dbg_dynamic_runtime_thunk-{arch} |
clang_rt.asan_dbg_dynamic-{arch} |
На следующей схеме показано, как библиотека ASan была связана для различных параметров компилятора до Visual Studio 2022 17.7 Preview 3:
На рисунке показаны четыре сценария связывания библиотеки среды выполнения ASan. Сценарии предназначены для /MT (статически связывающая среду выполнения), /MTd (статически связывающая среду выполнения отладки), /MD (динамически связывающая redist во время выполнения), /MDd (динамически связывает отладочный редист во время выполнения). Для /MT my_exe.exe имеет статическую копию среды выполнения ASan. my_dll.dll ссылки на среду выполнения ASan в my_exe.exe. Для /MTd схема одинакова, за исключением того, что она использует отладочную статическую связанную среду выполнения ASan. Для /MD my_exe.exe и my_dll.dll ссылку на динамически связанную среду выполнения ASan с именем clang_rt.asan_dynamic-x86_64.dll. Для /MDd схема совпадает с my_exe.exe и my_dll.dll ссылкой на отладочную среду выполнения ASan с именем clang_rt.asan_dbg_dynamic-x86_64.dll.
Перехват функций
AddressSanitizer достигает перехвата функций с помощью многих методов горячей патчинга. Эти методы лучше всего документируются в самом исходном коде.
Библиотеки среды выполнения перехватывают множество распространенных функций управления памятью и операций с памятью. Список списков см. в списке "AddressSanitizer" для перехваченных функций. Перехватчики выделения управляют метаданными и теневыми байтами, связанными с каждым вызовом выделения. При каждом вызове функции CRT, например malloc
или delete
вызове, перехватчики задают определенные значения в регионе теневой памяти AddressSanitizer, чтобы указать, доступны ли эти кучи и какие границы выделения имеются. Эти теневые байты позволяют компилятору проверять теневые байты , чтобы определить, является ли загрузка или хранилище допустимым.
Перехват не гарантируется успешно. Если пролог функции слишком короткий для jmp
записи, перехват может завершиться ошибкой. Если происходит сбой перехвата, программа выдает debugbreak
и останавливается. Если подключить отладчик, это делает причину проблемы перехвата ясной. Если у вас эта проблема, сообщите об ошибке.
Примечание.
Пользователи могут при необходимости попытаться продолжить перехват после сбоя, задав переменную ASAN_WIN_CONTINUE_ON_INTERCEPTION_FAILURE
среды любому значению. Продолжение последнего сбоя перехвата может привести к пропущенным отчетам об ошибках для этой функции.
Пользовательские распределители и среда выполнения AddressSanitizer
Среда выполнения AddressSanitizer предоставляет перехватчики для общих интерфейсов распределителя, malloc
/free
, (delete
/HeapFree
/HeapAlloc
new
через).RtlAllocateHeap
/RtlFreeHeap
Многие программы используют пользовательские распределители по одной или другой причине, например, любой программой dlmalloc
или решением с помощью std::allocator
интерфейса и VirtualAlloc()
. Компилятор не может автоматически добавлять вызовы управления теневой памятью в пользовательский распределитель. Это ответственность пользователя за использование предоставленного интерфейса ручного отравления. Этот API позволяет этим распределителям правильно работать с существующими соглашениями среды выполнения AddressSanitizer и теневых байтов.
Интерфейс отравлений AddressSanitizer вручную
Интерфейс для просвещений прост, но он накладывает ограничения выравнивания для пользователя. Пользователи могут импортировать эти прототипы путем импорта sanitizer/asan_interface.h
. Ниже приведены прототипы функций интерфейса:
void __asan_poison_memory_region(void const volatile *addr, size_t size);
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
Для удобства файл заголовка интерфейса AddressSanitizer предоставляет макросы оболочки. Эти макросы проверяют, включена ли функция AddressSanitizer во время компиляции. Они позволяют исходному коду пропускать вызовы функции отравлений, если они не нужны. Эти макросы должны быть предпочтительнее при вызове указанных выше функций напрямую:
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
Требования к выравниванию для отравлений AddressSanitizer
Любое отравление теневых байтов вручную должно учитывать требования к выравниванию. Пользователь должен добавить заполнение при необходимости, чтобы теневые байты заканчивались на границе байтов в теневой памяти. Каждый бит в теневой памяти AddressSanitizer кодирует состояние одного байта в памяти приложения. Это кодировка означает общий размер каждого выделения, включая любую заполнение, должен выровняться по 8-байтовой границе. Если требование выравнивания не удовлетворено, это может привести к неправильному отчету об ошибках. Неправильные отчеты могут проявляться как отсутствующие отчеты (ложные отрицательные) или отчеты о неисправных ошибках (ложные срабатывания).
Иллюстрация требования выравнивания и потенциальных проблем см. в приведенных примерах выравнивания ASan. Одна из них небольшая программа, чтобы показать, что может пойти не так с отравлением теневой памяти вручную. Второй пример реализации ручного отравления с помощью std::allocator
интерфейса.
Параметры времени выполнения
Microsoft C/C++ (MSVC) использует среду выполнения на основе среды выполнения Clang AddressSanitizer из репозитория llvm-project. Из-за этого большинство параметров среды выполнения используются между двумя версиями. Полный список общедоступных параметров среды выполнения Clang доступен здесь. Мы документируем некоторые различия в следующих разделах. Если вы обнаружите параметры, которые не работают должным образом, сообщите об ошибке.
Неподдерживаемые параметры AddressSanitizer
- detect_container_overflow
- unmap_shadow_on_exit
Примечание.
Параметр halt_on_error
среды выполнения AddressSanitizer не работает так, как можно ожидать. В библиотеках среды выполнения Clang и MSVC многие типы ошибок считаются неконтинуируемыми, включая большинство ошибок повреждения памяти.
Дополнительные сведения см. в разделе "Различия с Clang 12.0 ".
Параметры среды выполнения AddressSanitizer для MSVC
windows_hook_legacy_allocators
Логический, установите дляfalse
отключения перехватаGlobalAlloc
иLocalAlloc
распределителей.Примечание.
windows_hook_legacy_allocators
Параметр недоступен в общедоступной среде выполнения llvm-project при написании этой статьи. Этот вариант в конечном итоге может быть добавлен в общедоступный проект; однако это зависит от проверки кода и принятия сообщества.windows_hook_rtl_allocators
Параметр , ранее вариант согласия, в то время как AddressSanitizer был экспериментальным, теперь включен по умолчанию. В версиях до Visual Studio 2022 версии 17.4.6 значение параметра по умолчанию равноfalse
. В Visual Studio 2022 версии 17.4.6 и более поздних версиях параметрwindows_hook_rtl_allocators
поtrue
умолчанию.iat_overwrite
Строка, заданная"error"
по умолчанию. Существуют и другие возможные"protect"
"ignore"
значения. Некоторые модули могут перезаписатьimport address table
другие модули для настройки реализаций определенных функций. Например, драйверы обычно предоставляют пользовательские реализации для конкретного оборудования. Параметрiat_overwrite
управляет защитой среды выполнения AddressSanitizer от перезаписей для определенныхmemoryapi.h
функций. Среда выполнения в настоящее время отслеживаетVirtualAlloc
иVirtualProtect
VirtualQuery
функции для защиты. Этот параметр доступен в Visual Studio 2022 версии 17.5( предварительная версия 1 и более поздние версии). Следующиеiat_overwrite
значения определяют, как среда выполнения реагирует при перезаписи защищенных функций:- Если задано значение
"error"
(по умолчанию), среда выполнения сообщает об ошибке при обнаружении перезаписи. - Если задано значение
"protect"
, среда выполнения пытается избежать использования перезаписываемого определения и продолжается. Фактически исходноеmemoryapi
определение функции используется внутри среды выполнения, чтобы избежать бесконечного рекурсии. Другие модули в процессе по-прежнему используют перезаписанный определение. - Если задано значение
"ignore"
, среда выполнения не пытается исправить перезаписанные функции и продолжает выполнение.
- Если задано значение
windows_fast_fail_on_error
Логическое значение (false по умолчанию), котороеtrue
позволяет процессу завершить работу с __fastfail(71) после печати отчета об ошибке.
Примечание.
Если значение abort_on_error имеет значение true, в Windows программа завершается с выходом(3). Чтобы не изменить текущее поведение, мы решили вместо этого ввести этот новый параметр. Если оба abort_on_error и windows_fast_fail_on_error имеют значение true, программа завершит работу с __fastfail.
Список перехваченных функций AddressSanitizer (Windows)
Среда выполнения AddressSanitizer позволяет выполнять многие функции, чтобы обеспечить проверку безопасности памяти во время выполнения. Ниже приведен полный список функций, отслеживаемых средой выполнения AddressSanitizer.
Перехватчики по умолчанию
__C_specific_handler
(только x64)_aligned_free
_aligned_malloc
_aligned_msize
_aligned_realloc
_calloc_base
_calloc_crt
_calloc_dbg
(только для среды выполнения отладки)_except_handler3
(только x86)_except_handler4
(только x86) (undocumented)_expand
_expand_base
(undocumented)_expand_dbg
(только для среды выполнения отладки)_free_base
(undocumented)_free_dbg
(только для среды выполнения отладки)_malloc_base
(undocumented)_malloc_crt
(undocumented)_malloc_dbg
(только для среды выполнения отладки)_msize
_msize_base
(undocumented)_msize_dbg
(только для среды выполнения отладки)_realloc_base
(undocumented)_realloc_crt
(undocumented)_realloc_dbg
(только для среды выполнения отладки)_recalloc
_recalloc_base
(undocumented)_recalloc_crt
(undocumented)_recalloc_dbg
(только для среды выполнения отладки)_strdup
atoi
atol
calloc
CreateThread
free
frexp
longjmp
malloc
memchr
memcmp
memcpy
memmove
memset
RaiseException
realloc
RtlAllocateHeap
RtlCreateHeap
RtlDestroyHeap
RtlFreeHeap
RtlRaiseException
RtlReAllocateHeap
(undocumented)RtlSizeHeap
(undocumented)SetUnhandledExceptionFilter
strcat
strchr
strcmp
strcpy
strcspn
strdup
strlen
strncat
strncmp
strncpy
strnlen
strpbrk
strspn
strstr
strtok
strtol
wcslen
wcsnlen
Необязательные перехватчики
Перехватчики, перечисленные здесь, устанавливаются только в том случае, если включен параметр среды выполнения AddressSanitizer. Установите для windows_hook_legacy_allocators
false
отключения перехвата устаревшего распределителя.
set ASAN_OPTIONS=windows_hook_legacy_allocators=false
GlobalAlloc
GlobalFree
GlobalHandle
GlobalLock
GlobalReAlloc
GlobalSize
GlobalUnlock
LocalAlloc
LocalFree
LocalHandle
LocalLock
LocalReAlloc
LocalSize
LocalUnlock
См. также
Обзор AddressSanitizer
Известные проблемы AddressSanitizer
Справочник по сборке и языку AddressSanitizer
Теневой байт AddressSanitizer
Облачное или распределенное тестирование AddressSanitizer
Интеграция отладчика AddressSanitizer
Примеры ошибок AddressSanitizer