From: Kanchan Joshi <joshi.k@samsung.com>
To: Yehyeong Lee <yhlee@isslab.korea.ac.kr>,
Keith Busch <kbusch@kernel.org>, Jens Axboe <axboe@kernel.dk>,
Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>
Cc: Nitesh Shetty <nj.shetty@samsung.com>,
Hannes Reinecke <hare@suse.de>,
gliuxen@gmail.com, linux-nvme@lists.infradead.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH v3] nvme: bound FDP config log reads to the received buffer
Date: Tue, 13 Oct 2026 15:16:13 +0530 [thread overview]
Message-ID: <66bf5def-eabb-4c9f-bcd5-0143655ffd1f@samsung.com> (raw)
In-Reply-To: <20261008182453.1262733-1-yhlee@isslab.korea.ac.kr>
On 10/8/2026 11:54 PM, Yehyeong Lee wrote:
> v3: read the descriptor fields with get_unaligned_le*() since a device-supplied
> dsze can leave subsequent descriptors unaligned, which could fault on
> architectures without efficient unaligned access.
Were you able to test this part.
> v2: allocate the log buffer with kvzalloc() so that if the controller completes
> the Get Log Page with a short transfer, the uninitialized tail reads as zero
> and is rejected by the existing dsze check instead of being parsed (hardening).
> v1:https://lore.kernel.org/linux-nvme/20261008132604.1168105-1-
> yhlee@isslab.korea.ac.kr/
>
> drivers/nvme/host/core.c | 24 ++++++++++++++++++++----
> 1 file changed, 20 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 9bcab3dc4c118..094df0e6ed326 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -2272,13 +2272,17 @@ static int nvme_query_fdp_granularity(struct nvme_ctrl *ctrl,
> }
>
> size = le32_to_cpu(hdr.sze);
> + if (size < sizeof(*h)) {
header plus at least one descriptor is expected. So this can changed to:
if (size < sizeof(hdr) + sizeof(*desc)) {
> + dev_warn(ctrl->device, "FDP config log too small\n");
> + return 0;
> + }
> if (size > PAGE_SIZE * MAX_ORDER_NR_PAGES) {
> dev_warn(ctrl->device, "FDP config size too large:%zu\n",
> size);
> return 0;
> }
>
> - h = kvmalloc(size, GFP_KERNEL);
> + h = kvzalloc(size, GFP_KERNEL);
> if (!h)
> return -ENOMEM;
>
> @@ -2304,8 +2308,12 @@ static int nvme_query_fdp_granularity(struct nvme_ctrl *ctrl,
> desc = log;
> end = log + size - sizeof(*h);
> for (i = 0; i < fdp_idx; i++) {
> - u16 dsze = le16_to_cpu(desc->dsze);
> + u16 dsze;
>
> + if ((u8 *)desc + sizeof(*desc) > (u8 *)h + size)
> + goto short_desc;
This and other short_desc check can be covered by extending the existing
check below
> +
> + dsze = get_unaligned_le16(&desc->dsze);
> if (!dsze || log + dsze > end) {
here, by checking that next descriptor fits completely.
Also !dsze does not cover other invalid values from 1 to 63.
Overall, something like this:
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 7eb0f9fe6b18..9991cff5c332 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2273,13 +2273,19 @@ static int nvme_query_fdp_granularity(struct
nvme_ctrl *ctrl,
}
size = le32_to_cpu(hdr.sze);
+ if (size < sizeof(hdr) + sizeof(*desc)) {
+ dev_warn(ctrl->device, "FDP config size too small:%zu\n",
+ size);
+ return 0;
+ }
+
if (size > PAGE_SIZE * MAX_ORDER_NR_PAGES) {
dev_warn(ctrl->device, "FDP config size too large:%zu\n",
size);
return 0;
}
- h = kvmalloc(size, GFP_KERNEL);
+ h = kvzalloc(size, GFP_KERNEL);
if (!h)
return -ENOMEM;
@@ -2305,9 +2311,10 @@ static int nvme_query_fdp_granularity(struct
nvme_ctrl *ctrl,
desc = log;
end = log + size - sizeof(*h);
for (i = 0; i < fdp_idx; i++) {
- u16 dsze = le16_to_cpu(desc->dsze);
+ u16 dsze = get_unaligned_le16(&desc->dsze);
- if (!dsze || log + dsze > end) {
+ /* next descriptor must fit within the log */
+ if (dsze < sizeof(*desc) || log + dsze + sizeof(*desc) >
end) {
dev_warn(ctrl->device,
"FDP invalid config descriptor at
index %d\n", i);
ret = 0;
@@ -2317,13 +2324,13 @@ static int nvme_query_fdp_granularity(struct
nvme_ctrl *ctrl,
desc = log;
}
- if (le32_to_cpu(desc->nrg) > 1) {
+ if (get_unaligned_le32(&desc->nrg) > 1) {
dev_warn(ctrl->device, "FDP NRG > 1 not supported\n");
ret = 0;
goto out;
}
- info->runs = le64_to_cpu(desc->runs);
+ info->runs = get_unaligned_le64(&desc->runs);
out:
kvfree(h);
return ret;
next prev parent reply other threads:[~2026-10-13 9:46 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20261008182524epcas5p358972aeaced27431d3c1412e88a1fae5@epcas5p3.samsung.com>
2026-10-08 18:24 ` Yehyeong Lee
2026-10-13 9:46 ` Kanchan Joshi [this message]
2026-10-13 10:28 ` Yehyeong Lee
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=66bf5def-eabb-4c9f-bcd5-0143655ffd1f@samsung.com \
--to=joshi.k@samsung.com \
--cc=axboe@kernel.dk \
--cc=gliuxen@gmail.com \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=nj.shetty@samsung.com \
--cc=sagi@grimberg.me \
--cc=stable@vger.kernel.org \
--cc=yhlee@isslab.korea.ac.kr \
/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®