Стан гонки у збирачі сміття ядра Linux, здатний призвести до підвищення привілеїв

Янн Хорн (Jann Horn) з команди Google Project Zero, який свого часу виявив уразливості Spectre і Meltdown, опублікував техніку експлуатації вразливості (CVE-2021-4083) у збирачі сміття ядра Linux. Вразливість викликана станом гонки під час чищення файлових дескрипторів unix-сокетів і потенційно дозволяє локальному непривілейованому користувачеві домогтися виконання свого коду на рівні ядра.

Проблема цікава тим, що тимчасове вікно, протягом якого проявляється стан гонки, оцінювалося як занадто незначне для створення реальних експлоїтів, але автор дослідження показав, що навіть подібні вразливості, що спочатку скептично розглядаються, можуть стати джерелом реальних атак, якщо у творця експлоїту є необхідні навички і час. Янн Хорн показав, як за допомогою філігранних маніпуляцій можна звести стан гонки, що виникає при одночасному виклику функцій close() і fget(), до вразливості класу use-after-free, що повноцінно експлуатується, і домогтися звернення до вже звільненої структури даних усередині ядра.

Стан гонки виникає у процесі закриття файлового дескриптора за одночасного виклику функцій close() і fget(). Виклик close() може відпрацювати до виконання fget(), що введе збирач сміття в замішання оскільки відповідно до лічильником refcount у структури file не буде зовнішніх посилань, але вона залишиться прикріплена до файлового дескриптора, тобто. збирач сміття вважає, що має ексклюзивний доступ до структури, але фактично невеликий проміжок часу запис, що залишається в таблиці файлових дескрипторів, ще буде вказувати на структуру, що звільняється.

Для збільшення ймовірності попадання у стан гонки використано кілька трюків, які дозволили довести ймовірність успіху експлуатації до 30% при внесенні специфічних для конкретної оптимізації. Наприклад, для збільшення часу звернення до структури з файловими дескрипторами на кілька сотень наносекунд виконано витіснення даних з процесорного кешу через засмічення кешу активністю на іншому ядрі CPU, що дозволило домогтися віддачі структури пам'яті, а не швидкого кешу CPU.

Другою важливою особливістю стало використання збільшення часу стану гонки переривань, генерованих апаратним таймером. Підбирався такий момент, щоб обробник переривання спрацьовував під час виникнення стану гонки та на якийсь час переривав виконання коду. Для додаткового затягування повернення управління за допомогою epoll генерувалося близько 50 тисяч записів у waitqueue, що вимагають перебору в обробнику переривань.

Техніка експлуатації вразливості розкрита після 90-денного періоду нерозголошення. Проблема проявляється починаючи з ядра 2.6.32 та усунена на початку грудня. Виправлення увійшло до складу ядра 5.16, а також перенесено в LTS-гілки ядра та пакети з ядром, які постачаються в дистрибутивах. Примітно, що вразливість була виявлена ​​в ході аналізу схожої проблеми CVE-2021-0920, що виявляється у збирачі сміття під час обробки прапора MSG_PEEK.

Джерело: opennet.ru

Додати коментар або відгук