В OpenBSD 7.9 связали старое переполнение счётчика с root-эксплойтом

Исследовательская компания Calif опубликовала локальный эксплойт повышения привилегий до root в OpenBSD 7.9. Цепочка объединяет переполнение целочисленного счётчика в функции shmat(4) и ошибку use-after-free в ядре, обходя KARL, а также аппаратные механизмы SMAP и SMEP.
Первый дефект исправлен в errata 018, выпущенном 14 сентября как исправление надёжности. Второй устранён в errata 026 от 30 сентября как исправление безопасности. Оба обновления доступны через syspatch для всех архитектур; исправление переполнения также получили системы OpenBSD 7.8.
Счётчик из исходного BSD
Точкой входа в цепочку стал счётчик подключений разделяемой памяти shm_nattch. В исходных кодах BSD с 1988 года он определён как знаковый 16-битный тип short, поэтому максимальное значение составляет 32 767. В OpenBSD этот тип не был расширен.
Демонстрационный код отображает 127 сегментов разделяемой памяти и создаёт 259 процессов. В результате счётчик превышает максимум и после переполнения становится равен −32 643. Условие гонки затем задействует use-after-free: повреждённый счётчик ссылок приводит к освобождению памяти, которую продолжают использовать другие процессы.
Как обходятся защиты ядра
Дальнейшая часть цепочки использует отдельную запись за границы буфера для перезаписи счётчиков участия в multicast-группах ядра. После закрытия затронутого сокета последующие декременты меняют записи таблиц страниц и переводят пользовательское отображение памяти в режим, доступный супервизору. Это позволяет обойти SMAP и SMEP.
После этого эксплойт перезаписывает указатель на функцию по предсказуемому адресу ядра и запускает собственный код. Andrew Griffiths из Calif отметил, что KARL перелинковывает бинарный файл ядра и рандомизирует адреса функций и данных, однако распределители памяти ядра остаются детерминированными.
По описанию Calif, загрузочный и best-fit распределители не рандомизируют базовый адрес. Поэтому структуры, созданные на ранней стадии загрузки, включая указатели обработчиков сетевых интерфейсов lo0 и enc0, располагаются по одинаковым адресам после перезагрузок на одном и том же оборудовании. Для работы демонстрации не требуется отдельная уязвимость раскрытия адресов.
Что важно администраторам
На момент публикации CVE для обоих дефектов не назначены, а свидетельств их использования в атаках нет. Calif предложила дополнительные меры усиления: безопасное удаление элементов из связанных списков ядра, рандомизацию самоссылочного отображения таблиц страниц, рандомизацию распределителей памяти ядра и проверки границ, реализуемые компилятором.
Для организаций практический вывод состоит в проверке установки errata 018 и 026 через syspatch на системах OpenBSD. Этот случай показывает, что метка «надёжность» не исключает последствий для безопасности, если дефект можно объединить с другой ошибкой ядра.

