Дезинфицирующее средство кода
Эта статья нуждается в дополнительных цитатах для проверки . ( июль 2014 г. ) |
Средство очистки кода — это инструмент программирования, который обнаруживает ошибки в форме неопределенного или подозрительного поведения с помощью компилятора, вставляющего инструментальный код во время выполнения. Этот класс инструментов был впервые представлен Google AddressSanitizer (или ASan ) в 2012 году, который использует напрямую отображаемую теневую память для обнаружения повреждений памяти, таких как переполнение буфера или доступ к висячему указателю (использование после освобождения).
АдресСанитайзер
[ редактировать ]ASan от Google, представленный в 2012 году, использует схему теневой памяти для обнаружения ошибок памяти. Он доступен в:
- Clang (начиная с версии 3.1 [1] )
- GCC (начиная с версии 4.8 [2] )
- Xcode (начиная с версии 7.0 [3] )
- MSVC (широко доступен, начиная с версии 16.9). [4] ).
В среднем инструментарий увеличивает время обработки примерно на 73% и использование памяти на 240%. [5] Существует ASan с аппаратным ускорением под названием HWAsan, доступный для AArch64 и (в ограниченном виде) x86_64. [6]
AddressSanitizer не обнаруживает никаких неинициализированных операций чтения из памяти (но это обнаруживается MemorySanitizer). [7] ), и обнаруживает только некоторые ошибки использования после возврата. [8] Он также не способен обнаруживать все произвольные ошибки повреждения памяти, а также все произвольные ошибки записи из-за переполнения/переполнения целого числа (когда целое число с неопределенным поведением используется для расчета смещения адреса памяти). Соседние буферы в структурах и классах не защищены от переполнения, отчасти для предотвращения нарушения обратной совместимости. [9]
KernelAddressSanitizer
[ редактировать ]KernelAddressSanitizer KASan ( ) обнаруживает ошибки динамической памяти в ядре Linux. [10] Для инструментирования ядра требуется специальная функция в компиляторе, предоставляющая -fsanitize=kernel-address параметр командной строки, поскольку ядра не используют то же адресное пространство, что и обычные программы. [11] [12]
Другие дезинфицирующие средства
[ редактировать ]Google также выпустила LeakSanitizer (LSan, утечки памяти ), ThreadSanitizer (TSan, гонки данных и взаимоблокировки ), MemorySanitizer (MSan, неинициализированная память ) и UndefinedBehaviorSanitizer ( UBSan , неопределенное поведение , с детальным контролем). [13] Эти инструменты обычно доступны в Clang/LLVM и GCC. [14] [15] [16] Подобно KASan, существуют версии LSan, MSan, Tsan для конкретного ядра, а также полностью оригинальные средства очистки ядра, такие как KFENCE и KCSan. [17]
Дополнительные инструменты дезинфекции (сгруппированные по составителям в разделе -fsanitize или аналогичный флаг) включают: [14] [15] [16]
- LLVM Целостность потока управления и его аналог в ядре, который проверяет виртуальные таблицы и приведение типов на наличие CFI на переднем крае.
- MemTagSanitizer, инструмент, подобный ASan, который использует функции Armv8.5-A для очень низких накладных расходов.
- ShadowCallStack, инструмент AArch64, обеспечивающий теневого стека. защиту
- Scudo Hardened Allocator, альтернативный распределитель памяти, включающий GWP-ASan, вероятностный аналог ASan с низкими накладными расходами. [18]
- libFuzzer, инструмент LLVM, который добавляет покрытие кода к фаззингу. [19]
Использование
[ редактировать ]Средство очистки кода обнаруживает подозрительное поведение во время работы программы. Один из распространенных способов использования дезинфицирующего средства — объединить его с фаззингом , который генерирует входные данные, которые могут вызвать ошибки. [20]
Пользователи
[ редактировать ]Разработчики Chromium и Firefox являются активными пользователями AddressSanitizer; [20] [21] инструмент обнаружил сотни ошибок в этих веб-браузерах. [22] обнаружено несколько ошибок. В FFmpeg [23] и ФриТайп . [24] Ядро Linux включило AddressSanitizer для архитектуры x86-64 , начиная с версии Linux 4.0.
Примеры
[ редактировать ]ASan: использование кучи после освобождения
[ редактировать ]// To compile: g++ -O -g -fsanitize=address heap-use-after-free.cc
int main(int argc, char **argv) {
int *array = new int[100];
delete [] array;
return array[argc]; // BOOM
}
$ ./a.out ==5587==ERROR: AddressSanitizer: heap-use-after-free on address 0x61400000fe44 at pc 0x47b55f bp 0x7ffc36b28200 sp 0x7ffc36b281f8 READ of size 4 at 0x61400000fe44 thread T0 #0 0x47b55e in main /home/test/example_UseAfterFree.cc:5 #1 0x7f15cfe71b14 in __libc_start_main (/lib64/libc.so.6+0x21b14) #2 0x47b44c in _start (/root/a.out+0x47b44c) 0x61400000fe44 is located 4 bytes inside of 400-byte region [0x61400000fe40,0x61400000ffd0) freed by thread T0 here: #0 0x465da9 in operator delete[](void*) (/root/a.out+0x465da9) #1 0x47b529 in main /home/test/example_UseAfterFree.cc:4 previously allocated by thread T0 here: #0 0x465aa9 in operator new[](unsigned long) (/root/a.out+0x465aa9) #1 0x47b51e in main /home/test/example_UseAfterFree.cc:3 SUMMARY: AddressSanitizer: heap-use-after-free /home/test/example_UseAfterFree.cc:5 main Shadow bytes around the buggy address: [...] 0x0c287fff9fb0: fa 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 [...] Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 ASan internal: fe ==5587==ABORTING
ASan: переполнение буфера кучи
[ редактировать ]// RUN: clang++ -O -g -fsanitize=address heap-buf-of.cc && ./a.out
int main(int argc, char **argv) {
int *array = new int[100];
array[0] = 0;
int res = array[argc + 100]; // BOOM
delete [] array;
return res;
}
==25372==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61400000ffd4 at pc 0x0000004ddb59 bp 0x7fffea6005a0 sp 0x7fffea600598 READ of size 4 at 0x61400000ffd4 thread T0 #0 0x46bfee in main /tmp/main.cpp:4:13 0x61400000ffd4 is located 4 bytes to the right of 400-byte region [0x61400000fe40,0x61400000ffd0) allocated by thread T0 here: #0 0x4536e1 in operator delete[](void*) #1 0x46bfb9 in main /tmp/main.cpp:2:16
ASan: переполнение буфера стека
[ редактировать ]// RUN: clang -O -g -fsanitize=address stack-buf-of.cc && ./a.out
int main(int argc, char **argv) {
int stack_array[100];
stack_array[1] = 0;
return stack_array[argc + 100]; // BOOM
}
==7405==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff64740634 at pc 0x46c103 bp 0x7fff64740470 sp 0x7fff64740468 READ of size 4 at 0x7fff64740634 thread T0 #0 0x46c102 in main /tmp/example_StackOutOfBounds.cc:5 Address 0x7fff64740634 is located in stack of thread T0 at offset 436 in frame #0 0x46bfaf in main /tmp/example_StackOutOfBounds.cc:2 This frame has 1 object(s): [32, 432) 'stack_array' <== Memory access at offset 436 overflows this variable
ASan: переполнение глобального буфера
[ редактировать ]// RUN: clang -O -g -fsanitize=address global-buf-of.cc && ./a.out
int global_array[100] = {-1};
int main(int argc, char **argv) {
return global_array[argc + 100]; // BOOM
}
==7455==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000689b54 at pc 0x46bfd8 bp 0x7fff515e5ba0 sp 0x7fff515e5b98 READ of size 4 at 0x000000689b54 thread T0 #0 0x46bfd7 in main /tmp/example_GlobalOutOfBounds.cc:4 0x000000689b54 is located 4 bytes to the right of global variable 'global_array' from 'example_GlobalOutOfBounds.cc' (0x6899c0) of size 400
UBSan: разыменование nullptr
[ редактировать ]// RUN: g++ -O -g -fsanitize=null null-dereference.c && ./a.out
int main(int argc, char **argv) {
const char * ptr = nullptr;
return *ptr; // BOOM
}
null-dereference.c:4:10: runtime error: load of null pointer of type 'const char' Segmentation fault (core dumped)
См. также
[ редактировать ]- Интел МПХ
- Средство проверки приложений (AppVerif.exe) в Microsoft Windows SDK
- Valgrind — инструмент отладки памяти.
Ссылки
[ редактировать ]- ^ «Примечания к выпуску LLVM 3.1» . ЛЛВМ . Проверено 8 февраля 2014 г.
- ^ «Примечания к выпуску GCC 4.8» . ССЗ . Проверено 8 февраля 2014 г.
- ^ «Адресное дезинфицирующее средство | Документация разработчика Apple» .
- ^ «Примечания к выпуску Visual Studio 2019 версии 16.9» . Майкрософт . Проверено 5 марта 2021 г.
- ^ Константин Серебряный; Дерек Брюнинг; Александр Потапенко; Дмитрий Вьюков. «AddressSanitizer: быстрая проверка работоспособности адресов» (PDF) . Материалы конференции USENIX 2012 г., посвященной ежегодной технической конференции .
- ^ «Документация по проектированию AddressSanitizer с аппаратной поддержкой — документация Clang 17.0.0git» . clang.llvm.org .
- ^ «Санитаризация памяти» . Гитхаб .
- ^ «Сравнение инструментов памяти» . АдресСанитайзер Wiki . Проверено 1 декабря 2017 г.
- ^ «Обход AddressSanitizer» (PDF) . Эрик Уимберли . Проверено 1 июля 2014 г.
- ^ «КернелАдрессСанитайзер (КАСАН)» . Архивировано из оригинала 15 сентября 2015 г.
- ^ Джейк Эдж. «Очиститель адресов ядра» .
- ^ Джонатан Корбет. «3.20 Окно слияния, часть 2» .
- ^ Google (2 марта 2023 г.). «санитайзеры: этот проект является домом для дезинфицирующих средств: AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer и других» . Гитхаб . Google.
{{cite web}}
:|last1=
имеет общее имя ( справка ) - ^ Перейти обратно: а б «Дезинфицирующее средство — Книга о нестабильной ржавчине» . doc.rust-lang.org .
Эта функция позволяет использовать одно из следующих дезинфицирующих средств: [...] ControlFlowIntegrity LLVM Control Flow Integrity
- ^ Перейти обратно: а б «Руководство пользователя компилятора Clang — документация Clang 17.0.0git» . clang.llvm.org .
-f[no-]sanitize=check1,check2,... Включить проверки во время выполнения на предмет различных форм неопределенного или подозрительного поведения.
- ^ Перейти обратно: а б «Параметры инструментирования (с использованием коллекции компиляторов GNU (GCC))» . gcc.gnu.org .
- ^ «Дезинфицирующие средства ядра Linux» . Google. 2 марта 2023 г.
- ^ «GWP-ASan — документация LLVM 17.0.0git» . llvm.org .
- ^ «libFuzzer — библиотека для нечеткого тестирования на основе покрытия. — Документация LLVM 17.0.0git» . llvm.org .
- ^ Перейти обратно: а б Абхишек Арья; Крис Неккар; Команда безопасности Chrome. «Фаззинг ради безопасности» .
- ^ «Защита Firefox: пробуем новые методы анализа кода» . Архивировано из оригинала 07 марта 2016 г. Проверено 18 июня 2018 г.
- ^ «Некоторые ошибки, обнаруженные AddressSanitizer» . Гитхаб .
- ^ Матеуш Юрчик; Гинваэль Колдвинд (10 января 2014 г.). «FFmpeg и тысяча исправлений» . J00Ru // Технический блог Vx .
- ^ «Результаты поиска AddressSanitizer в ошибках FreeType» .