Уязвимость в cgroups v1, позволяющая выйти из изолированного контейнера

Раскрыты детали уязвимости (CVE-2022-0492) в реализации механизма ограничения ресурсов cgroups v1 в ядре Linux, которая может использоваться для выхода из изолированных контейнеров. Проблема проявляется начиная с ядра Linux 2.6.24 и устранена в выпусках ядра 5.16.12, 5.15.26, 5.10.97, 5.4.177, 4.19.229, 4.14.266 и 4.9.301. Проследить за публикаций обновления пакетов в дистрибутивах можно на данных страницах: Debian, SUSE, Ubuntu, RHEL, Fedora, Gentoo, Arch Linux.

Уязвимость вызвана логической ошибкой в обработчике файлов release_agent, из-за которой не выполнялись должные проверки при запуске обработчика с полным набором полномочий. Файл release_agent используется для определения программы, выполняемой ядром при завершении процесса в cgroup. Данная программа запускается с правами root и со всеми “capabilities” в корневом пространстве имён.
Подразумевалось, что доступ к настройке release_agent имеет только администратор, но на деле проверки ограничивались предоставлением доступа пользователю root, что не исключало изменение настройки из контейнера или пользователем root без прав администратора (CAP_SYS_ADMIN).

Раньше подобная особенность не была бы воспринята как уязвимость, но ситуация изменилась с появлением пространств имён идентификаторов пользователей (user namespaces), которые позволяют создавать в контейнерах отдельных пользователей root, не пересекающихся с пользователем root основного окружения. Соответственно, для атаки достаточно в контейнере, имеющем своего пользователя root в отдельном пространстве идентификаторов пользователей, подключить свой обработчик release_agent, который после завершения процесса будет выполнен с полными привилегиями основного окружения.

По умолчанию cgroupfs монтируется в контейнере в режиме только для чтения, но нет проблем перемонтировать данную псевдофс в режиме записи при наличии прав CAP_SYS_ADMIN или через создание при помощи системного вызова unshare вложенного контейнера с отдельным user namespace, в котором для созданного контейнера доступны права CAP_SYS_ADMIN.


Атака может быть совершена при наличии root-полномочий в изолированном контейнере или при запуске контейнера без флага no_new_privs, запрещающего получение дополнительных привилегий. В системе должна быть включена поддержка user namespaces (по умолчанию включена в Ubuntu и Fedora, но не активирована в Debian и RHEL) и присутствовать доступ к корневому cgroup v1 (например Docker запускает контейнеры в корневом RDMA cgroup). Атака также возможна при наличии привилегий CAP_SYS_ADMIN, в этом случае поддержка user namespaces и доступ к корневой иерархии cgroup v1 не требуется.

Кроме выхода из изолированного контейнера уязвимость также позволяет процессам, запущенным пользователем root без “capabilities” или любым пользователем с правами CAP_DAC_OVERRIDE (для атаки требуется доступ к файлу /sys/fs/cgroup/*/release_agent, который принадлежит root), получить доступ ко всем системным “capabilities”.

Отмечается, что уязвимость не может быть эксплуатирована при применении механизмов защиты Seccomp, AppArmor или SELinux для дополнительной изоляции контейнеров, так как Seccomp блокирует обращение к системному вызову unshare(), а AppArmor и SELinux не позволяют примонтировать cgroupfs в режиме записи.

Release. Ссылка here.