ZeroHour

CVE-2026-89968

niche

Unauthenticated Remote DoS in Linux Kernel nvmet-tcp Target (Missing R2T Check)

CVSS 3.1
7.5 high
EPSS
Published
()
Modified
AI analysis

The Linux kernel's nvmet-tcp (NVMe over Fabrics TCP) target accepts a host-to-controller data PDU (H2CData) after only validating its tag and buffer mapping, without verifying that the target actually solicited the data by sending a Ready To Transfer (R2T) message. A remote host can exploit this by submitting a write command that takes the R2T path and sending an unsolicited H2CData PDU for that command before the target transmits the R2T, causing the command to complete twice and its response node to be added to the queue's response list twice. The result is either a kernel BUG on the 'list_add double add' check (CONFIG_DEBUG_LIST builds) or an infinite loop that wedges the nvmet_tcp workqueue as a soft-lockup, i.e., a remote denial of service with no confidentiality or integrity impact. Any Linux system configured as an nvmet-tcp target on a network reachable by the attacker is affected, and no authentication is required on subsystems configured with allow_any_host. No public proof-of-concept is known, the issue is not in CISA KEV, and there are no reports of exploitation in the wild.

What to do: Apply the kernel update containing the nvmet-tcp fix (rejecting unsolicited H2CData PDUs) as soon as it is available for your distribution. Until patched, restrict access to NVMe/TCP target ports (default 4420/TCP) with firewall rules or host ACLs and avoid allow_any_host on subsystems reachable from untrusted networks. Verify whether you are affected by checking for loaded nvmet and nvmet_tcp modules and configured nvmet ports on potential target systems.

Affected
Linux kernel nvmet-tcp (NVMe over Fabrics TCP target subsystem)
Estimated exposure
nichelikely low thousands of nvmet-tcp target hosts worldwide, mostly on internal storage networks; internet-exposed instances probably only hundreds or fewer — nvmet-tcp is a specialized data-center storage deployment typically isolated from the internet, and public scans of the NVMe/TCP default port 4420 show limited exposure; the exact installed base is unknown, so this is an order-of-magnitude…

Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.

Description

In the Linux kernel, the following vulnerability has been resolved: nvmet-tcp: reject unsolicited H2CData PDUs nvmet_tcp_handle_h2c_data_pdu() accepts an H2CData PDU after only checking that its TTAG is a valid in-range command index and that the command's data buffers are mapped. It never checks that the target has actually solicited that data by sending an R2T for the command. A remote host can abuse this. It submits a write command that takes the R2T path and, before the target transmits the R2T, sends an H2CData PDU for that command's tag. The data completes the command early, and when the command then fails synchronously (e.g. a length mismatch caught by nvmet_check_transfer_len()), it is completed a second time. Each completion calls nvmet_tcp_queue_response(), so the same command is added to queue->resp_list twice while it is still linked; the second llist_add() makes the node point to itself (lentry->next == lentry). nvmet_tcp_process_resp_list() then walks that self-referential node and adds the command to resp_send_list twice. With CONFIG_DEBUG_LIST this trips the "list_add double add" check (kernel BUG); without it the loop never terminates and the nvmet_tcp workqueue wedges (soft-lockup). It is remotely triggerable and needs no authentication on an allow_any_host subsystem. Track whether an R2T has been transmitted for a command and reject an H2CData PDU that arrives before it. The flag is cleared on command reuse (nvmet_tcp_get_cmd() zeroes cmd->flags) and stays set across the multiple H2CData PDUs of a single solicited transfer.

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

In the news

No ingested article mentions this CVE yet.