From: Andrea Parri <parri.andrea@gmail.com>
To: Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>,
Chaitanya Kulkarni <kch@nvidia.com>
Cc: Andrea Parri <parri.andrea@gmail.com>,
Damien Le Moal <dlemoal@kernel.org>,
linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH 3/5] nvmet: zns: reject a NUMD whose byte count wraps
Date: Mon, 12 Oct 2026 16:12:30 +0200 [thread overview]
Message-ID: <20261012141239.156408-4-parri.andrea@gmail.com> (raw)
In-Reply-To: <20261012141239.156408-1-parri.andrea@gmail.com>
Zone Management Receive computes its buffer size as (numd + 1) << 2 in
u32, in nvmet_bdev_validate_zone_mgmt_recv(),
nvmet_bdev_zone_zmgmt_recv_work() and
nvmet_bdev_execute_zone_mgmt_recv(). NUMD is a 32-bit dword count, so
any NUMD from 0x3fffffff up wraps.
The data length check in nvmet_bdev_execute_zone_mgmt_recv() sees the
same wrapped value, so such a command can pass it. A data length that
does not match the wrapped size is already rejected by that check, with
Data SGL Length Invalid. Every site agrees on the wrapped size, so the
target zeroes and fills only that many bytes and nothing leaks, but it
answers a command whose NUMD asks for 4 GiB or more.
Reject a NUMD from U32_MAX / 4 up with Invalid Field, next to the
existing check for a NUMD smaller than the report header. Computing the
size in size_t instead would still wrap on 32-bit kernels, where
nvmet_check_transfer_len() and req->transfer_len are 32 bits wide.
nvmet_io_cmd_transfer_len() in core.c uses the same expression and is
left alone here.
Tested over the loop, tcp, rdma and fc transports with a zoned
null_blk namespace: a wrapping NUMD, sent with a data length that
matches the wrapped size, was accepted before this patch and now fails
with Invalid Field, while ordinary NUMD values still succeed.
Fixes: aaf2e048af27 ("nvmet: add ZBD over ZNS backend support")
Assisted-by: LLM
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
---
drivers/nvme/target/zns.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/target/zns.c b/drivers/nvme/target/zns.c
index 78d82b6ff1214..14689ca0c38af 100644
--- a/drivers/nvme/target/zns.c
+++ b/drivers/nvme/target/zns.c
@@ -150,14 +150,17 @@ void nvmet_execute_identify_ns_zns(struct nvmet_req *req)
static u16 nvmet_bdev_validate_zone_mgmt_recv(struct nvmet_req *req)
{
sector_t sect = nvmet_lba_to_sect(req->ns, req->cmd->zmr.slba);
- u32 out_bufsize = (le32_to_cpu(req->cmd->zmr.numd) + 1) << 2;
+ u32 numd = le32_to_cpu(req->cmd->zmr.numd);
+ u32 out_bufsize = (numd + 1) << 2;
if (sect >= get_capacity(req->ns->bdev->bd_disk)) {
req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, slba);
return NVME_SC_LBA_RANGE | NVME_STATUS_DNR;
}
- if (out_bufsize < sizeof(struct nvme_zone_report)) {
+ /* From U32_MAX / 4 up, the byte count wraps and no longer matches NUMD. */
+ if (numd >= U32_MAX / 4 ||
+ out_bufsize < sizeof(struct nvme_zone_report)) {
req->error_loc = offsetof(struct nvme_zone_mgmt_recv_cmd, numd);
return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
}
--
2.53.0
next prev parent reply other threads:[~2026-10-12 14:13 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 14:12 [PATCH 0/5] nvmet: fix stale data exposure and ZNS validation Andrea Parri
2026-10-12 14:12 ` [PATCH 1/5] nvmet-fc: only send read data for successful commands Andrea Parri
2026-10-12 14:12 ` [PATCH 2/5] nvmet: zns: don't leak stale memory in zone management receive Andrea Parri
2026-10-13 14:25 ` Christoph Hellwig
2026-10-13 15:47 ` Keith Busch
2026-10-12 14:12 ` Andrea Parri [this message]
2026-10-13 14:26 ` [PATCH 3/5] nvmet: zns: reject a NUMD whose byte count wraps Christoph Hellwig
2026-10-12 14:12 ` [PATCH 4/5] nvmet: pci-epf: report transport errors in command completions Andrea Parri
2026-10-13 14:27 ` Christoph Hellwig
2026-10-13 15:12 ` Damien Le Moal
2026-10-12 14:12 ` [PATCH 5/5] nvmet: pci-epf: require SGLs to match the command data length Andrea Parri
2026-10-13 14:28 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261012141239.156408-4-parri.andrea@gmail.com \
--to=parri.andrea@gmail.com \
--cc=dlemoal@kernel.org \
--cc=hch@lst.de \
--cc=kch@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®