Аппаратный адрессанитайзер

Информацию о том, как читать сбои HWASan, см. в разделе «Понимание отчетов HWASan» !

Аппаратный AddressSanitizer (HWASan) — это инструмент обнаружения ошибок памяти, аналогичный AddressSanitizer . HWASan использует гораздо меньше оперативной памяти по сравнению с ASan, что делает его подходящим для очистки всей системы. HWASan доступен только на Android 10 и выше и только на оборудовании AArch64.

Хотя HWASan полезен в первую очередь для кода C/C++, он также может помочь отладить код Java, вызывающий сбои в C/C++, используемом для реализации интерфейсов Java. Он полезен, поскольку обнаруживает ошибки памяти при их возникновении, указывая непосредственно на код, вызывающий сбои.

По сравнению с классическим ASan, HWASan имеет:

  • Аналогичная загрузка ЦП (~2x)
  • Аналогичные накладные расходы по размеру кода (40–50%)
  • Значительно меньшие накладные расходы на ОЗУ (10% – 35%)

HWASan обнаруживает тот же набор ошибок, что и ASan:

  • Переполнение/незаполнение буфера стека и кучи
  • Использование кучи после освобождения
  • Использование стека вне области действия
  • Двойной бесплатный/дикий бесплатный

Кроме того, HWASan обнаруживает использование стека после возврата.

HWASan (так же, как ASan) совместим с UBSan , оба могут быть включены на целевом устройстве одновременно.

Детали реализации и ограничения

HWASan основан на подходе тегирования памяти , при котором небольшое случайное значение тега связывается как с указателями, так и с диапазонами адресов памяти. Для корректного доступа к памяти теги указателя и памяти должны совпадать. HWASan использует функцию ARMv8 игнорирования верхнего байта (TBI), также называемую виртуальным тегированием адреса , для хранения тега указателя в старших битах адреса.

Более подробную информацию о дизайне HWASan можно прочитать на сайте документации Clang.

По своей сути HWASan не имеет красных зон ограниченного размера, как ASan, для обнаружения переполнений, или карантина ограниченной емкости, как ASan, для обнаружения использования памяти после освобождения. Поэтому HWASan может обнаружить ошибку независимо от размера переполнения или давности освобождения памяти. Это даёт HWASan значительное преимущество перед ASan.

Однако HWASan имеет ограниченное число возможных значений тегов (256), что означает, что вероятность пропуска любой ошибки во время одного выполнения программы составляет 0,4%.

Требования

Последние версии ядра Android (4.14+) поддерживают HWASan «из коробки». Ветки, специфичные для Android 10, не поддерживают HWASan.

Поддержка пользовательского пространства для HWASan доступна начиная с Android 11 .

Если вы работаете с другим ядром, HWASan требует, чтобы ядро ​​Linux принимало тегированные указатели в аргументах системных вызовов. Поддержка этой возможности была реализована в следующих пакетах исправлений:

Если вы создаете проект с использованием пользовательского набора инструментов, убедитесь, что он включает все до коммита LLVM c336557f .

Использовать HWASan

Для сборки всей платформы с использованием 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, изменять какие-либо файлы сборки не требуется.

Лучшая трассировка стека

HWASan использует быстрый раскручиватель на основе указателей кадров для записи трассировки стека для каждого события выделения и освобождения памяти в программе. Android по умолчанию включает указатели кадров в коде AArch64, поэтому на практике это отлично работает. Если вам нужно раскручивать стек через управляемый код, установите HWASAN_OPTIONS=fast_unwind_on_malloc=0 в окружении процесса. Обратите внимание, что для трассировки стека при неправильном доступе к памяти по умолчанию используется «медленный» раскручиватель; эта настройка влияет только на трассировки выделения и освобождения памяти. Этот параметр может сильно нагружать процессор, в зависимости от нагрузки.

Символизация

См. раздел «Символизация» в разделе «Понимание отчетов HWASan».

HWASan в приложениях

Подобно AddressSanitizer, HWASan не может анализировать код Java, но может обнаруживать ошибки в библиотеках JNI. До Android 14 запуск приложений HWASan на устройствах без HWASan не поддерживался.

На устройстве HWASan приложения можно проверить с помощью HWASan, собрав их код с SANITIZE_TARGET:=hwaddress в Make или -fsanitize=hwaddress в флагах компилятора. На устройстве без HWASan (под управлением Android 14 или более поздней версии) необходимо добавить параметр LD_HWASAN=1 в файл wrap.sh. Подробнее см. в документации разработчика приложений .