Исследователи из команды Google Project Zero опубликовали метод эксплуатации уязвимости (CVE-2020-29661) в реализации ioctl-обработчика TIOCSPGRP из tty-подсистемы ядра Linux, а также детально рассмотрели механизмы защиты, которые могли бы блокировать подобные уязвимости.
Вызывающая проблему ошибка была устранена в ядре Linux ещё 3 декабря прошлого года. Проблема проявляется в ядрах до версии 5.9.13, но большинство дистрибутивов устранили проблему в обновлениях пакетов с ядром, предложенных ещё в прошлом году (Debian, RHEL, SUSE, Ubuntu, Fedora, Arch). Похожая уязвимость (CVE-2020-29660) одновременно была найдена в реализации ioctl-вызова TIOCGSID, но она также уже повсеместно устранена.
Проблема вызвана ошибкой при установке блокировок, приводящей к состоянию гонки в коде drivers/tty/tty_jobctrl.c, которое удалось использовать для создания условий обращения к памяти после её освобождения (use-after-free), эксплуатируемых из пространства пользователя через манипуляции с ioct-вызовом TIOCSPGRP. Рабочий эксплоит продемонстрирован для повышения привилегий в Debian 10 с ядром 4.19.0-13-amd64.
При этом в опубликованной статье акцент ставится не столько на технике создания рабочего эксплоита, столько на том, какие инструменты в ядре существуют для защиты от подобных уязвимостей. Вывод делается не утешительный, методы типа сегментирования памяти в куче и контроля за обращением к памяти после её освобождения не применяются на практике, так как приводят к снижению производительности, а защита на основе CFI (Control Flow Integrity), блокирующая эксплоиты на поздних стадиях атаки, требует доработки.
При рассмотрении того, что могло бы изменить ситуацию в долгосрочной перспективе, выделяется применение продвинутых статических анализаторов или использование языков, обеспечивающих безопасную работу с памятью, таких как Rust и диалекты языка Си с расширенными аннотациями (например, Checked C), на этапе сборки проверяющих состояние блокировок, объектов и указателей. Из методов защиты также упоминается активация режима panic_on_oops, перевод структур ядра в режим только для чтения и ограничение доступа к системным вызовами при помощи таких механизмов, как seccomp.