Технические подробности о целостности потока управления
«Наличие огромного количества указателей на функции в ядре способствует популярности этого шаблона атаки. Даже если злоумышленники не могут внедрить собственный исполняемый код, для завершения эксплойта могут быть выполнены произвольные части существующего кода ядра.
ЛЛВМCFI пытается смягчить эти атаки, ограничивая допустимые цели вызовов и вызывая панику ядра при обнаружении нарушения CFI. Перед каждой косвенной ветвью добавляется проверка, подтверждающая, что целевой адрес указывает на действительную функцию с правильной сигнатурой. Это предотвращает переход косвенной ветки к произвольному месту кода и даже ограничивает количество вызываемых функций. Злоумышленник по-прежнему сможет изменить указатель функции, если ошибка разрешает доступ. Но CFI LLVM ограничивает 55% непрямых вызовов не более чем пятью возможными целями и 80% не более чем 20 целями. Чтобы определить все допустимые цели вызова для каждой косвенной ветки, компилятору необходимо просмотреть весь код ядра одновременно.
Использование LTO (Оптимизация времени соединения) делает это возможным. CFI LLVM требует использования LTO, при котором компилятор создает биткод, специфичный для LLVM, для всех C. единицы компиляции, а компоновщик, поддерживающий LTO, использует серверную часть LLVM для объединения битового кода и компиляции его в родной код.
В дополнение к разрешению использования CFI, LTO обеспечивает лучшую производительность во время выполнения за счет анализа всей программы и межмодульной оптимизации.
ThinLTO почти догнал улучшение производительности LTO. В режиме ThinLTO, как и в обычном LTO, Кланг выдает биткод LLVM после фазы компиляции. Бит-код ThinLTO дополнен компактным описанием модуля. На этапе связывания считываются только сводные данные и объединяются в объединенный сводный индекс, который включает в себя индекс местоположений функций для последующего импорта межмодульных функций. После этого выполняется быстрый и эффективный анализ всей программы по объединенному сводному индексу. ThinLTO позволяет выполнять многопоточный процесс компоновки, что приводит к сокращению времени компиляции.
Поскольку CFI прерывает выполнение программы при обнаружении определенных классов ошибок, он также классифицируется как инструмент поиска ошибок, как упоминалось ранее, при использовании в разрешительном режиме. Разрешающий CFI будет отображать нарушения CFI в журнале ядра, не вызывая паники ядра. Ядра ядра 4.9 (устройства поколения Pixel 3) и 4.14 (устройства поколения Pixel 4) имели несколько типов функций. несоответствия, приводящие к нарушениям CFI, которые были устранены Google в наборах исправлений, доступных в ядре/общем репо.
Однако из-за особенностей экосистемы Android эти несоответствия, скорее всего, будут обнаружены также в коде производителя SoC (в данном случае Qualcomm) или OEM (OnePlus). Несколько нарушений CFI в коде Qualcomm, отличных от ядра 4.19, были исправлены в ядре Kirisakura для OnePlus 8 Pro (пример: 1, 2, 3).
Запуск ядра в разрешительном CFI также выявил нарушения CFI в коде, связанном с драйверами OnePlus (соответствующие коммиты можно найти здесь и здесь). Ядро Kirisakura для OnePlus 8 Pro работает с применением CFI, защищая пользователей от такого рода атак с повторным использованием кода».
читать далее
Энтузиаст DIY (т. е. собиратель старых деталей ПК). Заядлый пользователь Android со времен Eclair, Сканда также любит следить за последними тенденциями развития в мире одноплатных компьютеров.