CVE-2026-89857 PUBLISHED

scsi: qla2xxx: Hold qpair lock when sending NVMe LS reject

Assigner: Linux
Reserved: 11.09.2026 Published: 16.09.2026 Updated: 16.09.2026

In the Linux kernel, the following vulnerability has been resolved:

scsi: qla2xxx: Hold qpair lock when sending NVMe LS reject

qla_nvme_ls_reject_iocb() allocates from and advances the request ring through __qla2x00_alloc_iocbs() (which assumes the hardware_lock is held) and qla2x00_start_iocbs() (which advances the ring and rings the request-in doorbell), but takes no lock itself. Two of its callers invoke it without the producer lock held:

  • qla_nvme_xmt_ls_rsp(), the NVMe-FC .xmt_ls_rsp transport callback, on its error path, and

  • qla2xxx_process_purls_pkt(), run from the purex work/DPC context.

Both use ha->base_qpair, whose qp_lock_ptr is hardware_lock, so they can run concurrently with normal I/O submission on the base ring and corrupt the ring producer state, leading to duplicated or dropped commands. The third caller, qla2xxx_process_purls_iocb(), runs inside qla24xx_process_response_queue() with the qpair lock already held and is safe; that is also why the lock cannot be taken inside the helper itself (it would recursively re-acquire hardware_lock on the response path).

Take qp_lock_ptr around the two unlocked callers and document the helper as caller-locked. Both run in process context, so spin_lock_irqsave() is used and nothing in the locked region sleeps.

Metrics

CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 9.8

AV:N - Unsolicited NVMe-FC LS frames are posted as PT_LS4_UNSOL and reach qla2xxx_process_purls_pkt and qla_nvme_xmt_ls_rsp from a remote SAN peer. QLogic CNAs speak FCoE and fabrics are stretched via FCIP/inter-fabric routing, so a compromised target delivers those frames over the storage network with no local syscall. AC:L - A malicious NVMe-FC peer drives both base_qpair producers: LS that fail nvme_fc_rcv_ls_req or xmt_ls_rsp take unlocked qla_nvme_ls_reject_iocb, while concurrent accepted LS (or host NVMe LS/ELS via qla2x00_start_sp on the same qpair from qla2x00_get_sp) take the locked path. The attacker can flood and retry those frames. PR:N - Unsolicited NVMe-FC Link Service frames are handled from a logged-in fabric N_Port with no Linux user, capability, or authentication check on the LS-reject path. FC-SP/EDIF is opt-in; zoning is network access, not privileges on the victim host. UI:N - The HBA response-queue interrupt, DPC PROCESS_PUREX_IOCB path, and nvme_fc workqueue process unsolicited LS and emit the reject IOCB automatically; no victim mount, open, or other interactive action is required. S:U - Request-ring producer corruption and any resulting kernel or adapter failure stay inside the host kernel that owns the qla2xxx driver and do not cross a VM, IOMMU, or other separate security-authority boundary. C:H - Unlocked __qla2x00_alloc_iocbs/qla2x00_start_iocbs racing a locked producer can overwrite one ring slot and doorbell an extra stale slot. Firmware then DMA-executes leftover IOCBs whose addresses and handles may already have been recycled, a use-after-free/DMA-confusion read of kernel or I/O buffers. I:H - The same stale-slot replay and double-doorbell let firmware rewrite recycled DMA buffers or complete the wrong outstanding_cmds handle, including a second scsi_done/sp->done on a reused SRB, which is a kernel write and control-flow hijack primitive rather than only dropped I/O. A:H - Corrupted request-ring producer state duplicates or drops commands as the fix describes, desynchronizes firmware completions, and can oops on a bad handle or hang NVMe/SCSI I/O, taking down storage served by the adapter.

Product Status

Vendor Linux
Product Linux
Versions Default: unaffected
  • affected from 875386b98857822b77ac7f95bdf367b70af5b78c to 7eb618877503edbf17aa65e357a81bda1fc8f163 (excl.)
  • affected from 875386b98857822b77ac7f95bdf367b70af5b78c to b3a362466db6b8ec47cc537ac641ac197fa69b5d (excl.)
  • affected from 875386b98857822b77ac7f95bdf367b70af5b78c to 11834e5773e20fd3742d7eb900876e66b9e7d029 (excl.)
  • affected from 875386b98857822b77ac7f95bdf367b70af5b78c to b02ff132017b28222187ebcf95ce7f4cb576cd36 (excl.)
  • affected from 875386b98857822b77ac7f95bdf367b70af5b78c to f743488e4a203049f27ec5d8cd0caccc483af01e (excl.)
Vendor Linux
Product Linux
Versions Default: affected
  • Version 6.6 is affected
  • unaffected from 0 to 6.6 (excl.)
  • unaffected from 6.6.157 to 6.6.* (incl.)
  • unaffected from 6.12.110 to 6.12.* (incl.)
  • unaffected from 6.18.51 to 6.18.* (incl.)
  • unaffected from 7.2.5 to 7.2.* (incl.)
  • unaffected from 7.3-rc1 to * (incl.)

References