См. раздел «Понимание отчетов HWASan» для получения информации о том, как читать отчеты HWASan!
Аппаратная очистка адресов (HWASan) — это инструмент обнаружения ошибок памяти, аналогичный AddressSanitizer . HWASan использует значительно меньше оперативной памяти по сравнению с ASan, что делает его подходящим для очистки всей системы. HWASan доступен только на Android 10 и выше и только на оборудовании AArch64.
Хотя HWASan в первую очередь полезен для кода на C/C++, он также может помочь в отладке кода на Java, вызывающего сбои в C/C++, используемом для реализации интерфейсов Java. Он полезен тем, что обнаруживает ошибки памяти в момент их возникновения, указывая непосредственно на ответственный код.
По сравнению с классическим ASan, HWASan обладает следующими характеристиками:
- Аналогичные накладные расходы на ЦП (~в 2 раза)
- Аналогичные накладные расходы на размер кода (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%.
Требования
В последних версиях (4.14+) стандартного ядра Android поддержка HWASan реализована «из коробки». В ветках, относящихся к Android 10, поддержка HWASan отсутствует.
Поддержка HWASan в пользовательском пространстве доступна начиная с Android 11 .
Если вы работаете с другим ядром, HWASan требует, чтобы ядро Linux принимало помеченные указатели в аргументах системных вызовов. Поддержка этого реализована в следующих наборах патчей от разработчиков:
- arm64 помеченный адрес ABI
- arm64: удаление пользовательских указателей, передаваемых ядру.
- mm: Избегайте создания виртуальных псевдонимов адресов в функциях brk()/mmap()/mremap().
- arm64: Проверка помеченных адресов в функции access_ok(), вызываемой из потоков ядра.
Если вы используете собственный набор инструментов сборки, убедитесь, что он включает в себя все изменения до коммита LLVM c336557f .
Используйте HWASan
Для сборки всей платформы с использованием HWASan используйте следующие команды:
lunch aosp_walleye-userdebug # (or any other product)export SANITIZE_TARGET=hwaddressm -j
Для удобства вы можете добавить параметр SANITIZE_TARGET в определение продукта, аналогично aosp_coral_hwasan .
Для пользователей, знакомых с AddressSanitizer, значительная часть сложностей сборки устранена:
- Нет необходимости запускать команду make дважды.
- Пошаговая сборка работает без дополнительных настроек.
- Нет необходимости прошивать пользовательские данные.
Также сняты некоторые ограничения AddressSanitizer:
- Поддерживаются статические исполняемые файлы.
- Допустимо пропускать проверку на наличие ошибок для любой целевой библиотеки, кроме libc. В отличие от ASan, здесь нет требования, чтобы если библиотека проверена, то и любой исполняемый файл, который её связывает, также был проверен.
Переключение между образами HWASan и обычными образами с тем же (или более высоким) номером сборки можно осуществлять свободно. Сброс данных с устройства не требуется.
Чтобы пропустить проверку модуля, используйте LOCAL_NOSANITIZE := hwaddress (Android.mk) или sanitize: { hwaddress: false } (Android.bp).
Очистка отдельных целей
HWASan can be enabled per-target in a regular (unsanitized) build, as long as libc.so is also sanitized. Add hwaddress: true to the sanitize block in "libc_defaults" in bionic/libc/Android.bp. Then do the same in the target you are working on.
Обратите внимание, что очистка 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. Более подробную информацию см. в документации для разработчиков приложений .