Технічні відомості про цілісність потоку керування
«Наявність величезної кількості покажчиків на функції в ядрі сприяє популярності цього шаблону атаки. Навіть якщо зловмисники не можуть впровадити власний виконуваний код, довільні частини існуючого коду ядра можуть бути виконані, щоб завершити їх подвиг.
LLVMCFI намагається пом'якшити ці атаки, обмежуючи дійсні цілі виклику та викликаючи паніку ядра при виявленні порушення CFI. Перевірка додається перед кожним непрямим розгалуженням, щоб підтвердити, що цільова адреса вказує на дійсну функцію з правильним підписом. Це запобігає переходу непрямої гілки до довільного розташування коду та навіть обмежує функції, які можна викликати. Зловмисник все одно зможе змінити покажчик функції, якщо помилка дозволяє доступ. Але CFI LLVM обмежує 55% непрямих дзвінків до щонайбільше 5 можливих цілей і 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, Сканда також любить стежити за останніми тенденціями розвитку у світі одноплатних комп’ютерів.