CVE-2026-89857 в Linux Kernel: race condition в qla2xxx NVMe LS reject и последствия для I/O

CVE: CVE-2026-89857
Продукт: Linux Kernel
Дата публикации: 16.09.2026
Критичность: CRITICAL
CVSS: 9.8 (3.1)
EPSS: 0,62%; процентиль 48,22%
CISA KEV: нет подтверждения в каталоге CISA KEV

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


Уязвимость CVE-2026-89857 затрагивает драйвер SCSI qla2xxx в ядре Linux. Функция qla_nvme_ls_reject_iocb() работает с request ring без блокировки, тогда как два её вызывающих кода могут выполняться одновременно с обычным I/O.

Это приводит к повреждению состояния ring producer и дублированию или потере команд. Для администратора практическое значение состоит в том, что система с qla2xxx и включённым NVMe-FC может терять данные или зависать при высокой нагрузке на storage.

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


Риск связан с гонкой в драйвере qla2xxx ядра Linux. При обработке NVMe LS reject два кода вызывают функцию без блокировки, которая меняет ring и doorbell одновременно с обычным I/O.

  • Тип ошибки: race condition / missing lock в драйвере qla2xxx
  • CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H, 9.8 CRITICAL
  • Вектор атаки: удалённый, без привилегий, без взаимодействия с пользователем
  • Факт эксплуатации: в источниках не подтверждено; есть только описание ошибки и патч
  • EPSS: 0,62% (percentile 48,22%)

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


Затронут Linux Kernel с драйвером qla2xxx, где включена поддержка NVMe over Fibre Channel.

  • Ядро Linux с подсистемой SCSI qla2xxx
  • Конфигурация CONFIG_NVME_FC или эквивалентная включённая поддержка NVMe-FC
  • Системы с контроллерами Marvell/Avnet, использующими qla2xxx как storage driver
  • Версии ядра до применения патча f743488e4a203049f27ec5d8cd0caccc483af01e и его stable backports

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


Функция qla_nvme_ls_reject_iocb() вызывает __qla2x00_alloc_iocbs() и qla2x00_start_iocbs(). Обе функции предполагают, что hardware_lock удерживается вызывающим кодом.

Сам qla_nvme_ls_reject_iocb() блокировку не берёт. Два из трёх вызывающих кодов работают без неё:

  • qla_nvme_xmt_ls_rsp() — NVMe-FC transport callback на error path
  • qla2xxx_process_purls_pkt() — purex work/DPC context

Оба используют ha->base_qpair, где qp_lock_ptr указывает на hardware_lock. Поэтому они могут выполняться одновременно с обычным I/O submission на base ring.

Третий вызывающий код, qla2xxx_process_purls_iocb(), работает внутри qla24xx_process_response_queue() с уже удерживаемой qpair lock и безопасен. Именно поэтому блокировку нельзя ставить внутрь helper: это привело бы к рекурсивному повторному захвату hardware_lock на response path.

Решение — обернуть два неблокированных вызова в spin_lock_irqsave() / spin_unlock_irqrestore() вокруг qp_lock_ptr и задокументировать helper как caller-locked.

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


Атака не требует отдельного эксплойта в смысле пользовательского кода. Она возникает из внутренней гонки драйвера.

Сценарий: система обрабатывает NVMe LS reject одновременно с обычным I/O на base ring. Один поток вызывает qla_nvme_ls_reject_iocb() без блокировки, другой — обычный I/O submission через те же структуры ring.

__qla2x00_alloc_iocbs() выделяет IOCБ и двигает указатель ring. qla2x00_start_iocbs() двигает ring и генерирует request-in doorbell. Если два потока делают это одновременно, состояние producer ring повреждается.

Последствия:

  • дублирование команд на hardware
  • потеря команд
  • некорректный порядок обработки I/O
  • зависание storage или деградация производительности

Вектор CVSS показывает удалённый доступ без привилегий, но практическая реализация зависит от загрузки системы и наличия NVMe-FC traffic. В источниках нет подтверждения, что атака может быть использована для произвольного выполнения кода; описанное следствие — повреждение ring state и потеря/дублирование команд.

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


Для воспроизведения ошибки нужны следующие условия:

  • установлен драйвер qla2xxx в ядре Linux
  • включена поддержка NVMe over Fibre Channel (CONFIG_NVME_FC)
  • система использует base_qpair qla2xxx для NVMe LS reject
  • есть одновременная обработка NVMe LS reject и обычного I/O submission
  • нет блокировки qp_lock_ptr вокруг вызова qla_nvme_ls_reject_iocb() в двух уязвимых путях

В источниках не указано, что требуется внешний атакующий для создания нагрузки. Гонка может возникать при внутренней работе драйвера, но практическая частота зависит от трафика NVMe-FC и I/O.

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


Система с qla2xxx обрабатывает storage I/O.

В этот момент приходит NVMe LS reject или ошибка transport callback. Драйвер вызывает qla_nvme_ls_reject_iocb() без захвата hardware_lock.

Одновременно обычный I/O поток отправляет команды на base ring через те же функции аллокации и старта IOCБ.

Оба потока пишут в один и тот же request ring: один двигает producer pointer, другой — doorbell. Состояние ring становится неконсистентным.

Результат:

  • hardware получает дублированные или пропущенные команды
  • ядро теряет учёт некоторых I/O операций
  • storage subsystem может зависнуть или начать возвращать ошибки

В источниках нет описания внешнего сценария с конкретными командами атакующего. Описанная проблема — внутренняя гонка драйвера, которая проявляется при определённых условиях нагрузки.

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


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

Есть:

  • описание ошибки в ядре Linux
  • патч с диффом и commit hash f743488e4a203049f27ec5d8cd0caccc483af01e
  • stable backports: 11834e5773e20fd3742d7eb900876e66b9e7d029, 7eb618877503edbf17aa65e357a81bda1fc8f163, b02ff132017b28222187ebcf95ce7f4cb576cd36, b3a362466db6b8ec47cc537ac641ac197fa69b5d

Отсутствие PoC в источниках не означает, что эксплойт невозможен. Описанная гонка может воспроизводиться при соответствующей нагрузке, но конкретные условия и команды проверки не приведены в предоставленных данных.

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


Специфичных IOC для этой уязвимости в источниках нет.

Неспецифичные точки контроля:

  • ошибки qla2xxx в dmesg или /var/log/messages
  • сообщения о lost I/O, timeout, reset на storage controller
  • аномальные задержки при работе NVMe over Fibre Channel
  • дублирование или потеря команд в trace/audit storage subsystem
  • рост числа ошибок SCSI/NVMe в iostat, sar, smartctl или vendor tools

Эти признаки не являются подтверждёнными IOC именно для CVE-2026-89857. Они подходят для общей диагностики проблем qla2xxx и NVMe-FC.

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


Проверка версии ядра и драйвера:

Bash:
uname -r
uname -a
cat /proc/version

Если версия ниже stable backport, система потенциально уязвима.

Дополнительные проверки:

  • наличие qla2xxx в lsmod или /sys/module/qla2xxx//sys/bus/scsi/drivers/qla2xxx
  • включённость NVMe-FC: grep CONFIG_NVME_FC /boot/config-$(uname -r)
  • ошибки драйвера: dmesg | grep -i qla2xxx, journalctl -k | grep -i qla2xxx
  • I/O errors: smartctl -a /dev/sdX или vendor-specific logs

В источниках нет отдельного детектора. Проверка ограничена версией ядра, наличием драйвера и симптомами в логах.

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


Команды проверки версии ядра:

Bash:
uname -r
uname -a
cat /proc/version

Проверка наличия qla2xxx:

Bash:
lsmod | grep qla2xxx

Проверка конфигурации NVMe-FC:

Bash:
grep CONFIG_NVME_FC /boot/config-$(uname -r)

Если uname -r показывает версию, не содержащую stable backport, и драйвер qla2xxx с NVMe-FC включён, система требует обновления.

В источниках нет точного списка версий ядра до исправления. Есть только commit hash upstream fix и stable commits.

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


Основное исправление — применение патча f743488e4a203049f27ec5d8cd0caccc483af01e или его stable backport.

Stable commits:


Практические шаги:

  • обновить ядро до версии, содержащей stable backport
  • если distribution не выпустило обновление, применить патч вручную или использовать vendor kernel
  • после обновления перезагрузить систему
  • проверить отсутствие ошибок qla2xxx в логах после нагрузки

В источниках нет конкретных версий дистрибутивов. Обновление должно соответствовать политике вашей системы.

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


Точных временных обходных путей в источниках нет.

Неспецифичные меры снижения риска:

  • снизить нагрузку на NVMe-FC, если это возможно
  • ограничить количество одновременных I/O операций на qla2xxx base_qpair
  • отключить NVMe-FC, если storage не критичен и есть альтернативный путь
  • обновить ядро как можно раньше
  • мониторить ошибки qla2xxx и I/O errors после изменений нагрузки

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

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


После обновления проверьте:

Bash:
uname -r
cat /proc/version

Убедитесь, что версия содержит stable backport.

Проверка наличия qla2xxx и NVMe-FC:

Bash:
lsmod | grep qla2xxx
grep CONFIG_NVME_FC /boot/config-$(uname -r)

Проверка логов после нагрузки:

Bash:
dmesg | grep -i qla2xxx
journalctl -k --since "1 hour ago" | grep -iE 'qla2xxx|nvme|scsi'
iostat -x 1 5

Если ошибки не появляются при нагрузке, исправление работает. В источниках нет автоматического способа подтвердить отсутствие гонки; только отсутствие ошибок и стабильная работа I/O.

Вывод​


CVE-2026-89857 — это race condition в драйвере qla2xxx Linux Kernel. Функция qla_nvme_ls_reject_iocb() работает без блокировки, хотя изменяет request ring и doorbell. Два вызывающих кода могут конфликтовать с обычным I/O, что приводит к повреждению состояния ring producer.

Для администратора это означает риск потери или дублирования команд на storage, зависаний и деградации производительности. Практическая защита — обновление ядра до версии со stable backport патча f743488e4a203049f27ec5d8cd0caccc483af01e.

В источниках нет подтверждённой эксплуатации, PoC или конкретных версий дистрибутивов. Есть только описание ошибки, патч и stable commits.

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


  1. NVD — CVE-2026-89857
  2. FIRST EPSS — CVE-2026-89857
  3. scsi: qla2xxx: Hold qpair lock when sending NVMe LS reject - kernel/git/stable/linux.git - Linux kernel stable tree
  4. scsi: qla2xxx: Hold qpair lock when sending NVMe LS reject - kernel/git/stable/linux.git - Linux kernel stable tree
  5. scsi: qla2xxx: Hold qpair lock when sending NVMe LS reject - kernel/git/stable/linux.git - Linux kernel stable tree
  6. scsi: qla2xxx: Hold qpair lock when sending NVMe LS reject - kernel/git/stable/linux.git - Linux kernel stable tree
  7. scsi: qla2xxx: Hold qpair lock when sending NVMe LS reject - kernel/git/stable/linux.git - Linux kernel stable tree
  8. CVEs — The Linux Kernel documentation

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


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