Что такое «теневые байты» в AddressSanitizer и как их интерпретировать?
Со страницы AddressSanitizerAlgorithm на GitHub (на которую также есть ссылка Страница LLVM AddressSanitizer ):
Виртуальное адресное пространство разделено на 2 непересекающихся класса:
- Основная память приложения (Mem): эта память используется обычным кодом приложения.
- Теневая память (Shadow): эта память содержит теневые значения (или метаданные). Между тенью и основной памятью приложения есть соответствие. Отравление байта в основной памяти означает запись некоторого специального значения в соответствующую теневую память.
Итак, «теневые байты» - это метаданные, описывающие состояние адресуемой памяти вашей программы.
Если мы посмотрим на вывод asan:
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
Freed heap region: fd
...
поэтому, если адресуема целая 8-байтовая строка, байт тени, который отслеживает (или затеняет), должен иметь значение 00
. Если он частично адресуемый, теневой байт будет 01..07
, что предположительно является количеством адресуемых байтов в строке.
Значение, на которое указывает шестнадцатеричный дамп, - fa
, или «Куча left redzone "- предположительно, это своего рода защитная область вокруг выделения кучи для обнаружения переполнения.
Из той же ссылки:
Библиотека времени выполнения заменяет mallo c и бесплатные функции. Память вокруг mallo c -ed регионов (красные зоны) отравлена
В более широком смысле, это описание (в адресах программ)
0x602000000005 is located 11 bytes to the left of 5-byte region
[0x602000000010,0x602000000015)
соответствует показанной карте теней:
=>0x0c047fff8000:[fa]fa 05 fa ...
Предполагая естественное выравнивание,
- байт тени
0x0c047fff8000
описывает (или, опять же, тени) программные адреса 0x602000000000..0x602000000007
, который включает адрес, к которому вы обращались - следующий байт тени в
0x0c047fff8001
описывает адреса программы 0x602000000008..0x60200000000F
- оба из них имеют значение
fa
, что означает «красная зона слева от кучи» - следующий теневой байт в
0x0c047fff8002
описывает программные адреса 0x602000000010..0x602000000007
и имеет значение 05
, что означает, что 5 байтов адресуются. Это 5 байтов вашей кучи.
Все это согласуется с частью ошибки, которую вы сделали поняли.
-
Тем не менее, я все еще сбит с толку, потому что легенда гласит, что fa означает «куча левой красной зоны», но она появляется справа от 05
и для слева от него. Почему нет "кучи правильных красных зон?"
Я не знаю, что на самом деле означает направленность. Обычно кучи изначально растут в одном направлении (традиционно вверх по мере роста стека вниз), но могут быть фрагментированы, освобождены, объединены и перераспределены. Является ли промежуток между двумя выделениями "справа" или "слева", или и тем, и другим, или ни одного? Все, что нам нужно знать, это то, что это отравленная область кучи, которая никогда не выделялась пользователю.
Может быть, это должна быть просто «красная зона кучи», если нет ориентации, соответствующей левому / среднему / правому стеку значения.
В этом примере ASAN сообщает, что программа вышла на 11 байт из 5-байтовой области, но показывает гораздо большую скорость, чем это.
каждый fa
представляет восемь байтов, как гласит легенда. Таким образом, если вы обращались к чему-либо от девяти до пятнадцати байтов до выделения (по модулю арифметики c ошибок), это было бы в том же теневом байте. Если бы вы обращались к одному-восьми байтам раньше, он отобразился бы в следующем байте тени (прямо перед 05
).
Остальные fa
s представляют собой просто карту окрестностей, которая в данном случае не кажется полезной, но может быть полезной в других.
Существует ли соответствующая подробная документация, которая на самом деле объясняет, что означают эти термины «красная зона слева от кучи», «красная зона в середине стека», «глобальная красная зона» и т. Д.?
Понятия не имею . Они кажутся вполне естественными из варианта использования - вы попали в красную зону = вы получили доступ к адресу, который вам не нужен. Вы всегда можете просто прочитать код, например. asan_internal.h
определяет значение kAsanHeapLeftRedzoneMagic
, а asan_allocator.cpp
отравляет им теневые байты.
Что такое «Теневой байт / адрес» в этом контексте?
Просто для полноты, теневой байт - это байт, который затеняет группу из восьми обычно доступных программных байтов и отслеживает некоторую информацию о них полезны для дезинфицирующего средства.
Теневой адрес - это адрес теневого байта.