CVE-2026-98056 в Linux Kernel: DoS через NVMe namespace scan и патч

CVE: CVE-2026-98056
Продукт: Linux Kernel
Дата публикации: 25.09.2026
Критичность: HIGH
CVSS: 7.5 (3.1)
EPSS: 0,60%; процентиль 46,71%
CISA KEV: нет подтверждения в каталоге CISA KEV

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


Уязвимость CVE-2026-98056 затрагивает драйвер NVMe в ядре Linux. Проблема возникает при сканировании списка namespace (NSID): если на контроллере есть разреженный диапазон NSID, функция nvme_scan_ns_list() выполняет итерацию по каждому NSID в промежутке, а не только по существующим namespace. Это может привести к многократному вызову nvme_find_get_ns() и загрузке CPU до soft lockup watchdog.

Патч заменяет поштучное удаление на диапазонный проход по отсортированному списку ctrl->namespaces.

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


Суть риска — зависание или сильная деградация работы ядра при обработке NVMe namespace с разреженным NSID пространством. Проблема не связана с утечкой данных, компрометацией памяти или обходом контроля доступа; она влияет на доступность подсистемы NVMe и может затрагивать весь узел, если soft lockup приводит к перезагрузке или блокировке CPU.

  • Тип ошибки: DoS через неограниченный цикл в драйвере NVMe (namespace list scan)
  • CVSS 3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — оценка 7.5, HIGH
  • Вектор атаки: удалённый доступ к NVMe контроллеру или возможность предоставить ядру список NSID с большим разреженным промежутком
  • Факт эксплуатации: в источниках не подтверждено; есть только описание механизма и патч
  • EPSS: 0,603% (percentile 46,71%) — вероятность активной эксплуатации в реальных атаках пока низкая

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


Затронуто ядро Linux с компонентом NVMe host driver. Конкретные версии ядра не перечислены в предоставленных источниках; патч присутствует в stable-ветках и связан с исходным commit 540c801c65eb ("NVMe: Implement namespace list scanning").


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

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


Ошибка в логике удаления устаревших namespace после сканирования списка NSID.

Функция nvme_scan_ns_list() обрабатывает промежутки между reported NSID. В исходной реализации для каждого NSID в промежутке вызывалась проверка и удаление через nvme_find_get_ns(). Если промежуток большой, а реальных namespace внутри нет, цикл выполняется по каждому NSID из 32-битного пространства.

NSIDs — это 32-битные значения. На контроллере с разреженным NSID пространством один промежуток может содержать миллиарды значений. Каждая итерация выполняет поиск в отсортированном списке namespace и при наличии удаляет объект. Если namespace нет, работа тратится на пустой поиск.

Патч заменяет поштучный проход на диапазонный: функция nvme_remove_nsid_range() принимает открытый интервал (start, end) и проходит по отсортированному списку ctrl->namespaces один раз, удаляя все namespace с NSID в диапазоне. Работа ограничивается количеством реально присутствующих namespace, а не размером промежуточного диапазона.

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


Атака использует саму возможность предоставить ядру список NSID с большим разреженным промежутком.

NVMe контроллер или внешний источник предоставляет ядру список namespace через log page LSI или аналогичный механизм namespace list scanning. Ядро сравнивает reported NSID и находит промежуток между предыдущим и следующим NSID.

В уязвимой версии nvme_scan_ns_list() запускает цикл по каждому NSID в промежутке. Для каждого NSID вызывается nvme_find_get_ns(), который ищет namespace в списке. Если промежуток содержит миллиарды значений, а реальных namespace мало или нет, CPU загружается на длительную работу.

Watchdog фиксирует soft lockup: watchdog: BUG: soft lockup - CPU#4 stuck for 26s!. Патч устраняет зависание за счёт замены цикла по NSID на один проход по отсортированному списку namespace с диапазоном (start, end).

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


Для воспроизведения эффекта DoS нужны следующие условия:

  • Система использует драйвер NVMe host.
  • NVMe контроллер подключён и ядро выполняет namespace list scan.
  • Контроллер или источник данных предоставляет список NSID с большим разреженным промежутком.
  • Промежуток содержит значительное количество NSID, при этом реальных namespace внутри мало или нет.
  • CPU не ограничен по времени работы в workqueue nvme-wq до того, как watchdog сработает.

В источниках не указано, что для атаки нужен локальный доступ, root или специальный контроллер. Вектор CVSS указывает удалённый доступ без привилегий и без взаимодействия пользователя: AV:N/AC:L/PR:N/UI:N/S:U.

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


Сценарий описан на уровне механизма ядра.

Удалённый или локальный субъект управляет NVMe контроллером или влияет на список NSID, который обрабатывает ядро. Контроллер возвращает список namespace с большим разрывом между NSID. Например, reported NSID могут быть 1 и 4294967295, а реальных namespace внутри нет.

Ядро переходит в nvme_scan_ns_list(), находит промежуток от 2 до 4294967294. В уязвимой версии цикл проходит по каждому NSID из этого диапазона. Каждая итерация вызывает nvme_find_get_ns() и при необходимости удаляет namespace. Если namespace нет, работа тратится на пустой поиск.

CPU остаётся занят в workqueue nvme-wq в функции nvme_scan_work. После 26 секунд watchdog фиксирует soft lockup. Система может зависнуть, перезагрузиться или потерять доступность подсистемы NVMe.

После применения патча промежуток обрабатывается одним вызовом nvme_remove_nsid_range(ctrl, prev, nsid) или nvme_remove_nsid_range(ctrl, nn, UINT_MAX). Проход по списку останавливается при достижении конца диапазона.

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


В предоставленных источниках нет отдельного PoC, эксплойта или подтверждения реальной эксплуатации.

Есть:

  • техническое описание уязвимости;
  • call trace с soft lockup;
  • патч в stable tree;
  • CVSS и EPSS.

Отсутствие сведений о публичном эксплойте не означает, что его нет. Для оценки риска опирайтесь на механизм: если вы управляете NVMe контроллером или можете влиять на namespace list, DoS воспроизводим через разреженный NSID диапазон.

Для проверки наличия патча используйте git log и поиск по commit hash.

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


Специфичных IOC для этой уязвимости в источниках нет. Ниже приведены неспецифичные признаки, которые можно использовать как общие точки контроля.

  • Soft lockup в kernel log: watchdog: BUG: soft lockup - CPU#4 stuck for 26s!
  • Workqueue: nvme-wq nvme_scan_work [nvme_core]
  • Call trace:

    Код:
    nvme_find_get_ns+0x7d/0xb0 [nvme_core]
    nvme_scan_ns_list+0xe8/0x280 [nvme_core]
    nvme_scan_work+0x18a/0x280 [nvme_core]
    process_one_work+0x197/0x380
    worker_thread+0x2fe/0x410
    kthread+0xe0/0x100
  • RIP: __srcu_read_unlock+0xb/0x20
  • Длительная загрузка CPU во время NVMe scan или после подключения контроллера.
  • Отсутствие namespace в списке, но высокий CPU usage в nvme_scan_work.

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

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


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

  • Проверка kernel log:

    Bash:
    grep -i "soft lockup" /var/log/kern.log
    dmesg | grep -i "soft lockup"
  • Поиск call trace:

    Bash:
    grep -A 10 "nvme_scan_work" /var/log/kern.log
  • Проверка NVMe контроллеров:

    Bash:
    lsblk -o NAME,TYPE,SIZE,MODEL
    nvme list
  • Мониторинг CPU по процессам и workqueue:

    Bash:
    top -H -p $(pidof nvme)
    cat /proc/$(pidof nvme)/stack
  • Проверка наличия патча:

    Bash:
    git log --oneline | grep "nvme: remove stale namespaces by NSID range during scan"

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

  • Debian/Ubuntu:

    Bash:
    apt list --installed 2>/dev/null | grep linux-image
  • RHEL/CentOS/Fedora:

    Bash:
    rpm -qa | grep kernel-core

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


Проверка версии ядра и наличия патча.

  • Текущая версия ядра:

    Bash:
    uname -r
  • Полная информация о ядре:

    Bash:
    uname -a
  • Альтернативный источник версии:

    Bash:
    cat /proc/version
  • Поиск патча в git tree (если есть исходники):

    Bash:
    git log --oneline | grep "nvme: remove stale namespaces by NSID range during scan"
  • Проверка commit hash в stable:

    Bash:
    git log --all --grep="4ed7f3d7d435bf5b63da2814dc9270f5ba896011"
  • Проверка через дистрибутив:

    Bash:
    apt list --installed | grep linux-image
    rpm -qa kernel-core

Если патч отсутствует, а NVMe контроллер подключён, система уязвима к DoS через разреженный NSID диапазон.

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


Основное исправление — применение патча из stable tree.


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

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


Временные меры снижают вероятность срабатывания DoS, но не устраняют уязвимость.

  • Отключить NVMe контроллер, если он не используется:

    Bash:
    echo 1 > /sys/bus/pci/devices/<BDF>/remove

    Замените <BDF> на реальный адрес PCI устройства, например 0000:02:00.0.
  • Ограничить namespace list scanning через параметры ядра или драйвер (если доступны в вашей версии).
  • Использовать NVMe контроллер с плотным NSID пространством, если это возможно.
  • Мониторить soft lockup и перезагружать систему при обнаружении.
  • Ограничить доступ к NVMe на уровне сети или хоста, если контроллер доступен удалённо.

Эти меры не заменяют патч. Они снижают поверхность атаки и дают время на обновление.

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


После применения патча проверьте:

  • Версия ядра:

    Bash:
    uname -r
  • Наличие патча в git log:

    Bash:
    git log --oneline | grep "nvme: remove stale namespaces by NSID range during scan"
  • Отсутствие soft lockup в journal:

    Bash:
    journalctl -k | grep -i "soft lockup"
  • Проверка NVMe namespace list:

    Bash:
    nvme list
    lsblk -o NAME,TYPE,SIZE,MODEL
  • Тестирование под нагрузкой (если возможно):

    Bash:
    fio --name=nsid_test --rw=randwrite --bs=4k --size=1g --numjobs=4 --runtime=60 --output=file --output_file=fio_result.txt

    Замените параметры под вашу систему. Если после теста нет soft lockup и CPU не загружается на длительную работу, патч работает.

Если патч отсутствует в вашей ветке stable, обратитесь к дистрибутиву или используйте upstream commit.

Вывод​


CVE-2026-98056 — это DoS уязвимость в NVMe namespace list scanning. Проблема возникает при обработке разреженного NSID диапазона и приводит к многократному вызову nvme_find_get_ns() до soft lockup.

Патч заменяет поштучный проход на диапазонный, что ограничивает работу количеством реальных namespace. Для администратора главное — проверить версию ядра, наличие патча и мониторинг kernel log.

Если NVMe контроллер подключён и используется, обновите ядро до версии с патчем. Если обновление невозможно, отключите контроллер или ограничьте доступ к нему.

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


  1. NVD — CVE-2026-98056
  2. FIRST EPSS — CVE-2026-98056
  3. nvme: remove stale namespaces by NSID range during scan - kernel/git/stable/linux.git - Linux kernel stable tree
  4. nvme: remove stale namespaces by NSID range during scan - kernel/git/stable/linux.git - Linux kernel stable tree
  5. nvme: remove stale namespaces by NSID range during scan - kernel/git/stable/linux.git - Linux kernel stable tree
  6. nvme: remove stale namespaces by NSID range during scan - kernel/git/stable/linux.git - Linux kernel stable tree
  7. CVEs — The Linux Kernel documentation

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


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