CVE-2026-89482: nvme-tcp: do not accept C2HData based on blk_rq_payload_bytes() alone
In the Linux kernel, the following vulnerability has been resolved:
nvme-tcp: do not accept C2HData based on blkrqpayloadbytes() alone
Commit 25e5cb780e62 ("nvme-tcp: fix possible crash in writezeroes processing") established that blkrqpayloadbytes() must not be read without first checking blkrqnrphyssegments(), and recorded the result in nvmetcpsetupcmdpdu() as req->datalen. The receive side was left as it was.
The two differ for REQOPWRITEZEROES, which has no physical segments but a non-zero blkrqbytes(), so setup leaves req->iter untouched while the receive gate lets a C2HData through and nvmetcprecvdata() copies into whatever the previous command on that tag left there. The driver-private area is zeroed only when the tag set is allocated.
Reproduced with a test target that leaves a residual iterator on a tag and then sends a C2HData for a WRITEZEROES command on the same tag:
BUG: KASAN: wild-memory-access in copytoiter+0x642/0x1330 Write of size 512 at addr ffe728c2175dfa81 by task kworker/0:1H/103
CPU: 0 UID: 0 PID: 103 Comm: kworker/0:1H Not tainted 7.2.0-rc5-NVMETCP-gf5098b6bae76 #1 PREEMPT(lazy) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, archcaps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Workqueue: nvmetcpwq nvmetcpiowork Call Trace: <TASK> dumpstacklvl+0x53/0x70 kasanreport+0xce/0x100 ? copytoiter+0x642/0x1330 kasancheckrange+0x105/0x1b0 asanmemcpy+0x3c/0x60 copytoiter+0x642/0x1330 ? pfxsockhasperm+0x10/0x10 ? workerthread+0x45b/0xd10 ? pfxcopytoiter+0x10/0x10 ? rawspinlockbh+0x83/0xe0 ? pfxrawspinlockbh+0x10/0x10 skbdatagramiter+0xf3/0x820 ? pfxsimplecopytoiter+0x10/0x10 ? asanmemcpy+0x3c/0x60 ? skbcopybits+0x58d/0x830 skbcopydatagramiter+0x37/0x120 nvmetcprecvskb+0xa07/0x4320 ? pfxnvmetcprecvskb+0x10/0x10 tcpreadsock+0x1ab/0x810 ? pfxnvmetcprecvskb+0x10/0x10 ? pfxlocksocknested+0x10/0x10 ? pfxtcpreadsock+0x10/0x10 nvmetcptryrecv+0x152/0x1e0 ? pfxnvmetcptryrecv+0x10/0x10 ? pfxmutexunlock+0x10/0x10 nvmetcpiowork+0x1e4/0x6c0 ? schedule+0x181a/0x49f0 ? pfxnvmetcpiowork+0x10/0x10 processonework+0x633/0x1030
Keep the blkrqpayloadbytes() test and add req->datalen to it. The old test is what rejects a C2HData naming a tag that is no longer in flight, because blkupdaterequest() zeroes rq->datalen on completion; req->datalen and req->currbio are driver-private and survive completion, so they cannot stand in for it. Setup initialises the iterator only when both req->currbio and req->datalen are set, so the gate now tests the same two.
Affected Software
Event History
Frequently Asked Questions
Which systems are realistically exposed to this issue?
Linux systems using the nvme-tcp driver are exposed when communicating with an NVMe/TCP target that can send C2HData responses. The reproduced case requires reuse of a command tag whose prior command left a residual iterator.
What does an attacker need to send to trigger the fault?
The target must send C2HData for a REQ_OP_WRITE_ZEROES command on a reused tag. WRITE_ZEROES has no physical segments but can have non-zero request bytes, allowing the receive path to copy data through an iterator left by an earlier command.
How could an affected system be identified?
The reported reproduction produces a KASAN wild-memory-access report in _copy_to_iter, involving a write of 512 bytes from an nvme-tcp receive worker. Testing requires a target that leaves a residual iterator on a tag and then sends C2HData for WRITE_ZEROES on that same tag.
Is there a documented configuration workaround if patching cannot happen immediately?
No configuration-based workaround is provided in the available data. Reducing exposure requires avoiding NVMe/TCP targets that could send the crafted C2HData sequence until the available fixes are applied.