AddressSanitizer - Википедия - AddressSanitizer

AddressSanitizer (или же ASan) - это инструмент программирования с открытым исходным кодом, созданный Google это обнаруживает повреждение памяти ошибки Такие как переполнение буфера или доступ к висячий указатель (использовать после бесплатного использования). AddressSanitizer основан на компилятор приборы и с прямым отображением теневая память. AddressSanitizer в настоящее время реализован в Лязг (начиная с версии 3.1[1]) , GCC (начиная с версии 4.8[2]), Xcode (начиная с версии 7.0[3]) и MSVC (начиная с версии 16.4[4]). В среднем инструментальные средства увеличивают время обработки примерно на 73% и использование памяти на 240%.[5]

Пользователи

Хром и Fire Fox разработчики являются активными пользователями AddressSanitizer;[6][7] инструмент обнаружил сотни ошибок в этих веб-браузерах.[8]Был обнаружен ряд ошибок в FFmpeg[9]и FreeType.[10] В Ядро Linux включил AddressSanitizer для x86-64 архитектура Linux версии 4.0.

KernelAddressSanitizer

В KernelAddressSanitizer (КАСАН) обнаруживает ошибки динамической памяти в ядре Linux.[11] Инструментарий ядра требует специальной функции в компиляторе, предоставляющем -fsanitize = адрес-ядра параметр командной строки, поскольку ядра не используют то же адресное пространство, что и обычные программы.[12][13]

Примеры

Куча-использование-после освобождения

1 // Для компиляции: g ++ -O -g -fsanitize = адрес heap-use-after-free.cc2 int главный(int argc, char **argv) {3   int *множество = новый int[100];4   Удалить [] множество;5   возвращаться множество[argc];  // БУМ6 }
$ ./a.out==5587== ОШИБКА: AddressSanitizer: heap-use-after-free на адресе 0x61400000fe44 на компьютере 0x47b55f bp 0x7ffc36b28200 sp 0x7ffc36b281f8READ размера 4 на 0x61400000fe44 thread T0 # 0 0x47b55e / home / testfterA в основном / testfter .cc: 7 # 1 0x7f15cfe71b14 в __libc_start_main (/lib64/libc.so.6+0x21b14) # 2 0x47b44c в _start (/root/a.out+0x47b44c)0x61400000fe44 находится в 4 байтах внутри области 400 -1400000 [0x406000], 0x61400000ffd0) освобожден потоком T0 здесь: # 0 0x465da9 в операторе delete [] (void *) (/root/a.out+0x465da9) # 1 0x47b529 в основном /home/test/example_UseAfterFree.cc:6 ранее выделен потоком T0 здесь : # 0 0x465aa9 in operator new [] (unsigned long) (/root/a.out+0x465aa9) # 1 0x47b51e в основном /home/test/example_UseAfterFree.cc:5 РЕЗЮМЕ: AddressSanitizer: heap-use-after-free / home /test/example_UseAfterFree.cc:7 байтов mainShadow вокруг ошибочного адреса: 0x0c287fff9f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9f90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9fa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c287fff9fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa => 0x0c287fff9fc0: fa fa fa fa fa fa fa fa [fd] fd fd fd fd fd fd fd 0x0c287fff9fd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c287fff9fe0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c287fff9ff0: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa 0x0c fa fa fa fa000: fa fa fa fa fa fa 0x0c287fffa010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Легенда теневого байта (один теневой байт представляет 8 байтов приложения): Адресуемый: 00 Частично адресуемый: 01 02 03 04 05 06 07 Куча левая красная зона: fa Куча правая красная зона: fb Освобожденная область кучи: fd Стек левая красная зона: f1 Средняя красная зона стека: f2 Стопка правой красной зоны: f3 Частичная красная зона стека: f4 Стек после возврата: f5 Использование стека после области действия: f8 Globa l redzone: f9 Глобальный порядок инициализации: f6 Отравлен пользователем: f7 ASan internal: fe == 5587 == ABORTING

Переполнение буфера кучи

1 // ЗАПУСК: clang ++ -O -g -fsanitize = адрес% t && ./a.out2 int главный(int argc, char **argv) {3   int *множество = новый int[100];4   множество[0] = 0;5   int res = множество[argc + 100];  // БУМ6   Удалить [] множество;7   возвращаться res;8 }
== 25372 == ОШИБКА: AddressSanitizer: переполнение буфера кучи на адресе 0x61400000ffd4 на ПК 0x0000004ddb59 bp 0x7fffea6005a0 sp 0x7fffea600598READ размера 4 на 0x61400000ffd4 thread T0 # 0 0x46bfee/4000:38 справа от 400-байтовой области [0x61400000fe40,0x61400000ffd0), выделенной потоком T0 здесь: # 0 0x4536e1 в операторе delete [] (void *) # 1 0x46bfb9 в основном файле /tmp/main.cpp:2:16

Стек-буфер-переполнение

1 // ЗАПУСК: clang -O -g -fsanitize = адрес% t && ./a.out2 int главный(int argc, char **argv) {3   int stack_array[100];4   stack_array[1] = 0;5   возвращаться stack_array[argc + 100];  // БУМ6 }
== 7405 == ОШИБКА: AddressSanitizer: переполнение буфера стека по адресу 0x7fff64740634 на ПК 0x46c103 bp 0x7fff64740470 sp 0x7fff64740468READ размера 4 на 0x7fff64740634 thread T0 # 0 0x46c10cc2, расположенном в файле main /tress740634 thread T0 # 0 0x46c10cc2 в файле main /tress6x7 поток T0 со смещением 436 в кадре № 0 0x46bfaf в основном /tmp/example_StackOutOfBounds.cc:2 Этот кадр имеет 1 объект (ы): [32, 432) 'stack_array' <== Доступ к памяти со смещением 436 переполняет эту переменную

Глобальное переполнение буфера

// ЗАПУСК: clang -O -g -fsanitize = адрес% t && ./a.outint global_array[100] = {-1};int главный(int argc, char **argv) {  возвращаться global_array[argc + 100];  // БУМ}
== 7455 == ОШИБКА: AddressSanitizer: global-buffer-overflow на адресе 0x000000689b54 на ПК 0x46bfd8 bp 0x7fff515e5ba0 sp 0x7fff515e5b98READ размера 4 на 0x000000689b54 thread T0 # 0 0x46bfdexampleb40x02000 в файле main /tlomp справа от глобальной переменной global_array из example_GlobalOutOfBounds.cc (0x6899c0) размером 400

Ограничения

AddressSanitizer не обнаруживает чтение неинициализированной памяти (но это определяется Память[14]), и обнаруживает только некоторые ошибки использования после возврата.[15] Он также не способен обнаруживать все ошибки произвольного повреждения памяти или все ошибки произвольной записи из-за целочисленного переполнения / переполнения (когда целое число с неопределенным поведением используется для вычисления смещения адресов памяти). Смежные буферы в структурах и классах не защищены от переполнения, отчасти для предотвращения нарушения обратной совместимости.[16]

Смотрите также

Рекомендации

  1. ^ «Примечания к выпуску LLVM 3.1». LLVM. Получено 8 февраля 2014.
  2. ^ «Примечания к выпуску GCC 4.8». GCC. Получено 8 февраля 2014.
  3. ^ «Address Sanitizer | Документация для разработчиков Apple».
  4. ^ «Заметки о выпуске Visual Studio 2019 версии 16.4». Microsoft. Получено 6 ноября 2020.
  5. ^ Константин Серебряный; Дерек Брюнинг; Александр Потапенко; Дмитрий Вьюков. «AddressSanitizer: быстрая проверка корректности адресов» (PDF). Материалы конференции USENIX 2012 по Ежегодной технической конференции.
  6. ^ Абхишек Арья; Крис Неккар; Команда безопасности Chrome. «Фаззинг для безопасности».
  7. ^ «Защита Firefox: новые методы анализа кода». Архивировано из оригинал на 2016-03-07. Получено 2018-06-18.
  8. ^ «Некоторые из ошибок, обнаруженных AddressSanitizer».
  9. ^ Матеуш Юрчик; Гинваэль Холодный Ветер (10 января 2014 г.). «FFmpeg и тысяча исправлений».
  10. ^ "Результаты поиска AddressSanitizer в FreeType Bugs".
  11. ^ "KernelAddressSanitizer (КАСАН)". Архивировано из оригинал на 2016-12-23. Получено 2016-12-08.
  12. ^ Джейк Эдж. "Средство очистки адресов ядра".
  13. ^ Джонатан Корбет. "3.20 окно слияния, часть 2".
  14. ^ "MemorySanitizer".
  15. ^ "ComparisonOfMemoryTools". AddressSanitizer Вики. Получено 1 декабря 2017.
  16. ^ «Обход AddressSanitizer» (PDF). Эрик Уимберли. Получено 1 июля 2014.

внешняя ссылка