21.05.2022

Уязвимость в VFS ядра Linux, позволяющая повысить свои привилегии

В API Filesystem Context, предоставляемым ядром Linux, выявлена уязвимость (CVE-2022-0185), позволяющая локальному пользователю добиться получения прав root в системе. Выявивший проблему исследователь опубликовал демонстрацию работы эксплоита, позволяющего выполнить код с правами root в Ubuntu 20.04 в конфигурации по умолчанию. Код эксплоита планируется разместить на GitHub в течение недели, после того как дистрибутивы выпустят обновление с исправлением уязвимости.

Уязвимость присутствует в функции legacy_parse_param() в VFS и вызвана отсутствие должной проверки максимального размера параметров, предоставляемых в файловых системах, не поддерживающих API Filesystem Context. При передаче слишком большого параметра можно вызвать переполнение целочисленной переменной, используемой для расчета размера записываемых данных — в коде имеется проверка выхода за границу буфера «if (len > PAGE_SIZE — 2 — size)», которая не срабатывает, если значение size больше 4094 из-за целочисленного переполнения через нижнюю границу (integer underflow, при приведении 4096 — 2 — 4095 к unsigned int получится 2147483648).

Указанная ошибка позволяет при обращении к специально оформленному образу ФС вызвать переполнение буфера и перезаписать данные ядра, следующие за выделенной областью памяти. Для эксплуатации уязвимости требуется наличие прав CAP_SYS_ADMIN, т.е. полномочий администратора. Проблема в том, что подобные полномочия непривилегированный пользователь может получить в изолированном контейнере, если в системе включена поддержка пространств имён идентификаторов пользователей (user namespaces). Например, user namespaces по умолчанию включён в Ubuntu и Fedora, но не активирован в Debian и RHEL (если не используются платформы контейнерной изоляции).

Проблема проявляется начиная с ядра Linux 5.1 и устранена во вчерашних обновлениях 5.16.2, 5.15.16, 5.10.93, 5.4.173. Обновления пакетов с устранением уязвимости уже выпущены для RHEL, Debian, Fedora, Ubuntu. Исправление пока недоступно в Arch Linux, Gentoo, SUSE и openSUSE. В качестве обходного пути защиты для систем, не использующих контейнерную изоляцию можно выставить в 0 значение sysctl «user.max_user_namespaces»:

 echo "user.max_user_namespaces=0" > /etc/sysctl.d/userns.conf # sysctl -p /etc/sysctl.d/userns.conf

Источник.