В Netfilter, подсистеме ядра Linux, используемой для фильтрации и модификации сетевых пакетов, выявлена уязвимость (CVE-2021-22555), позволяющая локальному пользователю получить привилегии root в системе, в том числе находясь в изолированном контейнере. Для тестирования подготовлен рабочий прототип эксплоита, обходящий механизмы защиты KASLR, SMAP и SMEP. Исследователь, выявивший уязвимость, получил от Google вознаграждение, размером 20 тысяч долларов, за выявление метода обхода изоляции контейнеров Kubernetes в кластере kCTF.
Проблема проявляется начиная с ядра 2.6.19, выпущенного 15 лет назад, и вызвана ошибкой в обработчиках IPT_SO_SET_REPLACE и IP6T_SO_SET_REPLACE, приводящей к переполнению буфера при отправке специально оформленных параметров через вызов setsockopt в режиме compat. В обычных условиях вызов compat_setsockopt() может выполнить только пользователь root, но необходимые для совершения атаки полномочия также могут быть получены непривилегированным пользователем в системах с включённой поддержкой пространств имён идентификаторов пользователей (user namespaces).
Пользователь может создать контейнер с отдельным пользователем root и из него эксплуатировать уязвимость. Например, “user namespaces” по умолчанию включён в Ubuntu и Fedora, но не активирован в Debian и RHEL. Патч с исправлением уязвимости принят в состав ядра Linux 13 апреля. Обновления пакетов уже сформированы проектами Debian, Arch Linux и Fedora. В Ubuntu, RHEL и SUSE обновления на стадии подготовки.
Проблема возникает в функции xt_compat_target_from_user() из-за некорректного расчёта размера памяти при сохранении структур ядра после преобразования из 32- в 64-разрядное представление. Ошибка позволяет записать четыре нулевых байта в любую позицию за границей выделенного буфера, ограниченную смещением 0x4C. Указанной возможности оказалось достаточно для создания эксплоита, позволяющего добиться получения прав root – через очистку указателя m_list->next в структуре msg_msg создавались условия для обращения к данным после освобождения памяти (use-after-free), что затем использовалось для получения сведений об адресах и изменения других структур через манипуляцию с системным вызовом msgsnd().