nvme-multipath: fix underflow in ANA log bounds checks

The number of ANA groups advertised through Identify Controller sizes the
ANA log buffer. The ANA log header and group descriptors independently
supply the number of groups and namespace IDs to parse.

Both bounds checks subtract an untrusted object size from ana_log_size
before comparing the current offset. If the object is larger than the
buffer, the size_t subtraction underflows and lets the parser read beyond
ana_log_buf.

Check the current offset before the first subtraction and compare each
object size with the remaining buffer instead. This rejects inconsistent
ANA data before dereferencing a truncated group descriptor or walking an
oversized namespace ID array.

Fixes: 0d0b660f21 ("nvme: add ANA support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
Daehyeon Ko 2026-09-15 11:19:56 +09:00 committed by Keith Busch
parent 7f4d0c359b
commit 63fa2d9c9c

View File

@ -843,7 +843,8 @@ static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data,
u32 nr_nsids;
size_t nsid_buf_size;
if (WARN_ON_ONCE(offset > ctrl->ana_log_size - sizeof(*desc)))
if (WARN_ON_ONCE(offset > ctrl->ana_log_size ||
sizeof(*desc) > ctrl->ana_log_size - offset))
return -EINVAL;
nr_nsids = le32_to_cpu(desc->nnsids);
@ -859,7 +860,7 @@ static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data,
return -EINVAL;
offset += sizeof(*desc);
if (WARN_ON_ONCE(offset > ctrl->ana_log_size - nsid_buf_size))
if (WARN_ON_ONCE(nsid_buf_size > ctrl->ana_log_size - offset))
return -EINVAL;
error = cb(ctrl, desc, data);