Исследователи из команды Google Project Zero разработали метод эксплуатации уязвимостей в ядре Linux, вызванных разыменованием указателей NULL. До сих пор проблемам в ядре, связанным с разыменованием указателей NULL, не уделялось должного внимания, так как доведение таких проблем до атак, приводящих к повышению привилегий или выполнению своего кода, считалось нереалистичным (непривилегированным процессам запрещён маппинг в нижней области адресного пространства). Как правило подобные ошибки приводят к генерации ядром oops-предупреждений, после которых проблемные задачи завершаются и состояние восстанавливается без необходимости остановки работы системы.
Новый метод атаки основывается на особенности обработки состояний “oops”, в результате которых можно добиться увеличения значения счётчика ссылок (refcount), что в свою очередь может привести к переполнению счётчика и освобождению памяти, связанной с refcount. В этом случае эксплуатация сводится к манипуляциям, типичным для атак use-after-free (возникает ситуация, когда у объекта счётчик ссылок становится равен нулю, память освобождается, но фактически остаются рабочие ссылки, указывающие на освобождённую память).
Разыменование указателя NULL в данном случае используется как способ управляемой генерации состояния “oops”. Проблема состоит в том, что для достижения переполнения 32-разрядного refcount требуется примерно 232 вызовов состояния “oops”. С практической стороны для проведения атаки при помощи предложенного эксплоита требуется около 8 дней непрерывной генерации состояний “oops”. В случае успеха эксплоит позволяет добиться выполнения своего кода на уровне ядра.
Используемое в эксплоите разыменование указателя NULL устранено в октябре, но так как выявление похожих проблем не является редкостью и они ранее трактовались как ошибки, а не уязвимости, разработчики добавят в ядро Linux общую защиту для предотвращения атак, манипулирующих генерацией состояний “oops”. В частности, в состав ядра 6.2 приняты изменения, ограничивающие максимальное число “oops”. После достижения лимита, который по умолчанию выставлен в 10 тысяч oops (при желании можно изменить через параметр oops_limit), ядро будет инициировать переход в состояние “panic” с последующей перезагрузкой, что не позволит добиться необходимого для обнуления refcount числа итераций. Ограничение также планируют перенести в ранее выпущенные, но ещё поддерживаемые, ветки ядра, а также в пакеты с ядром популярных дистрибутивов.