CVE-2026-98070 в Linux Kernel: race condition в RDS TCP, уязвимые версии и защита

CVE: CVE-2026-98070
Продукт: Linux Kernel
Дата публикации: 25.09.2026
Критичность: HIGH
CVSS: 8.1 (3.1)
EPSS: нет данных; процентиль нет данных
CISA KEV: нет подтверждения в каталоге CISA KEV

Краткое описание​


В Linux kernel исправлена гонка в модуле net/rds при обработке reset callbacks для TCP. Старый код ждал освобождения флага RDS_IN_XMIT, но на слаботранзакционных архитектурах это не исключало повторный захват флага отправителем и параллельное переписывание состояния cp_xmit_* вместе с заменой сокета.

Нарушается взаимное исключение между путями отправки и сброса. Это приводит к повреждению данных ядра, потере целостности соединения и возможному отказу работы RDS-сервисов.

Основные характеристики​


Риск связан с гонкой в ядре Linux при обработке TCP-соединений RDS. Один поток может одновременно менять состояние передачи и заменять сокет, что нарушает инварианты модуля net/rds.

  • Тип ошибки: race condition / store-buffering в слаботранзакционной архитектуре
  • CVSS 3.1: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H, оценка 8.1, severity HIGH
  • Условие атаки: удалённый доступ к RDS-сервису или возможность инициировать reset TCP-соединения в уязвимой системе
  • Факт эксплуатации: не подтверждён в предоставленных источниках
  • EPSS: нет данных; процентиль не указан

Какие продукты и версии затронуты​


Затронут Linux kernel с модулем net/rds, где используется функция rds_tcp_reset_callbacks(). Пакет доказательств не содержит точного списка версий ядра и дистрибутивов.

  • Компонент: net/rds/tcp.c в ядре Linux
  • Функция: rds_tcp_reset_callbacks()
  • Связанные функции: rds_send_xmit(), rds_send_path_reset(), rds_conn_shutdown(), tcp_sendmsg()
  • Версии: не раскрыты в предоставленных источниках
  • Дистрибутивы: не раскрыты в предоставленных источниках

Причина уязвимости​


Старый код вызывал wait_event(), ожидая, что флаг RDS_IN_XMIT будет снят. Это только читало состояние флага и не блокировало повторный захват другим потоком.

После возврата из wait_event() функция rds_send_xmit() могла снова установить RDS_IN_XMIT. Между путями reset и send возникла store-buffering гонка: resetter записывал state и читал bit, sender записывал bit и читал state. На слаботранзакционных архитектурах оба потока могли не увидеть запись друг друга.

В результате rds_send_path_reset() переписывала cp_xmit_* одновременно с работой отправки. Это нарушало условие, которое комментарий над rds_send_path_reset() требует соблюдать: вызов должен быть защищён от параллельного изменения состояния передачи.

Дополнительно старый код кэшировал t_sock до ожидания. Если teardown в rds_conn_shutdown() освобождал сокет и очищал t_sock, застаревший указатель мог остаться в памяти reset-потока. После пробуждения accept path мог получить невалидный или уже освобождённый указатель.

Отдельная ветка !osock вызывала rds_send_path_reset() без какой-либо сериализации. Теперь она выполняется под RDS_IN_XMIT, как и основной путь.

Как работает атака​


Атака использует гонку между двумя путями: reset TCP-соединения в RDS и отправка данных по этому соединению.

Первый поток вызывает rds_tcp_reset_callbacks(). Он устанавливает состояние пути в RDS_CONN_RESETTING, чтобы остановить новых отправителей. Затем он ждёт освобождения RDS_IN_XMIT.

Второй поток находится внутри tcp_sendmsg() или вызывающей функции и может войти в rds_send_xmit(). После того как wait_event() вернул управление reset-потоку, второй поток может снова захватить RDS_IN_XMIT.

Из-за слабой порядковости записей процессоры могут не показать друг другу обновления state и bit. Reset-поток видит флаг очищенным, но на самом деле sender уже владеет им. Sender видит старое состояние, но resetter уже начал менять cp_xmit_*.

Оба потока начинают одновременно работать с одним и тем же состоянием передачи. rds_send_path_reset() перезаписывает cp_xmit_*, а rds_send_xmit() использует эти поля для отправки. Это приводит к повреждению структуры соединения, потере пакетов, некорректным переходам состояния RDS_CONN_RESETTING / RDS_CONN_UP и возможному падению ядра или отказу сервиса.

Отдельный сценарий связан со старым указателем t_sock. Если teardown освободил сокет до пробуждения reset-потока, указатель может быть невалидным. Использование такого указателя нарушает память и может вызвать crash или повреждение данных.

Условия успешной эксплуатации​


Для успешной эксплуатации нужны следующие условия.

  • Система использует Linux kernel с уязвимым модулем net/rds
  • Включён подсистема RDS или сервис, использующий RDS TCP
  • Есть возможность инициировать reset TCP-соединения в RDS: например, обрыв соединения, duelling SYN, повторный connect/accept или принудительный shutdown
  • Архитектура поддерживает слабую порядковость записей или гонка может воспроизводиться на других архитектурах при определённых условиях переключения потоков
  • Уязвимая версия ядра не обновлена до исправленной ветки stable

Возможный сценарий атаки​


Сценарий начинается с RDS-соединения между двумя узлами. На одном из узлов происходит reset TCP-соединения, например из-за duelling SYN или ошибки соединения.

Reset-поток вызывает rds_tcp_reset_callbacks(). Он переводит путь в состояние RDS_CONN_RESETTING и ждёт освобождения RDS_IN_XMIT. В это время другой поток пытается отправить данные по тому же соединению через tcp_sendmsg().

После возврата из ожидания reset-поток начинает менять cp_xmit_* и заменять сокет. Если sender успел снова захватить RDS_IN_XMIT, оба потока работают одновременно. Переписывание состояния передачи происходит без взаимного исключения.

Результатом может стать повреждение структуры rds_conn_path или cp_transport_data. Соединение может перейти в некорректное состояние, пакеты могут потеряться, а сервис RDS может перестать отвечать. При использовании stale t_sock возможна работа с освобождённым указателем сокета.

После обновления ядра до стабильной ветки с исправлением reset-поток захватывает RDS_IN_XMIT через test_and_set_bit_lock(), удерживает флаг на протяжении замены сокета и вызова rds_send_path_reset(), затем освобождает его и будит ожидающие потоки. Это исключает параллельное выполнение.

Ссылки на исправления:


Есть ли публичный эксплойт​


В предоставленных источниках нет информации о публичном эксплойте, PoC или подтверждённой эксплуатации CVE-2026-98070.

Исправление опубликовано в stable tree Linux kernel. Это означает, что техническое описание уязвимости и патч доступны в ядре. Но факт того, что кто-то использует эту гонку для компрометации систем, не подтверждён.

Отсутствие публичного эксплойта не означает, что эксплуатация невозможна. Условие AC:H указывает на сложность автоматизации: нужно попасть в узкое окно гонки между reset и send потоками, а также иметь доступ к RDS-сервису или возможность инициировать reset соединений.

Для оценки риска достаточно проверить версию ядра и наличие модуля net/rds. Если сервис использует RDS TCP, обновление до исправленной stable-ветки является приоритетным.

Признаки эксплуатации​


Специфичных IOC для CVE-2026-98070 в предоставленных источниках нет.

Можно использовать только общие точки контроля, которые не являются уникальными признаками этой уязвимости.

  • Рост числа RDS reset callbacks или ошибок TCP в ядре
  • Внезапное увеличение количества обрывов соединений RDS
  • Падения ядра или kernel panic с участием net/rds, tcp, socket или memory corruption
  • Аномальные задержки в RDS-сервисах после массовых reconnect/accept операций
  • Появление некорректных состояний RDS_CONN_RESETTING / RDS_CONN_UP в логировании ядра
  • Рост числа ошибок cancel_delayed_work_sync или lock_sock в trace

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

Как обнаружить атаку​


Для обнаружения атаки или последствий уязвимости можно использовать мониторинг ядра и сетевого состояния.

  • Проверить версию ядра с командами uname -r, uname -a и cat /proc/version
  • Проверить, загружен ли модуль net/rds: lsmod | grep rds или modinfo rds если доступен
  • Смотреть kernel log на ошибки RDS, TCP reset, socket lock, memory corruption
  • Использовать ftrace или bpftrace для отслеживания вызовов rds_tcp_reset_callbacks(), rds_send_xmit(), tcp_sendmsg()
  • Мониторить количество соединений RDS и частоту reset/duelling SYN
  • Проверять журналы приложений, использующих RDS, на повторные обрывы и reconnect

Конкретных сигнатур для этой CVE нет. Детекция опирается на аномалии поведения RDS TCP и ошибки ядра.

Полезные команды:

Bash:
uname -r
uname -a
cat /proc/version
lsmod | grep rds
dmesg | grep -iE 'rds|tcp reset|socket lock|panic'
journalctl -k | grep -iE 'rds|tcp reset|socket lock|panic'

Как проверить свою версию​


Проверить версию ядра можно стандартными командами.

  • uname -r — краткая версия ядра
  • uname -a — полная информация о ядре и архитектуре
  • cat /proc/version — версия ядра из runtime

Если используется дистрибутив, дополнительно проверять пакет kernel через пакетный менеджер:

Bash:
dpkg -l | grep linux-image   # Debian/Ubuntu
rpm -qa | grep kernel         # RHEL/CentOS/Fedora
apt-cache policy linux-image   # Debian/Ubuntu
yum list installed kernel     # RHEL/CentOS/Fedora

Точный список исправленных версий не раскрыт в предоставленных источниках. Для подтверждения исправления нужно сверить версию ядра с stable-веткой, куда был внесён патч.

Ссылки на патчи:


Исправление​


Основное исправление — обновление Linux kernel до стабильной ветки, содержащей патч net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks().

  • Обновить ядро через пакетный менеджер дистрибутива
  • Проверить наличие модуля net/rds после обновления
  • Перезагрузить систему или перезапустить сервисы, использующие RDS TCP
  • Если обновление невозможно немедленно, ограничить доступ к RDS-сервисам и снизить частоту reset соединений

Патч меняет логику rds_tcp_reset_callbacks():

  • Вместо простого ожидания освобождения RDS_IN_XMIT используется test_and_set_bit_lock()
  • Флаг удерживается на протяжении замены сокета и вызова rds_send_path_reset()
  • После завершения флаг освобождается через clear_bit_unlock()
  • Ожидающие потоки будятся через wake_up_all()

Это гарантирует, что reset-поток исключает sender от параллельного изменения состояния передачи.

Ссылки на исправления:


Временные меры защиты​


Пока обновление ядра не выполнено, можно снизить вероятность попадания в окно гонки.

  • Ограничить количество одновременных RDS TCP соединений
  • Уменьшить частоту reconnect и reset операций
  • Отключить или изолировать сервисы, использующие RDS, если они не критичны
  • Настроить мониторинг kernel log для быстрого обнаружения аномалий
  • Проверить, что модуль net/rds загружен только на системах, где он действительно нужен

Эти меры не устраняют уязвимость. Они лишь снижают вероятность одновременного выполнения reset и send потоков.

Если сервис RDS работает в production, приоритет — обновление ядра. Если это невозможно, ограничить доступ к RDS-интерфейсам и снизить нагрузку на TCP-reset пути.

Как проверить устранение уязвимости​


После обновления нужно подтвердить, что патч применён.

  • Проверить версию ядра: uname -r
  • Сверить версию с stable-веткой, содержащей commit 02c5f9dc2efd823e061954d564ce00bacd1bebeb или его backport
  • Проверить наличие функции test_and_set_bit_lock() в rds_tcp_reset_callbacks(): grep -n 'test_and_set_bit_lock' /lib/modules/$(uname -r)/kernel/net/rds/tcp.o если доступен исходный код или бинарник
  • Проверить, что модуль net/rds загружен: lsmod | grep rds
  • Провести функциональную проверку RDS TCP после обновления
  • Смотреть kernel log на отсутствие новых ошибок reset и socket lock

Команды:

Bash:
uname -r
grep -n 'test_and_set_bit_lock' /lib/modules/$(uname -r)/kernel/net/rds/tcp.o 2>/dev/null || echo "binary not available"
lsmod | grep rds
dmesg | grep -iE 'rds|tcp reset|socket lock'

Если патч не найден в ядре, нужно обновить дистрибуивный пакет kernel или применить backport от вендора.

Вывод​


CVE-2026-98070 — это race condition в Linux kernel внутри модуля net/rds. Уязвимость возникает из-за того, что старый код только ждал освобождения RDS_IN_XMIT, но не блокировал повторный захват другим потоком. На слаботранзакционных архитектурах это приводит к параллельному изменению состояния передачи и замене сокета.

Исправление уже опубликовано в stable tree Linux kernel. Оно заменяет wait_event() на test_and_set_bit_lock(), удерживает флаг RDS_IN_XMIT на протяжении критической секции и освобождает его с wake-up.

Для систем с RDS TCP это обновление нельзя откладывать: гонка может повредить состояние соединения, привести к потере данных или отказу ядра. Если точные версии дистрибутивов не раскрыты, нужно проверить версию ядра и наличие патча через stable-ветку.

Официальные источники​


  1. NVD — CVE-2026-98070
  2. net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks() - kernel/git/stable/linux.git - Linux kernel stable tree
  3. net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks() - kernel/git/stable/linux.git - Linux kernel stable tree
  4. net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks() - kernel/git/stable/linux.git - Linux kernel stable tree
  5. net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks() - kernel/git/stable/linux.git - Linux kernel stable tree
  6. CVEs — The Linux Kernel documentation

История обновлений статьи​


  • 29.09.2026 — Опубликована первая версия материала.
 
Назад
Верх Низ