[PATCH v3 4/5] nvme: clamp FDP placement handle count to the buffer size
Guixin Liu <[email protected]> Tue, 4 Aug 2026 10:19:00 +0800
| Newsgroups | org.infradead.lists.linux-nvme |
|---|---|
| Message-ID | <[email protected]> |
nvme_query_fdp_info() allocates the RUH status buffer for at most
S8_MAX - 1 descriptors and caps the io-mgmt-receive transfer to that
size. head->nr_plids, however, is taken verbatim from the device-supplied
nruhsd field, which can be up to 65535. If a non-conformant or malicious
device reports more descriptors than the buffer holds, the copy loop
reads past the end of the ruhs buffer (heap out-of-bounds read).
Clamp nr_plids to the number of descriptors the buffer can actually hold.
Fixes: 30b5f20bb2dd ("nvme: register fdp parameters with the block layer")
Signed-off-by: Guixin Liu <[email protected]>
Reviewed-by: Hannes Reinecke <[email protected]>
Reviewed-by: Kanchan Joshi <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Reviewed-by: Nilay Shroff <[email protected]>
---
drivers/nvme/host/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 453c1f0b2dd0..b1f444cd3daf 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2358,6 +2358,7 @@ static int nvme_query_fdp_info(struct nvme_ns *ns, struct nvme_ns_info *info)
}
head->nr_plids = le16_to_cpu(ruhs->nruhsd);
+ head->nr_plids = min_t(u16, head->nr_plids, S8_MAX - 1);
if (!head->nr_plids)
goto free;
--
2.43.7