ZeroHour

CVE-2026-89973

large

Linux kernel nvme-tcp C2HData direction flaw allows controller-triggered WARNING DoS

CVSS 3.1
8.2 high
EPSS
Published
()
Modified
AI analysis

The Linux kernel's nvme-tcp initiator fails to verify the data direction of an incoming C2HData PDU: nvme_tcp_handle_c2h_data() locates the request by command ID and checks it has a payload, but never confirms the command was actually a read. A malicious, compromised, or buggy NVMe/TCP controller can therefore answer a write command with C2HData, sending the receive path into _copy_to_iter() on a write-oriented iterator where WARN_ON_ONCE fires and the copy returns zero, failing the command with -EFAULT and resetting the controller. No data is copied, so there is no memory corruption; what an attacker gains is a remotely triggerable kernel WARN on demand, which is a full host crash on systems booted with panic_on_warn and repeated controller resets (availability loss) otherwise. Only Linux systems running the nvme-tcp (NVMe over Fabrics TCP) initiator against a controller they do not fully trust are affected. No public proof-of-concept or in-the-wild exploitation is known; the flaw was fixed by adding a direction check that rejects non-read C2HData PDUs.

What to do: Apply the upstream kernel fix ('nvme-tcp: check the data direction of a C2HData PDU') via your distribution's kernel update as soon as it is released. Until then, restrict NVMe/TCP (TCP port 4420) to trusted storage networks, avoid connecting nvme-tcp initiators to untrusted or third-party controllers, and review whether panic_on_warn is enabled on storage hosts, where this bug is fatal. Monitor host logs for repeated 'nvme nvme0: queue ... failed to copy request' / 'receive failed: -14' messages, which indicate a controller sending malformed C2HData.

Affected
Linux kernel nvme-tcp driver (NVMe over Fabrics TCP initiator)Exact affected ranges not enumerated in the advisory; issue exists in nvme-tcp code prior to the fix commit (the reported warning was reproduced on a 7.2.0-rc5
Estimated exposure
largeorder of 10,000-100,000 enterprise/data-center hosts with active NVMe/TCP initiator sessions; effectively zero internet-exposed instances — nvme-tcp ships in mainline kernels and is a mainstream transport for enterprise all-flash arrays and storage fabrics, but triggering requires an established initiator session with a malicious or compromised controller, which exists mainly…

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: nvme-tcp: check the data direction of a C2HData PDU nvme_tcp_handle_c2h_data() finds the request by command id and checks that it has a payload, but it does not check that the command asked for data to be read. A controller that answers a write command with C2HData therefore reaches nvme_tcp_recv_data(), where _copy_to_iter() hits WARN_ON_ONCE(i->data_source) and returns 0. The receive path turns that into -EFAULT and resets the controller. No data is copied, so this is not memory corruption. What a controller gets is a kernel warning it can raise at will, which is fatal on a host booted with panic_on_warn. The send path already knows the direction - it consults rq_data_dir() when it builds a command - and nvme_tcp_handle_r2t() checks the length and the offset of the request it names. The C2HData path does not check the direction at all. Reject a C2HData PDU whose command is not a read. Rejecting it fails the command and resets the controller, as the neighbouring check in this function does; what goes away is the warning. [ 6.885580] ------------[ cut here ]------------ [ 6.886457] WARNING: lib/iov_iter.c:193 at _copy_to_iter+0x289/0x1330, CPU#0: kworker/0:1H/71 [ 6.888137] CPU: 0 UID: 0 PID: 71 Comm: kworker/0:1H Not tainted 7.2.0-rc5-NVMETCP-gf5098b6bae76 #1 PREEMPT(lazy) [ 6.891165] Workqueue: nvme_tcp_wq nvme_tcp_io_work [ 6.891875] RIP: 0010:_copy_to_iter+0x289/0x1330 [ 6.903739] Call Trace: [ 6.904085] [ 6.909254] __skb_datagram_iter+0x433/0x820 [ 6.911026] skb_copy_datagram_iter+0x37/0x120 [ 6.911622] nvme_tcp_recv_skb+0xa07/0x4320 [ 6.913378] __tcp_read_sock+0x1ab/0x810 [ 6.915788] nvme_tcp_try_recv+0x152/0x1e0 [ 6.918222] nvme_tcp_io_work+0x1e4/0x6c0 [ 6.926906] [ 6.927226] ---[ end trace 0000000000000000 ]--- [ 6.927878] nvme nvme0: queue 1 failed to copy request 0x71 data [ 6.928709] nvme nvme0: receive failed: -14

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

In the news

No ingested article mentions this CVE yet.