Исследователи Anthropic показали работающий эксплойт для уязвимости CVE-2026-98432 в TCP-стеке ядра Linux. Атака идёт по сети без учётной записи и без действий пользователя: на сервере с MPTCP-слушателем она приводит к выполнению команд с правами root. Официальная запись CVE оценивает проблему в 9,8 балла по CVSS 3.1 и относит её к критическим. Исправления уже вышли в основной ветке и во всех поддерживаемых стабильных ядрах, но программы на Go 1.24 и новее включают MPTCP по умолчанию и тоже попадают в зону риска.
Что известно об ошибке в TCP-стеке Linux
Суть ошибки
Ошибка живёт в обработке рукопожатия TCP на стороне сервера. Когда клиент присылает SYN, ядро создаёт request-сокет и сохраняет в нём опции IPv4, например Record Route или Timestamp. Это служебные байты заголовка, которые задают маршрут ответа или метки времени.
В функции tcp_v4_syn_recv_sock() ядро передаёт владение этими опциями дочернему сокету без копирования. Параллельно другая CPU может обрабатывать повторный SYN для того же request-сокета и собирать SYNACK. Чтение ireq->ireq_opt идёт только под rcu_read_lock(), а функции ip_build_and_send_pkt() и ip_options_build() затем дважды читают длину опций.
С момента коммита 079096f103fa request-сокеты обрабатываются без блокировки слушателя. Ничто не мешает освободить дочерний сокет, пока SYNACK ещё собирается. В inet_sock_destruct() память опций освобождается обычным kfree() вместо kfree_rcu(), поэтому сборка SYNACK обращается к уже освобождённой памяти. Это use-after-free, обращение к памяти после её освобождения.
Похожий сценарий связан с миграцией request-сокета: при net.ipv4.tcp_migrate_req=1 или BPF-программе REUSEPORT-миграции reqsk_timer_handler() клонирует request-сокет, и клон делит те же опции с оригиналом. Когда клон освобождают, другая CPU ещё может использовать эти опции, а tcp_v4_reqsk_destructor() тоже вызывает обычный kfree().
Исправление заменяет kfree() на kfree_rcu() в inet_sock_destruct() и tcp_v4_reqsk_destructor(). RCU (read-copy-update) - механизм ядра, который откладывает освобождение памяти, пока её читатели не закончат. IPv6 в первом сценарии не затронут: tcp_v6_syn_recv_sock() дублирует опции. Для миграции с ipv6_opt, который выставляет только CALIPSO, готовят отдельный патч.
Условия атаки
Эксплуатация не требует учётной записи, особых прав и действий пользователя. Нужен только доступ по сети к слушающему TCP-сокету на IPv4. Атакующий присылает SYN с опциями Record Route или Timestamp, а затем повторный SYN, чтобы попасть в гонку между завершением рукопожатия и освобождением сокета.
Anthropic показала цепочку на сервере с MPTCP-слушателем. MPTCP (Multipath TCP) - расширение TCP, которое ведёт несколько сетевых путей в одном соединении. При этом сама ошибка не привязана к MPTCP: Go Security Team прямо отмечает, что уязвимы могут быть и системы без таких слушателей.
Гонка устроена удобно для атакующего: проигранная попытка ломает только рукопожатие и не роняет систему. Поэтому попытки можно повторять, пока одна из них не сработает.
Что даёт эксплуатация
Минимальное последствие - отказ в обслуживании. Устаревшая длина опций или смещения заставляют ip_build_and_send_pkt() выйти за границы буфера SYNACK, а ip_options_build() - писать по неверным адресам; ядро падает с oops или паникой.
Дальше открываются утечка памяти и запись. Если освобождённый объект удаётся переиспользовать, SYNACK может вернуть атакующему соседние данные кучи ядра. Через подменённые смещения можно также выполнить записи за границами буфера и повредить управляющий поток.
Anthropic довела это до полной цепочки. На первом этапе эксплойт обходит KASLR, рандомизацию адресов ядра: гонка заставляет ядро прочитать подконтрольную атакующему длину и отправить лишние байты обратно, среди которых оказывается указатель ядра. На втором этапе переполнение перезаписывает указатель обратного вызова на подготовленную в памяти ядра полезную нагрузку, и та вызывает нужные функции ядра, заканчивая командой оболочки от root. В лабораторном PoC утечка указателя заняла около 48 минут, а выполнение команды - ещё около пяти.
Официальная оценка 9,8 по CVSS 3.1 отражает высокий ущерб по конфиденциальности, целостности и доступности. Вектор - сеть, сложность низкая, права и участие пользователя не нужны.
Затронутые версии
Уязвимы ядра Linux начиная с 4.4, где появился коммит 079096f103fa. Исправления вошли в стабильные выпуски 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10 и в 7.3 и новее. Основной коммит исправления - e3f33b0a в 7.3-rc7.
Дистрибутивы обновляются своими пакетами. В Debian исправления вышли для bookworm (6.1.190-1, DLA-4841-1), trixie (6.12.113-1, DSA-6568-1) и unstable (7.2.10-1). Отдельно обновлён linux-6.12 для bookworm - 6.12.113-1~deb12u1 по DLA-4850-1.
Проверять нужно версию ядра на самом хосте. В контейнерах ядро общее с хостом, поэтому обновление образа проблему не закрывает.
При чём тут Go и MPTCP
С версии Go 1.24 программы на Go включают MPTCP по умолчанию для слушающих сокетов на Linux. Поэтому Go-сервисы на стандартной библиотеке net, включая API-серверы и обратные прокси, могут сами создавать MPTCP-слушатели, даже если разработчик об этом не думал.
Отключить поведение можно на этапе выполнения: переменная окружения GODEBUG=multipathtcp=0. На этапе сборки в go.mod добавляют строку godebug multipathtcp=0. Для отдельных сокетов есть net.ListenConfig.SetMultipathTCP и net.Dialer.SetMultipathTCP.
Go Security Team считает такую меру хрупкой. Один забытый слушатель оставляет систему открытой, а расчёт на то, что все эксплойты требуют MPTCP, может не оправдаться. Патч ядра команда называет основным решением.
Что делать
В первую очередь обновите ядро до исправленного выпуска своей ветки и перезагрузитесь. Проверьте версию командой uname -r и сверьте её со списком исправленных выпусков. Для дистрибутивных ядер дождитесь пакета с исправлением или поставьте его из security-репозитория.
Отдельно посмотрите на интернет-сервисы, которые принимают TCP-соединения на IPv4: веб-серверы, прокси, балансировщики и API. Приоритет - хосты с MPTCP-слушателями и системы, где включали net.ipv4.tcp_migrate_req=1 или BPF-программы миграции.
Если обновиться сразу нельзя, сократите сетевой доступ к слушающим портам и отключите MPTCP в Go-программах через GODEBUG или go.mod. Эти меры снижают поверхность атаки, но не устраняют ошибку в ядре. После обновления проверьте журналы на паники ядра и убедитесь, что перезагрузка действительно произошла: обновлённый пакет без перезагрузки оставляет старое ядро в работе.
Ссылки
- https://www.cve.org/CVERecord?id=CVE-2026-98432
- https://git.kernel.org/pub/scm/linux/security/vulns.git/plain/cve/published/2026/CVE-2026-98432.mbox
- https://www.anthropic.com/research/discovering-vulnerabilities-with-claude
- https://security-tracker.debian.org/tracker/CVE-2026-98432
- https://groups.google.com/g/golang-announce/c/PCoQcdxoScw