Download - Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)
![Page 1: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/1.jpg)
AddressSanitizer Как сделать программы на C/С++
надежнее и безопаснее
Костя СеребряныйGoogle
![Page 2: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/2.jpg)
План доклада
● Ошибки доступа в память (C/C++)● AddressSanitizer -- инструмент для
поиска ошибок○ Что делает○ Как работает
![Page 3: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/3.jpg)
Почему С или С++ ?
● Всё написано на C или C++○ Даже если Вы об этом не знаете
● Виртуальные машины (Java, Perl, Python)
● Базы данных (MySQL)
● Веб серверы (Apache)
● Все остальное тоже (libpng, libz, memcached)
![Page 4: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/4.jpg)
C++ в Google
● Всего > 100М строк кода○ Больше всего кода на С++
● Серверная часть○ Mapreduce, Bigtable, Spanner, Chubby, ...
● Chrome (> 10M строк)
![Page 5: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/5.jpg)
Плата за эффективность
+ "Ручное" управление памятью - Ошибки использования памяти * Переполнение буфера * Использование после free
Открытые ворота для хакеров
![Page 6: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/6.jpg)
Что же делать?
● Бинарная инструментация○ Valgrind, Dr.Memory, Intel Parallel Studio, Purify,
Bounds Checker, Insure++, ... ○ Медленно (> 20x), только heap
● Отладочный malloc○ Постраничная защита
■ electric fence, libgmalloc, Page Heap○ Магические значения○ Находят не всё, медленно, только heap
![Page 7: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/7.jpg)
AddressSanitizer
● Инструментирующий компилятор + библиотека
● Май 2011: первая версия○ Май 2012: входит в LLVM 3.1
● clang -faddress_sanitizer a.c
![Page 8: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/8.jpg)
Кстати: Clang, LLVM
● Компилятор C/C++ (opensource)● Независимые модули
○ C++ frontend○ Статический анализ, диагностика○ Оптимизатор○ Кодогенератор (x86, ARM, ...)
● Основной компилятор на MacOS, iOS● Активно используется в Google● Сопоставим с GCC по производительности
![Page 9: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/9.jpg)
AddressSanitizer
● Переполнение буфера○ Динамические объекты○ Стековые объекты ○ Глобальные объекты
● Использование после free()● Двойной free, пересечение параметров
memcpy, и др.
![Page 10: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/10.jpg)
Самое главное
● Среднее замедление: < 2x○ 3x-3.5x на очень больших бинарниках (кэш
инструкций)
● Клиентские приложения почти не замедляются
○ Chrome, Firefox
![Page 11: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/11.jpg)
Пример global-buffer-overflowint global_array[100] = {-1};int main(int argc, char **argv) { return global_array[argc + 100]; // BOOM}% clang++ -O1 -faddress-sanitizer example_GlobalOutOfBounds.cc ; ./a.out
==10538== ERROR: AddressSanitizer global-buffer-overflow READ of size 4 at 0x000000415354 thread T0 #0 0x402481 in main example_GlobalOutOfBounds.cc:3 #1 0x7f0a1c295c4d in __libc_start_main ??:0 #2 0x402379 in _start ??:0
0x000000415354 is located 4 bytes to the right of global variable 'global_array' (0x4151c0) of size 400
![Page 12: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/12.jpg)
Пример stack-buffer-overflowint main(int argc, char **argv) { int stack_array[100]; stack_array[1] = 0; return stack_array[argc + 100]; } // BOOM% clang++ -O1 -faddress-sanitizer example_StackOutOfBounds.cc; ./a.out
==10589== ERROR: AddressSanitizer stack-buffer-overflowREAD of size 4 at 0x7f5620d981b4 thread T0 #0 0x4024e8 in main example_StackOutOfBounds.cc:4 #1 0x7f5621db6c4d in __libc_start_main ??:0 #2 0x402349 in _start ??:0
Address 0x7f5620d981b4 is located at offset 436 in frame <main> of T0's stack: This frame has 1 object(s): [32, 432) 'stack_array'
![Page 13: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/13.jpg)
Пример heap-buffer-overflowint main(int argc, char **argv) { int *array = new int[100]; int res = array[argc + 100]; // BOOM delete [] array; return res; }% clang++ -O1 -faddress-sanitizer example_HeapOutOfBounds.cc; ./a.out==10565== ERROR: AddressSanitizer heap-buffer-overflowREAD of size 4 at 0x7fe4b0c76214 thread T0 #0 0x40246f in main example_HeapOutOfBounds.cc:3 #1 0x7fe4b0cb4c4d in __libc_start_main ??:0
0x7fe4b0c76214 is located 4 bytes to the right of 400-byte region [0x7fe..., 0x7fe...)allocated by thread T0 here: #0 0x402c36 in operator new[](unsigned long) _asan_rtl_ #1 0x402422 in main example_HeapOutOfBounds.cc:3
![Page 14: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/14.jpg)
Пример heap-use-after-freeint main(int argc, char **argv) { int *array = new int[100]; delete [] array; return array[argc]; } // BOOM% clang++ -O1 -faddress-sanitizer example_UseAfterFree.cc; ./a.out==30226== ERROR: AddressSanitizer heap-use-after-freeREAD of size 4 at 0x7faa07fce084 thread T0 #0 0x40433c in main example_UseAfterFree.cc:4
0x7faa07fce084 is located 4 bytes inside of 400-byte region [0x7fa...,x7fa...)freed by thread T0 here: #0 0x4058fd in operator delete[](void*) _asan_rtl_ #1 0x404303 in main example_UseAfterFree.cc:4
previously allocated by thread T0 here: #0 0x405579 in operator new[](unsigned long) _asan_rtl_ #1 0x4042f3 in main example_UseAfterFree.cc:2
![Page 15: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/15.jpg)
КАК ЖЕ ЭТО ВСЕ РАБОТАЕТ?
![Page 16: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/16.jpg)
Теневой (shadow) байт
0
7
6
5
4
3
2
1
-1
● У любых выравненных 8-и байт программы одно из 9-ти состояний:
○ N хороших байт○ (8 - N) плохих
Addressable
Unaddressable
Shadow
Хорошие
Плохие
Тень
![Page 17: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/17.jpg)
Отображение память тень
Виртуальные адреса:Тень = Память / 8
0xffffffff0x20000000
0x1fffffff0x04000000
0x03ffffff0x00000000
Память
Тень
Закрыто
![Page 18: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/18.jpg)
Или так:0xffffffff0x40000000
0x3fffffff0x28000000
0x27ffffff0x24000000
0x23ffffff0x20000000
0x1fffffff0x00000000
Тень = Память / 8 + 0x20000000
Память
Тень
Закрыто
![Page 19: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/19.jpg)
Инструментирование: 8 байт*a = ...
char *shadow = (a>>3)+Offset;if (*shadow)
ReportError(a);*a = ...
![Page 20: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/20.jpg)
Инструментирование: < 8 байт*a = ...
char *shadow = (a>>3)+Offset;if (*shadow && *shadow <= ((a&7)+N-1)) ReportError(a);*a = ...
![Page 21: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/21.jpg)
Немножко ассемблераshr $0x3,%rax # shift by 3 mov $0x100000000000,%rcx or %rax,%rcx # add offsetcmpb $0x0,(%rcx) # load shadowje 1f <foo+0x1f>ud2a # generate SIGILL*
movq $0x1234,(%rdi) # original store
* May use call instead of UD2
![Page 22: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/22.jpg)
Стековые переменныеvoid foo() { char a[328];
<------------- CODE ------------->
}
![Page 23: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/23.jpg)
Стековые переменныеvoid foo() { char rz1[32]; // 32-byte aligned char a[328]; char rz2[24]; char rz3[32]; int *shadow = (&rz1 >> 3) + kOffset; shadow[0] = 0xffffffff; // poison rz1 shadow[11] = 0xffffff00; // poison rz2 shadow[12] = 0xffffffff; // poison rz3 <------------- CODE -------------> shadow[0] = shadow[11] = shadow[12] = 0; }
![Page 24: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/24.jpg)
Глобальные переменные
int a;
struct { int original; char redzone[60];} a; // 32-aligned
![Page 25: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/25.jpg)
Библиотека
● Ининциализация теневой памяти● Замена malloc/free
○ Отравленные области вокруг malloc○ Отравление памяти при free, карантин○ Сохранение стеков malloc/free
● Перехват memset, strlen, и т.п. ● Вывод сообщений
![Page 26: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/26.jpg)
Трофеи
● Chromium (включая WebKit); в первые 10 месяцев○ heap-use-after-free: 201○ heap-buffer-overflow: 73○ global-buffer-overflow: 8○ stack-buffer-overflow: 7○ Google выплатил > $100k внешним исследователям
● Сотни ошибок в серверных приложениях Google● Firefox, FreeType, FFmpeg, WebRTC, libjpeg-turbo ● Perl, Vim, LLVM, GCC● MySQL
● А у Вас баги есть?
![Page 27: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/27.jpg)
Есть что улучшить
● Статический анализ○ Меньше проверок
● Инструментировать всё○ Библиотеки, Ассемблер
● Адаптировать для ядра
● Портировать на Windows○ Уже работает для С
![Page 28: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/28.jpg)
Короче...
● AddressSanitizer: ○ Находит много ошибок в коде на C/C++ ○ Очень быстрый○ Можно использовать при тестировании○ ... и в боевом режиме (осторожно)○ Работает на Linux, MacOS, Android○ Часть LLVM
○ clang.llvm.org/docs/AddressSanitizer.html
![Page 29: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/29.jpg)
А еще у нас есть...
● ThreadSanitizer○ Находит гонки (data races)○ С++ и Go
● MemorySanitizer○ Находит использование
неинициализированных данных (С++)
![Page 30: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/30.jpg)
Q&A
![Page 31: Address Sanitizer или как сделать программы на c/с++ надежнее и безопаснее (Константин Серебряный)](https://reader030.vdocuments.net/reader030/viewer/2022020716/5583b4c1d8b42ae2238b5400/html5/thumbnails/31.jpg)
Valgrind ASan MSan
Heap out-of-bounds YES YES NO
Stack out-of-bounds NO YES NO
Global out-of-bounds NO YES NO
Use-after-free YES YES NO
Use-after-return NO Sometimes NO
Uninitialized reads YES NO YES
CPU Overhead 10x-300x 1.5x-3x 3x
ASan/MSan vs Valgrind