22 апреля 2026 года Linux CNA опубликовал CVE-2026-31431 — уязвимость ядра Linux в algif_aead, AEAD-компоненте интерфейса криптосокетов AF_ALG. Команда Xint назвала ошибку Copy Fail и показала, как можно изменить байты в кэше страниц (page cache) файла, открытого только на чтение, не «пачкая» его на диске.
Это описание точно с точки зрения Linux, но за ним остаётся без ответа один вопрос, актуальный для Kubernetes:
Если под запущен не от root, у него сброшены все Linux-возможности (capabilities), используется seccomp-профиль RuntimeDefault, и он допущен по Pod Security Standards уровня Restricted — может ли он всё равно достичь кодового пути ядра, задействованного в Copy Fail?
Мы проверили это на двух реальных Kubernetes-кластерах:
-
Talos
v1.12.2, ядро6.18.5-talos, containerd2.1.6 -
EKS на Amazon Linux 2023.11, ядро
6.12.79-101.147.amzn2023.x86_64, containerd2.2.1
Короткий ответ: да. В обоих кластерах под, не имеющий прав root и допущенный по PSS Restricted, мог создать AF_ALG-сокет и выполнить bind к нужному AEAD-алгоритму. В обоих кластерах такой под мог изменить закэшированные байты файла, встроенного в слой образа специально созданного контейнера, а другой под из того же образа на том же узле наблюдал изменённые байты. RuntimeDefault этот путь не блокировал. Блокировал его только пользовательский профиль Localhost, запрещающий socket(AF_ALG, …).
Мы также провели контролируемые лабораторные тесты на цепочку получения root в обоих конфигурациях — Talos/containerd и EKS/containerd — с помощью специально созданного setuid-помощника внутри тестового образа. В этих тестах удавалось получить euid 0 внутри контейнера, если pod допускал эскалацию привилегий (privilege escalation). Pod-писатель, работающий под PSS Restricted, мог мутировать общие байты в кэше слоя образа, однако allowPrivilegeEscalation: false не позволял этому поду воспользоваться setuid-передачей самому.
Эта статья намеренно ограничена по охвату. Мы не публикуем эксплойт-код. Мы не атаковали setuid-бинарники хоста, исполняемые файлы хоста, файлы, управляемые пакетным менеджером, или файлы production-приложений. В setuid-тесте использовался только специально созданный помощник внутри одноразового лабораторного образа.
Обновление от 3 мая 2026 года: Мы повторно проверили основные трекеры и бюллетени вендоров. Результат для Kubernetes, описанный ниже, не изменился, но ситуация с покрытием у вендоров продолжает развиваться. SUSE сообщает, что обновления выпущены для всех поддерживаемых дистрибутивов SUSE Linux Enterprise и openSUSE Leap, а обновления образов для публичных облаков ещё в процессе. Трекер Amazon Linux по-прежнему показывает статус «ожидает исправления» для потоков ядра Amazon Linux 2 и Amazon Linux 2023. Публичный бюллетень Red Hat остаётся в статусах Important и Ongoing, а публичные материалы Red Hat по OpenShift указывают, что затронуты OpenShift Container Platform 4 и управляемые кластеры ROSA Classic/OpenShift Dedicated, работа по устранению продолжается. NVD также продолжала добавлять ссылки к записи CVE 3 мая. Используйте пакетные/advisory-каналы вендоров как актуальный источник истины.
Обновление от 2 мая 2026 года: CISA добавила CVE-2026-31431 в каталог Known Exploited Vulnerabilities 1 мая на основании свидетельств активной эксплуатации, установив срок устранения для FCEB-организаций — 15 мая 2026 года. Microsoft Defender сообщает, что наблюдаемая эксплуатация пока ограничена и носит преимущественно характер proof-of-concept/тестовой активности, однако эти предварительные тесты могут привести к росту числа попыток эксплуатации.
Ситуация у вендоров также продолжает меняться. AlmaLinux перенесла исправленные ядра из тестовых репозиториев в production; Debian теперь перечисляет исправленные пакеты ядра для bullseye-security, bookworm-security, trixie-security, forky и sid; CloudLinux/KernelCare расширила покрытие ядер и livepatch-патчей по состоянию на 2 мая. Продолжайте использовать advisory-каналы OS-вендоров как источник истины — одна лишь версия ядра может не учитывать бэкпорты и состояние livepatch. Это меняет степень срочности, но не результат для Kubernetes: на проверенных нами затронутых узлах PSS Restricted и RuntimeDefault не устраняли доступность AF_ALG.
Обновление от 1 мая 2026 года: После публикации запись CVE была обновлена дополнительными порогами исправленных версий стабильных ядер, а вендоры опубликовали дополнительные руководства по митигации и патчам. Debian указал исправление для trixie-security в версии 6.12.85-1; Ubuntu выпустил митигацию через kmod, отключающую algif_aead до выхода патчей ядра; AlmaLinux опубликовала исправленные ядра в тестовых репозиториях; CloudLinux отметил, что митигации через modprobe.d и rmmod не работают на системах семейства RHEL, когда algif_aead встроен в ядро; Sidero рекомендовала использовать Talos 1.12.7+ или 1.13.0+. Основной результат для Kubernetes остаётся неизменным: на проверенных нами затронутых узлах PSS Restricted и RuntimeDefault не устраняли доступность AF_ALG.
Ключевые выводы
-
PSS Restricted не блокировал соответствующий путь AF_ALG ни в одном из протестированных кластеров. Seccomp-профиль
RuntimeDefaultне блокировал AF_ALG ни на Talos/containerd, ни на EKS/containerd. -
Пользовательский профиль
Localhost, запрещающийsocket(AF_ALG, …), заблокировал этот путь в обоих кластерах. -
Видимость изменений кэша страниц между подами воспроизводилась на одном узле, включая случай с общим слоем образа контейнера.
-
В контролируемых лабораторных тестах на Talos и EKS удавалось получить euid 0 внутри контейнера, когда pod с
allowPrivilegeEscalation: trueвыполнял мутированный специально созданный setuid-помощник из общего слоя образа. -
PSS Restricted не остановил мутацию кэша страниц, однако
allowPrivilegeEscalation: falseзаблокировал путь через setuid-помощника внутри ограниченного пода. -
Байты на диске оставались нетронутыми в лабораторном тесте с hostPath, тогда как обычные кэшированные чтения возвращали изменённые байты.
Что такое Copy Fail
Официальное название CVE — crypto: algif_aead - Revert to operating out-of-place. Запись CVE содержит оценку CVSS 3.1 — 7.8 High с вектором AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H. Диапазон затронутых версий в upstream начинается с коммита 72548b093ee38a6d4f2a19e6ef1948ae05c181f7. По состоянию на 3 мая 2026 года в записи CVE/NVD перечислены исправленные пороговые версии стабильных ядер: 5.10.254, 5.15.204, 6.1.170, 6.6.137, 6.12.85, 6.18.22, 6.19.12 и 7.0.
Разбор от Xint объясняет примитив: непривилегированный локальный процесс может использовать AF_ALG AEAD-операции и splice() таким образом, что ядро выполняет запись в страницы кэша страниц, подкреплённые файлом. Эти страницы используются обычными операциями чтения и путями исполнения, но файл при этом не помечается изменённым на диске в обычном смысле.
Это различие важно в контексте Kubernetes, потому что контейнеры на одном узле разделяют ядро хоста и кэш страниц хоста. Неймспейсы Kubernetes изолируют многое, но не дают каждому поду отдельное ядро Linux.
Почему Kubernetes меняет характер последствий
Команды Kubernetes обычно оценивают подобные уязвимости через призму конфигурации рабочей нагрузки:
-
Запущен ли под от root или нет?
-
Является ли он привилегированным?
-
Есть ли у него опасные Linux-возможности?
-
Использует ли он host-неймспейсы или hostPath?
-
Применяет ли неймспейс Pod Security Standards Restricted?
-
Включён ли seccomp?
Эти вопросы по-прежнему полезны, но Copy Fail нарушает одно из распространённых допущений: seccomp-профиль RuntimeDefault — это не то же самое, что запрет AF_ALG.
Kubernetes определяет RuntimeDefault как seccomp-профиль по умолчанию для используемого среды выполнения контейнеров (container runtime). Этот профиль варьируется в зависимости от рантайма и версии. В проверенных нами профилях Docker/Moby и containerd запрещают socket(AF_VSOCK, …), но не запрещают socket(AF_ALG, …). AF_ALG — это адресное семейство 38, AF_VSOCK — 40.
Это значит, что pod может выглядеть вполне безопасным по большинству стандартных критериев Kubernetes — и при этом иметь доступ к интерфейсу ядра, необходимому для эксплуатации данной уязвимости.
Что мы тестировали
Мы провели пять оборонительных лабораторных тестов на обоих кластерах, а затем — контролируемые тесты цепочки получения root на Talos/containerd и EKS/containerd.
1. Разрешает ли RuntimeDefault AF_ALG?
В обоих кластерах pod, не имеющий прав root, со сброшенными capabilities и seccompProfile.type: RuntimeDefault, успешно создал AF_ALG-сокет.
Результат на Talos:
AF_ALG_SOCKET_OK
AF_ALG_AUTHENCESN_BIND_OK
Результат на EKS:
AF_ALG_SOCKET_OK
AF_ALG_AUTHENCESN_BIND_OK
Это само по себе не доказывает факт эксплуатации. Это доказывает, что соответствующий путь системного вызова был доступен из обычного пода.
2. Блокирует ли PSS Restricted AF_ALG?
Нет. В обоих кластерах неймспейс с pod-security.kubernetes.io/enforce=restricted допустил pod, запущенный не от root с профилем RuntimeDefault, который мог создавать AF_ALG-сокеты и выполнять bind к нужному AEAD-алгоритму.
Оба кластера вернули:
PSS_RESTRICTED_AFALG_OK
Это не баг Kubernetes. PSS Restricted — это базовый уровень защиты рабочих нагрузок, а не обещание заблокировать любую поверхность атаки ядра.
Главный вывод прост: не говорите себе, что «PSS Restricted» означает «AF_ALG заблокирован».
3. Может ли другой pod наблюдать изменения кэша страниц?
Да — в нашем лабораторном тесте с общим hostPath-inode.
На Talos pod-писатель в одном неймспейсе изменил закэшированные байты тестового файла со смещением 64 с CROS на TLXN. Pod-читатель в другом неймспейсе наблюдал изменённые байты:
CROSSNS_WRITER_BEFORE 43524f53 b'CROS'
CROSSNS_WRITER_AFTER 544c584e b'TLXN'
CROSSNS_READER_OFFSET_64 544c584e b'TLXN'
На EKS тот же кросс-неймспейсный тест изменил CROS на EKXN:
CROSSNS_WRITER_BEFORE 43524f53 b'CROS'
CROSSNS_WRITER_AFTER 454b584e b'EKXN'
CROSSNS_READER_OFFSET_64 454b584e b'EKXN'
Неймспейсы не имели значения, потому что кэш — это ресурс узла, а не неймспейса.
4. Сохраняется ли эффект после завершения атакующего пода?
Да, в нашем лабораторном тесте. После удаления Job-писателя и Job-читателя следующий Job-читатель, запланированный на том же узле, всё равно наблюдал изменённые закэшированные байты.
Talos:
LIFECYCLE_READER_OFFSET_64 544c584e b'TLXN'
EKS:
LIFECYCLE_READER_OFFSET_64 454b584e b'EKXN'
Это не персистентность на диске. Это персистентность в кэше страниц узла. Перезагрузка или иное вытеснение соответствующих страниц устраняет этот класс эффектов, однако одно лишь удаление пода этого не делает.
5. Требуется ли для этого hostPath?
Это был тест, который интересовал нас больше всего. HostPath — уже высокорисковый паттерн, и аудитория Kubernetes справедливо спросила бы: не сводится ли всё это просто к «hostPath опасен» с лишними шагами?
Мы создали специальный лабораторный образ с файлом только для чтения по пути /copyfail-lab/target.bin. Pod A запустился из этого образа и изменил закэшированные байты файла. Pod B запустился из того же образа на том же узле и прочитал тот же путь.
На Talos Pod A изменил IMG0 на TIMG, и Pod B увидел TIMG:
IMAGE_WRITER_BEFORE 494d4730 b'IMG0'
IMAGE_WRITER_AFTER 54494d47 b'TIMG'
IMAGE_READER_OFFSET_64 54494d47 b'TIMG'
IMAGE_EXPECTED_SHA256 915a6e4d52cf856e62c67cdb4e453c785c3ec6515e51dee3fd3f95e1c9d9f03a
IMAGE_READER_SHA256 a18219a47a679b294ed62a16bd6a9c8b050799c5a282f3e650b63745970fa8ac
На EKS Pod A изменил IMG0 на EIMG, и Pod B увидел EIMG:
IMAGE_WRITER_BEFORE 494d4730 b'IMG0'
IMAGE_WRITER_AFTER 45494d47 b'EIMG'
IMAGE_READER_OFFSET_64 45494d47 b'EIMG'
IMAGE_EXPECTED_SHA256 915a6e4d52cf856e62c67cdb4e453c785c3ec6515e51dee3fd3f95e1c9d9f03a
IMAGE_READER_SHA256 f4b6127700e72fe2c7f9293a427e7966bd66572df3a16a505364f7bd1a1448a5
Вот в чём суть находки с точки зрения Kubernetes: в наших лабораторных тестах на Talos/containerd и EKS/containerd проблема не ограничивалась hostPath. Для кросс-подовой видимости на одном узле оказалось достаточно файла, встроенного в слой образа контейнера.
Не стоит излишне обобщать результаты за пределы того, что мы реально тестировали. Поведение снапшоттеров (snapshotters), драйверы хранилища, сборка мусора образов, вытеснение кэша страниц и конфигурация рантайма могут изменить детали. Но утверждение «это важно только если вы монтируете hostPath» не соответствует действительности в кластерах, которые мы тестировали.
Может ли это привести к получению root в Kubernetes?
Да — с важными оговорками.
После теста со слоем образа мы создали вторые одноразовые лабораторные образы для Talos и EKS. Они содержали специально созданный setuid-root помощник, единственным привилегированным действием которого была запись маркера внутри своего контейнера при условии, что четырёхбайтовый маркер в файле его собственного слоя образа изменился. Помощники не затрагивали файлы хоста, файлы, управляемые пакетным менеджером, или реальные бинарники приложений.
В поде без прав root, со сброшенными capabilities, с seccomp RuntimeDefault и allowPrivilegeEscalation: true помощник отказывал в доступе до мутации, а после изменения закэшированных байтов слоя образа достигал euid 0:
COPYFAIL_LAB_DENY found=0 ruid=1000 euid_start=0 euid_now=1000
COPYFAIL_WRITE ... before=4a4c5430 after=4a4c5431
COPYFAIL_LAB_ALLOW found=1 regain=0 marker_fd=3 ruid=1000 euid_start=0 euid_now=0
Мы воспроизвели ту же последовательность на Talos/containerd и EKS/containerd. Это доказывает полную цепочку получения root внутри контейнера в наших лабораторных условиях, при наличии доступной setuid-цели и pod-а, допускающего эскалацию привилегий.
PSS Restricted меняет эту часть цепочки. Мы запустили тот же мутированный помощник с allowPrivilegeEscalation: false, что устанавливает no_new_privs. Изменённые байты были видны, но помощник стартовал без setuid-повышения и не смог получить euid 0:
COPYFAIL_LAB_ALLOW found=1 regain=-1 marker_fd=-1 errno=1 ruid=1000 euid_start=1000 euid_now=1000
Специфичный для Kubernetes результат — это кросс-подовый вариант, который также воспроизвёлся в обоих кластерах. Pod-писатель под PSS Restricted изменил закэшированные байты помощника в общем слое образа. Отдельный pod из того же образа на том же узле, с allowPrivilegeEscalation: true, затем наблюдал изменённые байты слоя образа и достиг euid 0:
WRITER: COPYFAIL_WRITE ... before=4a4c4330 after=4a4c4331
WRITER: COPYFAIL_LAB_ALLOW found=1 regain=-1 marker_fd=-1 euid_start=1000 euid_now=1000
READER_JLC0_OFFSET -1 READER_JLC1_OFFSET 8192
READER: COPYFAIL_LAB_ALLOW found=1 regain=0 marker_fd=3 ruid=1000 euid_start=0 euid_now=0
Что это означает: PSS Restricted не помешал поду изменить байты в кэше страниц общего слоя образа, а другой pod с доступной setuid-целью и включённой эскалацией привилегий смог воспользоваться этим изменённым состоянием кэша.
Что это не означает: мы не доказали компрометацию хоста с правами root, побег из контейнера (container escape) или то, что любая рабочая нагрузка под PSS Restricted может стать root именно через этот setuid-путь. Результат с получением root зависит от наличия доступной цели, способной превратить изменённые байты в привилегированное выполнение.
Диск оставался нетронутым, пока кэшированные чтения видели изменения
Для лабораторного файла на hostPath мы сравнили обычные кэшированные чтения с чтениями через O_DIRECT.
На Talos обычные чтения возвращали JLT!, а прямые чтения видели оригинальный 0123 и оригинальную SHA-256:
NORMAL_OFFSET_64 4a4c5421 b'JLT!'
NORMAL_SHA256 40879caad4634328849e0405d26e23f506ea54c86c3a8176a036c3acb4a9e39a
DIRECT_OFFSET_64 30313233 b'0123'
DIRECT_SHA256 d281ea21d2bc15d0f737288a081f5982ad6e08d836af73ca013ab00e469cf27f
На EKS обычные чтения возвращали EKS!, а прямые чтения видели оригинальный 0123 и оригинальную SHA-256:
NORMAL_OFFSET_64 454b5321 b'EKS!'
NORMAL_SHA256 0e33005673886ecf2d6f7782dbcfca3f7ef29d09411ca4a925a6e8b83b15bb4d
DIRECT_OFFSET_64 30313233 b'0123'
DIRECT_SHA256 d281ea21d2bc15d0f737288a081f5982ad6e08d836af73ca013ab00e469cf27f
Это подтверждает ключевое наблюдение Xint: данный класс повреждений может влиять на то, что видят обычные операции чтения файлов, не изменяя при этом персистентное содержимое файла на диске. Это также объясняет, почему проверки целостности, ограниченные только диском, могут оказаться неправильным средством защиты для данного класса ошибок.
Здесь важна точность формулировок. Мы не утверждаем, что каждый инструмент проверки целостности файлов отказывает в любой конфигурации. Мы говорим о том, что если инструмент проверяет только персистентные байты на диске, он может пропустить изменение, существующее только в кэше страниц, которое обычные операции чтения всё равно будут наблюдать.
Проверенный способ митигации
Первичным исправлением является патч ядра. Red Hat, Ubuntu, Debian и другие дистрибутивы следует отслеживать через собственные advisory- и пакетные каналы, поскольку вендорские ядра часто содержат бэкпортированные исправления без соответствия номерам версий upstream.
Проверьте, применима ли рекомендация «отключить модуль» к вашей OS на узле. В некоторых ядрах семейства RHEL algif_aead встроен в ядро, а не загружается как удаляемый модуль, поэтому правила blacklist в modprobe.d и команда rmmod algif_aead могут выполниться без реального устранения поверхности атаки. Проверьте митигацию с помощью runtime-теста на создание AF_ALG-сокета или поддерживаемого вендором контроля, прежде чем считать узел защищённым.
В качестве компенсирующего контроля мы протестировали профиль seccomp типа Localhost, запрещающий socket(), когда первый аргумент равен AF_ALG (38). На обоих кластерах — Talos и EKS — это заблокировало путь с ошибкой EPERM, а тестовый файл остался неизменным.
Talos:
AF_ALG_SOCKET_BLOCKED errno=1 strerror=Operation not permitted
MITIGATED_BEFORE 61626364 b'abcd'
MITIGATED_AFTER 61626364 b'abcd'
EKS:
AF_ALG_SOCKET_BLOCKED errno=1 strerror=Operation not permitted
MITIGATED_BEFORE 61626364 b'abcd'
MITIGATED_AFTER 61626364 b'abcd'
Мы также повторили лабораторный тест с setuid-помощником на Talos с тем же профилем Localhost, запрещающим AF_ALG. Писатель завершился ошибкой на socket(AF_ALG, …), маркер свежего помощника остался неизменным, а помощник не достиг мутированного пути:
PermissionError: [Errno 1] Operation not permitted
AFTER_JLB0_OFFSET 8192 AFTER_JLB1_OFFSET -1
COPYFAIL_LAB_DENY found=0 ruid=1000 euid_start=0 euid_now=1000
Kubernetes не встраивает seccomp-фильтры системных вызовов прямо в YAML пода. Профиль Localhost должен находиться на узле по пути, где kubelet хранит seccomp-профили, а спецификации подов ссылаются на него по имени. Это означает, что план устранения состоит из двух частей:
-
Разместить профиль с запретом AF_ALG на каждом узле, которому это необходимо.
-
Принудительно применить этот профиль для ненадёжных рабочих нагрузок до тех пор, пока ядро не будет пропатчено.
Не относитесь к слову Localhost как к магическому заклинанию. Нужно проверить реальное содержимое профиля.
Что сегодня обнаруживает Juliet
Juliet теперь имеет начальный сканер для Copy Fail, а также policy gate для команд, которые хотят применять временную seccomp-митигацию в период патчинга ядер на узлах.
Сканер объединяет три источника данных:
-
Факты Node KBOM:
osImage,kernelVersionиcontainerRuntimeVersion. -
Конфигурация безопасности рабочей нагрузки: эффективный seccomp-профиль каждого контейнера с учётом наследования настроек на уровне пода.
-
Содержимое seccomp-профилей
Localhostна узле: агент Juliet на узле хэширует и разбирает JSON профилей kubelet типаLocalhostи проверяет, запрещает ли указанный профильsocket(AF_ALG, …).
Juliet открывает Issue высокой степени серьёзности, когда pod запланирован на узле в статусе affected или unknown по Copy Fail, и хотя бы один контейнер не использует верифицированный на узле профиль Localhost, запрещающий AF_ALG. Профили RuntimeDefault, незаданные, Unconfined, не относящиеся к Localhost, с отсутствующим содержимым, ошибками разбора или профили Localhost, не доказывающие наличие запрета, — все они остаются в статусе подверженных уязвимости.
Хотите проверить свои кластеры? Запросите бесплатную проверку на подверженность Copy Fail, или запустите Juliet бесплатно, подключите кластер, откройте Security → All Findings и найдите Copy Fail или CVE-2026-31431. Существующие пользователи также могут спросить Explorer: which pods are exposed to Copy Fail?
Мы также добавили встроенную политику высокой степени серьёзности с именем copyfail-require-custom-seccomp. По умолчанию она отключена и предназначена для пользователей, желающих проводить аудит или принудительно применять эту конкретную митигацию. Политика отмечает контейнеры, init-контейнеры и ephemeral-контейнеры, эффективный seccomp-профиль которых не задан, равен Unconfined, RuntimeDefault или любому значению, не являющемуся Localhost.
Одно важное ограничение: Juliet не претендует на полное определение статуса исправления CVE на узле только по строкам версии ядра. Сопоставление версий ядра рискованно, поскольку вендоры бэкпортируют исправления. Сканер помечает ядра, на которых мы воспроизвели уязвимость в лаборатории, как affected, учитывает случаи «не затронуто» от вендоров, которые мы проверили, и в остальных случаях оставляет узел в статусе unknown до появления подтверждения в виде вендорского пакета или advisory.
Что командам Kubernetes следует делать сейчас
1. В первую очередь патчить узлы
Считайте ядро узла источником истины. Используйте advisory- и пакетные каналы вашего OS-вендора, а не только семантические версии upstream-ядра.
CISA теперь включила CVE-2026-31431 в каталог KEV, поэтому относитесь к этому как к приоритетной работе по патчингу, а не к теоретической локальной эскалации привилегий Linux. Red Hat оценивает проблему как Important и в своём трекере перечисляет RHEL 8, RHEL 9, RHEL 10 и потоки kernel-rt для RHEL 8/9 как затронутые. Ubuntu отмечает проблему как High. Трекер Debian показывает статус по конкретным пакетам в разных ветках. Эти статусы могут меняться по мере выхода пакетов, поэтому там, где это возможно, автоматизируйте работу с вендорскими данными.
2. Не считайте, что RuntimeDefault блокирует AF_ALG
Мы протестировали настройки containerd по умолчанию на Talos и EKS и обнаружили доступность AF_ALG. Проверенные нами текущие профили по умолчанию для Moby и containerd также не запрещают AF_ALG.
Если ваша временная митигация опирается на seccomp, проверьте реальное поведение рантайма на каждом семействе узлов.
3. Используйте целевой профиль seccomp типа Localhost для ненадёжных рабочих нагрузок
Блокировка всех вызовов socket() сломает рабочие нагрузки. Точечный контроль — запретить socket() только тогда, когда адресное семейство равно AF_ALG.
Примените этот профиль к неймспейсам, в которых выполняется ненадёжный код, CI-задания, build-раннеры, мультитенантные рабочие нагрузки или что-либо, выполняющее плагины, предоставленные пользователями.
4. Снизить риски совместного использования узла
Результат с образом контейнера важен, потому что многие поды на одном узле могут разделять один и тот же файл из нижнего слоя образа. До выхода патча снизьте ненужное совместное размещение высокорисковых и высокоценных рабочих нагрузок:
-
Изолируйте CI/build-рабочие нагрузки на выделенные узлы.
-
Избегайте смешения мультитенантных рабочих нагрузок с рабочими нагрузками, смежными с плоскостью управления, или привилегированными рабочими нагрузками.
-
Сократите число привилегированных подов, использование host-неймспейсов и широких hostPath-монтирований.
-
Рассмотрите использование изолированных рантаймов (sandboxed runtimes), но проверьте их. Ни один из наших кластеров не имел доступных RuntimeClass для gVisor, Kata или Firecracker, поэтому мы не делаем заявлений о sandbox-рантаймах.
5. Относиться к подозрительным узлам как к скомпрометированным
Повреждение только в кэше страниц носит временный характер, но процесс, эксплуатировавший его, мог использовать полученный доступ для внесения персистентных изменений в другом месте. Если вы подозреваете эксплуатацию, пропатчите или замените узел и проведите расследование рабочих нагрузок, выполнявшихся на нём.
Сигналы рантайма — например, неожиданная активность AF_ALG или authencesn-сокетов от рабочих нагрузок, которым не нужны API криптографии ядра — являются полезными сигналами для первоначальной сортировки инцидента, однако само по себе создание сокета не является доказательством успешной эксплуатации Copy Fail. Рассматривайте это как значимый сигнал для расследования, сохраняйте доказательства и следуйте своему процессу реагирования на инциденты на узлах.
Что мы доказали и что не доказали
Реальных фактов здесь достаточно — без преувеличений.
Мы доказали контролируемую цепочку получения root внутри контейнера на Talos/containerd и EKS/containerd, когда pod с allowPrivilegeEscalation: true запускал мутированный специально созданный setuid-помощник из общего слоя образа.
Не утверждайте, что каждый Kubernetes-кластер уязвим. Результат зависит от запущенного ядра, вендорских патчей, конфигурации рантайма и политики рабочих нагрузок.
Не утверждайте, что побег из контейнера или компрометация хоста с правами root гарантированы. Это мощный примитив локального воздействия на ядро, однако компрометация узла зависит от доступных целевых файлов, неймспейсов, монтирований, поведения рабочей нагрузки и того, что злоумышленник может заставить другой процесс прочитать или выполнить.
Не утверждайте, что PSS Restricted в одиночку делает угрозу безвредной. В нашей лаборатории PSS Restricted останавливал setuid-передачу внутри ограниченного пода, но не останавливал этот pod от мутации байтов в кэше общего слоя образа, которые другой pod впоследствии использовал.
Не утверждайте, что инструменты проверки целостности файлов всегда отказывают. Скажите точнее: инструменты, проверяющие только персистентные байты на диске, могут пропустить изменение, существующее только в кэше страниц, которое обычные операции чтения всё равно наблюдают.
Не утверждайте, что sandbox-рантаймы митигируют проблему без проведения тестов. Они могут изменить модель риска, но мы не имели доступа к sandbox RuntimeClass ни в одном из протестированных кластеров.
Часто задаваемые вопросы
Это уязвимость Kubernetes?
Нет. CVE-2026-31431 — уязвимость ядра Linux. Kubernetes важен здесь потому, что поды на одном узле разделяют ядро хоста, и в протестированных нами сценариях эффекты от кэша страниц были видны между подами на одном узле.
Блокирует ли Pod Security Standards Restricted эту уязвимость?
Нет, в наших тестах — нет. PSS Restricted допустил pod без прав root с профилем RuntimeDefault, который мог создавать AF_ALG-сокеты и выполнять bind к нужному AEAD-алгоритму.
Блокирует ли seccomp RuntimeDefault?
Нет — в протестированных нами кластерах Talos/containerd и EKS/containerd. RuntimeDefault определяется рантаймом. Проверенные нами стандартные профили рантаймов не запрещали AF_ALG.
Можно ли через это получить root?
В наших лабораторных тестах на Talos и EKS — да, для root внутри контейнера при определённых условиях: наличие доступной setuid-цели в специально созданном слое образа и pod с allowPrivilegeEscalation: true. Мы не доказали компрометацию хоста с правами root или побег из контейнера; allowPrivilegeEscalation: false предотвращал эту setuid-передачу в протестированных нами ограниченных подах.
Требуется ли для этого hostPath?
Нет, в наших тестах — нет. Мы воспроизвели кросс-подовую видимость с помощью специально созданного слоя образа контейнера. HostPath был полезен для демонстрации разницы между поведением диска и кэша страниц с помощью O_DIRECT, но для результата со слоем образа он не требовался.
Что нужно заблокировать?
Для компенсирующего контроля через seccomp — запретить socket(), когда arg0 равен AF_ALG (38). Проверьте реальный профиль на узле и протестируйте поведение рантайма. Патч ядра — первичное исправление.
Источники
Запись CVE-2026-31431 Запись NVD для CVE-2026-31431 Запись каталога CISA KEV для CVE-2026-31431 CISA: CVE-2026-31431 добавлена в KEV Microsoft Security: уязвимость Copy Fail позволяет эскалировать привилегии до root в Linux в облачных средах Xint: Copy Fail copy.fail Коммит исправления Linux stable fafe0fa2 Коммит исправления Linux stable ce42ee42 Коммит исправления Linux stable a664bf3d Данные Red Hat по CVE Бюллетень безопасности Red Hat RHSB-2026-02 Red Hat: митигация CVE-2026-31431 для OpenShift Red Hat: митигация CVE-2026-31431 для ROSA Classic и OpenShift Dedicated Данные Amazon Linux по CVE Данные Ubuntu по CVE Ubuntu: доступны исправления для уязвимости Copy Fail Трекер безопасности Debian AlmaLinux: выпущены патчи для Copy Fail CloudLinux: обновление ядра для Copy Fail SUSE: реакция на уязвимость Copy Fail CIQ: митигация CVE-2026-31431 для Rocky Linux Sidero Labs: Copy Fail и Talos Linux Pod Security Standards в Kubernetes Документация по seccomp в Kubernetes Ограничения безопасности ядра Linux в Kubernetes Документация Docker по seccomp Профиль seccomp по умолчанию для Moby Профиль seccomp по умолчанию для containerd Константы адресных семейств сокетов Linux