Jump to content

Дезинфицирующее средство кода

Средство очистки кода — это инструмент программирования, который обнаруживает ошибки в форме неопределенного или подозрительного поведения с помощью компилятора, вставляющего инструментальный код во время выполнения. Этот класс инструментов был впервые представлен 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)

См. также

[ редактировать ]
  1. ^ «Примечания к выпуску LLVM 3.1» . ЛЛВМ . Проверено 8 февраля 2014 г.
  2. ^ «Примечания к выпуску GCC 4.8» . ССЗ . Проверено 8 февраля 2014 г.
  3. ^ «Адресное дезинфицирующее средство | Документация разработчика Apple» .
  4. ^ «Примечания к выпуску Visual Studio 2019 версии 16.9» . Майкрософт . Проверено 5 марта 2021 г.
  5. ^ Константин Серебряный; Дерек Брюнинг; Александр Потапенко; Дмитрий Вьюков. «AddressSanitizer: быстрая проверка работоспособности адресов» (PDF) . Материалы конференции USENIX 2012 г., посвященной ежегодной технической конференции .
  6. ^ «Документация по проектированию AddressSanitizer с аппаратной поддержкой — документация Clang 17.0.0git» . clang.llvm.org .
  7. ^ «Санитаризация памяти» . Гитхаб .
  8. ^ «Сравнение инструментов памяти» . АдресСанитайзер Wiki . Проверено 1 декабря 2017 г.
  9. ^ «Обход AddressSanitizer» (PDF) . Эрик Уимберли . Проверено 1 июля 2014 г.
  10. ^ «КернелАдрессСанитайзер (КАСАН)» . Архивировано из оригинала 15 сентября 2015 г.
  11. ^ Джейк Эдж. «Очиститель адресов ядра» .
  12. ^ Джонатан Корбет. «3.20 Окно слияния, часть 2» .
  13. ^ Google (2 марта 2023 г.). «санитайзеры: этот проект является домом для дезинфицирующих средств: AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer и других» . Гитхаб . Google. {{cite web}}: |last1= имеет общее имя ( справка )
  14. ^ Перейти обратно: а б «Дезинфицирующее средство — Книга о нестабильной ржавчине» . doc.rust-lang.org . Эта функция позволяет использовать одно из следующих дезинфицирующих средств: [...] ControlFlowIntegrity LLVM Control Flow Integrity
  15. ^ Перейти обратно: а б «Руководство пользователя компилятора Clang — документация Clang 17.0.0git» . clang.llvm.org . -f[no-]sanitize=check1,check2,... Включить проверки во время выполнения на предмет различных форм неопределенного или подозрительного поведения.
  16. ^ Перейти обратно: а б «Параметры инструментирования (с использованием коллекции компиляторов GNU (GCC))» . gcc.gnu.org .
  17. ^ «Дезинфицирующие средства ядра Linux» . Google. 2 марта 2023 г.
  18. ^ «GWP-ASan — документация LLVM 17.0.0git» . llvm.org .
  19. ^ «libFuzzer — библиотека для нечеткого тестирования на основе покрытия. — Документация LLVM 17.0.0git» . llvm.org .
  20. ^ Перейти обратно: а б Абхишек Арья; Крис Неккар; Команда безопасности Chrome. «Фаззинг ради безопасности» .
  21. ^ «Защита Firefox: пробуем новые методы анализа кода» . Архивировано из оригинала 07 марта 2016 г. Проверено 18 июня 2018 г.
  22. ^ «Некоторые ошибки, обнаруженные AddressSanitizer» . Гитхаб .
  23. ^ Матеуш Юрчик; Гинваэль Колдвинд (10 января 2014 г.). «FFmpeg и тысяча исправлений» . J00Ru // Технический блог Vx .
  24. ^ «Результаты поиска AddressSanitizer в ошибках FreeType» .
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: b208384a512669f01faf04a13cfe0791__1719633480
URL1:https://arc.ask3.ru/arc/aa/b2/91/b208384a512669f01faf04a13cfe0791.html
Заголовок, (Title) документа по адресу, URL1:
Code sanitizer - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)