[PATCH v3] nvme: core: reject invalid LBA data size from Identify Namespace
John Garry
john.g.garry at oracle.com
Tue Jun 2 09:18:30 PDT 2026
On 02/06/2026 16:42, Keith Busch wrote:
> On Tue, Jun 02, 2026 at 04:15:41PM +0100, Keith Busch wrote:
>> On Tue, Jun 02, 2026 at 02:10:07PM +0100, John Garry wrote:
>>> On 15/05/2026 19:58, Chao Shi wrote:
>>>> + if (id->lbaf[lbaf].ds < SECTOR_SHIFT ||
>>>> + check_shl_overflow(le64_to_cpu(id->nsze),> + id->lbaf[lbaf].ds -
>>> SECTOR_SHIFT,
>>>> + &capacity)) {
>>>> + dev_warn_once(ns->ctrl->device,
>>>> + "invalid LBA data size %u, skipping namespace\n",
>>>> + id->lbaf[lbaf].ds);
>>>> + ret = -ENODEV;
>>>> + goto out;
>>>> + }
>>>
>>> JFYI, this is giving a C=1 warning:
>>>
>>> drivers/nvme/host/core.c:2411:13: warning: unsigned value that used to be signed checked against zero?
>>> drivers/nvme/host/core.c:2411:13: signed value source
>>>
>>> I can't seem to quieten it myself, though.
>>>
>>> BTW, I would have thought that check_shl_overflow would catch
>>> id->lbaf[lbaf].ds < SECTOR_SHIFT (so that we don't need the extra check).
>>
>> I see it too. check_shl_overflow has checks that suggest it was
>> expecting a signed type, as all the < 0 checks don't make sense for
>> unsigned. The warning seems harmless, but I'd too like to see it
>> suppressed.
>>
>> I think it's odd that I'm not seeing a similar error for the similar
>> usage in generic_check_addressable() from fs/libfs.c. They look the same
>> to me with respect to the types passed in.
>
> It appears that sparse is having trouble with the type provenance of a
> __bitwise __le64 type. No idea why. As a test, I replaced the
> le64_to_cpu() to a u64 type on stack initialized to a random ULL value
> and the warning goes away.
Yeah, ditto.
> I say we can ignore the sparse warning, or we
> can rewrite this to avoid the check_shl_overflow entirely.
Since sparse is having problems with le64_to_cpu(), I suppose using your
own version is ok. It would be nice to know the root cause of this
issue, though...
cheers
>
> ---
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index cad9d97352615..6409a8218e3eb 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -2372,8 +2372,8 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
> struct nvme_zone_info zi = {};
> struct nvme_id_ns *id;
> unsigned int memflags;
> - sector_t capacity;
> - unsigned lbaf;
> + unsigned lbaf, shift = 0;
> + u64 capacity, nsze;
> int ret;
>
> ret = nvme_identify_ns(ns->ctrl, info->nsid, &id);
> @@ -2407,10 +2407,13 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
> goto out;
> }
>
> - if (id->lbaf[lbaf].ds < SECTOR_SHIFT ||
> - check_shl_overflow(le64_to_cpu(id->nsze),
> - id->lbaf[lbaf].ds - SECTOR_SHIFT,
> - &capacity)) {
> + nsze = le64_to_cpu(id->nsze);
> + if (id->lbaf[lbaf].ds >= SECTOR_SHIFT)
> + shift = id->lbaf[lbaf].ds - SECTOR_SHIFT;
> +
> + if (shift < SECTOR_SHIFT || shift >= 64 || nsze > U64_MAX >> shift) {
> dev_warn_once(ns->ctrl->device,
> "invalid LBA data size %u, skipping namespace\n",
> id->lbaf[lbaf].ds);
> --
More information about the Linux-nvme
mailing list