[PATCH 0/5] nvmet: fix stale data exposure and ZNS validation
From: Andrea Parri
Date: Mon Oct 12 2026 - 10:41:59 EST
A connected host can currently receive stale target memory through three
nvmet paths.
The FC transport sends a read buffer even when the command completes with
an error. Some errors occur before the command handler initializes that
buffer, so the host receives data left in the allocation.
Zone Management Receive writes only the Number of Zones field and the
descriptors returned by the backend, while the transports send the entire
requested buffer. Reserved header bytes and unused descriptor slots can
therefore retain stale data. The handler also does not verify that the
transport data length agrees with NUMD, allowing a host to increase the
amount returned beyond the size described by the command.
The PCI endpoint transport allocates each read segment at the length of
the host's SGL data descriptor and sends every segment in full, even when
the descriptors describe more than the command transfers. The excess
reaches the host uninitialized, on any successful read.
Patch 1 makes the FC transport send read data only for successful
commands, matching the TCP and RDMA transports. Patch 2 validates the
Zone Management Receive transfer length and zeroes the report before
filling it. Patch 3 rejects NUMD values whose byte count wraps the u32
length calculation instead of accepting the wrapped request.
Patch 4 fixes a related PCI endpoint bug that patch 5 depends on. The
transport reports every error it detects itself as a successful
completion, because nvmet_pci_epf_complete_iod() reloads the status from
a CQE that only the nvmet core fills in, so even a write whose data
could not be fetched is reported as written. Patch 5 then makes the
transport reject SGLs whose data descriptors do not add up to the
command's data length.
Patches 1-3 were tested over the loop, tcp, rdma (rdma_rxe) and fc
(fcloop) transports, with a zoned null_blk namespace for the Zone
Management Receive fixes. On the unpatched kernel, a failed Identify over
fc returns data, zone reports carry stale bytes and accept a transfer
length that disagrees with NUMD, and a wrapping NUMD is accepted. With
patches 1-3 applied, none of these occur on any of the four transports.
Patches 4 and 5 are build-tested only: no PCI endpoint hardware was
available.
A tested reproducer for patches 1-3 is available privately on request.
Andrea Parri (5):
nvmet-fc: only send read data for successful commands
nvmet: zns: don't leak stale memory in zone management receive
nvmet: zns: reject a NUMD whose byte count wraps
nvmet: pci-epf: report transport errors in command completions
nvmet: pci-epf: require SGLs to match the command data length
drivers/nvme/target/fc.c | 8 ++++----
drivers/nvme/target/pci-epf.c | 30 +++++++++++++++++++++++++++---
drivers/nvme/target/zns.c | 17 +++++++++++++++--
3 files changed, 46 insertions(+), 9 deletions(-)
base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
--
2.53.0