Добавить в корзинуПозвонить
Найти в Дзене
Пока не взломали

Уязвимость Copy Fail, она же CVE-2026-31431

Это не тот случай, когда сервер можно забрать прямо из интернета одним красивым запросом. Тут атакующему сначала нужен обычный пользователь на машине или код внутри контейнера. Но дальше история становится заметно веселее: из непривилегированного состояния можно попытаться доползти до root. И самое мерзкое — баг выглядит почти скромно. Речь про контролируемую запись всего 4 байт в page cache читаемого файла. Четыре байта, да. В обычной жизни это звучит как мелочь, а в ядре Linux — как «мы чуть-чуть подпилили несущую балку, ничего страшного». Технически всё крутится вокруг AF_ALG. Это такой интерфейс, через который userspace может ходить к криптографическому API ядра через сокеты. В цепочке всплывают algif_aead, AEAD-режимы и шаблон authencesn, который обычно живёт где-то рядом с IPsec ESN. Сам по себе набор не выглядит криминально. Крипта, сокеты, ядро, оптимизации — обычная внутренняя кухня. А потом в кадр заходит splice(). Он нужен, чтобы гонять данные почти без копирования. Бы

Уязвимость Copy Fail, она же CVE-2026-31431

Это не тот случай, когда сервер можно забрать прямо из интернета одним красивым запросом. Тут атакующему сначала нужен обычный пользователь на машине или код внутри контейнера. Но дальше история становится заметно веселее: из непривилегированного состояния можно попытаться доползти до root.

И самое мерзкое — баг выглядит почти скромно.

Речь про контролируемую запись всего 4 байт в page cache читаемого файла. Четыре байта, да. В обычной жизни это звучит как мелочь, а в ядре Linux — как «мы чуть-чуть подпилили несущую балку, ничего страшного».

Технически всё крутится вокруг AF_ALG. Это такой интерфейс, через который userspace может ходить к криптографическому API ядра через сокеты. В цепочке всплывают algif_aead, AEAD-режимы и шаблон authencesn, который обычно живёт где-то рядом с IPsec ESN.

Сам по себе набор не выглядит криминально. Крипта, сокеты, ядро, оптимизации — обычная внутренняя кухня.

А потом в кадр заходит splice().

Он нужен, чтобы гонять данные почти без копирования. Быстро, красиво, эффективно. Именно тот тип оптимизации, который все любят до момента, пока кто-нибудь не замечает, что page cache внезапно оказался в роли буфера, куда можно писать.

В algif_aead когда-то добавили in-place-обработку: источник и приёмник операции могут быть одним и тем же scatterlist. Меньше копирований, меньше накладных расходов, всё по учебнику производительности.

Но у authencesn есть своя маленькая привычка — использовать часть destination-буфера как временное место для перестановки байтов. В нормальном сценарии это просто странная, но рабочая внутренняя механика. А в связке со splice() получается фокус: временная запись может попасть не в обычный буфер, а в страницу page cache файла.

Вот здесь уже становится нехорошо.

Файл на диске остаётся прежним. Проверки целостности могут быть спокойны. Пакетный менеджер тоже ничего не заподозрит. А процесс при запуске может получить данные не с диска, а из уже подменённого page cache.

В обсуждениях всплывал сценарий с setuid-бинарями вроде /usr/bin/su: на диске лежит нормальный файл, а в памяти — чуть «доработанная» версия. Ровно тот тип бага, который выглядит как лабораторная странность, пока не понимаешь, что примитив достаточно практичный.

Отдельная радость — контейнеры.

Page cache общий с хостом, и если непривилегированный код внутри контейнера может добраться до нужной цепочки, изоляция снова начинает напоминать не бетонную стену, а нарисованную линию на полу. Мы с вами знаем, как это обычно продаётся: «почти как виртуалка». А потом внезапно выясняется, что нет, не почти.

По данным исследователей, корень проблемы тянется с ветки ядра 4.14, так что потенциальная зона поражения большая. Успешные проверки упоминались на свежих Ubuntu, Amazon Linux, RHEL и SUSE. Патч, судя по описанию, делает не магию, а нормальную инженерную вещь: убирает опасную in-place-оптимизацию в algif_aead.

Иногда лишнее копирование дешевле, чем бесплатный локальный root.

Если у вас shared-хостинг, Kubernetes-ноды, CI-runner'ы, терминальные серверы или любая машина, где крутится чужой код, это не та уязвимость, которую стоит отложить «до планового окна через месяц». Обновление ядра — основной вариант.

Временный костыль возможен, если algif_aead собран модулем:

echo "install algif_aead /bin/false" > /etc/modprob

rmmod algif_aead 2>/dev/null

Проверить, загружен ли он сейчас:

lsmod | grep algif_aead

Если он встроен прямо в ядро, этот трюк не поможет. Тогда остаётся патчить ядро и резать доступ к AF_ALG, особенно в контейнерах и песочницах. Через seccomp, например. Большинству веб-приложений криптосокеты ядра вообще не нужны, но обычно контейнеру выдают побольше возможностей «чтобы потом не разбираться, почему не стартует».

Мониторинг тоже имеет смысл. Создание сокетов семейства AF_ALG, странные связки со splice(), обращения к конструкциям вроде authencesn(hmac(sha256),cbc(aes)) — для обычного www-data или CI-job это не совсем будничное поведение.

Copy Fail не превращает любой Linux-сервер в тыкву по сети.