Среда выполнения 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 не i386x86_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 связана для различных параметров компилятора:

Схема связывания библиотеки 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 была связана до Visual Studio 2022 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/HeapAllocnewчерез).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и VirtualProtectVirtualQuery функции для защиты. Этот параметр доступен в 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.

Перехватчики по умолчанию

Необязательные перехватчики

Перехватчики, перечисленные здесь, устанавливаются только в том случае, если включен параметр среды выполнения AddressSanitizer. Установите для windows_hook_legacy_allocatorsfalse отключения перехвата устаревшего распределителя. set ASAN_OPTIONS=windows_hook_legacy_allocators=false

См. также

Обзор AddressSanitizer
Известные проблемы AddressSanitizer
Справочник по сборке и языку AddressSanitizer
Теневой байт AddressSanitizer
Облачное или распределенное тестирование AddressSanitizer
Интеграция отладчика AddressSanitizer
Примеры ошибок AddressSanitizer