См. раздел «Понимание отчетов HWASan» для получения информации о том, как читать сбои HWASan!
Аппаратный AddressSanitizer (HWASan) — это инструмент обнаружения ошибок памяти, аналогичный AddressSanitizer . HWASan использует намного меньше оперативной памяти по сравнению с ASan, что делает его пригодным для очистки всей системы. HWAsan доступен только на Android 10 и выше и только на оборудовании AArch64.
Хотя HWASan в первую очередь полезен для кода C/C++, он также может помочь в отладке кода Java, вызывающего сбои в C/C++, используемом для реализации интерфейсов Java. Это полезно, потому что оно фиксирует ошибки памяти, когда они происходят, указывая вам непосредственно на ответственный код.
Вы можете загрузить готовые образы HWASan на поддерживаемые устройства Pixel с сайта ci.android.com ( подробные инструкции по настройке ).
По сравнению с классическим ASan, HWASan имеет:
- Аналогичная нагрузка на ЦП (~ 2 раза)
- Накладные расходы на аналогичный размер кода (40–50 %)
- Гораздо меньшие затраты на ОЗУ (10–35%)
HWASan обнаруживает тот же набор ошибок, что и ASan:
- Переполнение или опустошение буфера стека и кучи
- Куча использования после бесплатного
- Использование стека за пределами области действия
- Двойное бесплатное/дикое бесплатное
Кроме того, HWASan обнаруживает использование стека после возврата.
HWASan (так же, как ASan) совместим с UBSan , оба могут быть включены на цели одновременно.
Детали реализации и ограничения
HWASan основан на подходе к разметке памяти , при котором небольшое случайное значение тега связывается как с указателями, так и с диапазонами адресов памяти. Чтобы доступ к памяти был действительным, указатель и теги памяти должны совпадать. HWASan использует функцию игнорирования верхнего байта (TBI) ARMv8, также называемую маркировкой виртуального адреса , для хранения тега указателя в старших битах адреса.
Подробнее о дизайне HWASan можно прочитать на сайте документации Clang.
По замыслу HWASan не имеет красных зон ASan ограниченного размера для обнаружения переполнения или карантина ограниченной емкости ASan для обнаружения использования после освобождения. По этой причине HWASan может обнаружить ошибку независимо от того, насколько велико переполнение или как давно была освобождена память. Это дает HWASan большое преимущество перед ASan.
Однако HWASan имеет ограниченное количество возможных значений тегов (256), а это значит, что вероятность пропустить какую-либо ошибку за одно выполнение программы составляет 0,4%.
Требования
Последние версии (4.14+) общего ядра Android поддерживают HWASan «из коробки». Конкретные ветки Android 10 не поддерживают HWASan.
Поддержка HWASan в пользовательском пространстве доступна начиная с Android 11 .
Если вы работаете с другим ядром, HWASan требует, чтобы ядро Linux принимало тегированные указатели в аргументах системного вызова. Поддержка этого была реализована в следующих наборах обновлений:
- Arm64 тегированный адрес ABI
- Arm64: отменить теги пользовательских указателей, передаваемых в ядро
- мм: избегайте создания псевдонимов виртуальных адресов в brk()/mmap()/mremap().
- Arm64: проверка помеченных адресов в методе access_ok(), вызываемом из потоков ядра.
Если вы создаете собственный набор инструментов, убедитесь, что он включает в себя все, вплоть до фиксации LLVM c336557f .
Используйте ХВАСан
Используйте следующие команды для сборки всей платформы с использованием HWASan:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
Для удобства вы можете добавить параметр SANITIZE_TARGET в определение продукта, аналогично aosp_coral_hwasan .
Для пользователей, знакомых с AddressSanitizer, большая часть сложностей сборки исчезла:
- Нет необходимости запускать make дважды.
- Инкрементные сборки работают «из коробки».
- Нет необходимости прошивать пользовательские данные.
Некоторые ограничения AddressSanitizer также исчезли:
- Поддерживаются статические исполняемые файлы.
- Можно пропустить очистку любой цели, кроме libc. В отличие от ASan, нет требования, согласно которому, если библиотека очищена, то и любой исполняемый файл, который ссылается на нее, тоже должен быть очищен.
Переключение между HWASan и обычными образами с тем же (или более высоким) номером сборки можно осуществлять свободно. Протирать устройство не требуется.
Чтобы пропустить очистку модуля, используйте LOCAL_NOSANITIZE := hwaddress
(Android.mk) или sanitize: { hwaddress: false }
(Android.bp).
Дезинфекция отдельных целей
HWASan можно включить для каждой цели в обычной (неочищенной) сборке, если libc.so
также очищен. Добавьте hwaddress: true
в блок sanitize в "libc_defaults"
в bionic/libc/Android.bp. Затем сделайте то же самое с целью, над которой вы работаете.
Обратите внимание, что очистка libc позволяет помечать выделение кучи памяти в масштабе всей системы, а также проверять теги для операций с памятью внутри libc.so
. Это может выявить ошибки даже в двоичных файлах, для которых HWASan не был включен, если плохой доступ к памяти находится в libc.so
(например, pthread_mutex_unlock()
в мьютексе, обработанном delete()
).
Нет необходимости изменять какие-либо файлы сборки, если вся платформа собрана с использованием HWASan.
Флешстанция
В целях разработки вы можете прошить сборку AOSP с поддержкой HWASan на устройство Pixel с разблокированным загрузчиком с помощью Flashstation . Выберите цель _hwasan, например aosp_flame_hwasan-userdebug. Дополнительные сведения см. в документации NDK для HWASan для разработчиков приложений.
Улучшенная трассировка стека
HWASan использует быстрый механизм размотки на основе указателей кадров для записи трассировки стека для каждого события выделения и освобождения памяти в программе. Android по умолчанию включает указатели кадров в коде AArch64, поэтому на практике это отлично работает. Если вам нужно развернуть управляемый код, установите HWASAN_OPTIONS=fast_unwind_on_malloc=0
в среде процесса. Обратите внимание, что трассировки стека неправильного доступа к памяти по умолчанию используют «медленный» механизм размотки; этот параметр влияет только на трассировки выделения и освобождения. Этот вариант может сильно нагружать процессор, в зависимости от нагрузки.
Символизация
См. раздел «Обозначение символов» в разделе «Понимание отчетов HWASan».
ХВАСан в приложениях
Подобно AddressSanitizer, HWASan не может просматривать код Java, но может обнаруживать ошибки в библиотеках JNI. До версии Android 14 запуск приложений HWASan на устройствах, отличных от HWASan, не поддерживался.
На устройстве HWASan приложения можно проверить с помощью HWASan, создав их код с помощью SANITIZE_TARGET:=hwaddress
в Make или -fsanitize=hwaddress
во флагах компилятора. На устройстве, не поддерживающем HWASan (под управлением Android 14 или более поздней версии), необходимо добавить параметр файла Wrap.sh LD_HWASAN=1
. Дополнительные сведения см. в документации разработчика приложения .