[PATCH v2 2/2] libnvdimm/labels: reject an implausibly large on-media slot count

From: Bryam Vargas via B4 Relay

Date: Wed Jun 24 2026 - 00:19:47 EST


From: Bryam Vargas <hexlabsecurity@xxxxxxxxx>

Even with the bound evaluated in 64-bit, nslot is constrained only by
config_size, which nvdimm_init_nsarea() takes verbatim from the dimm's
ND_CMD_GET_CONFIG_SIZE response with no upper sanity check. A firmware
or emulated device reporting a large config_size would let a
correspondingly large on-media nslot pass validation and drive a large
allocation and memset loop in nd_label_data_init().

Reject an nslot above NSINDEX_NSLOT_MAX (64K). The largest legitimate
count is config_size / label_size -- about 1K on a real ~128K label area
-- so this cannot affect a conforming device, and it bounds the slot loop
independently of the firmware-reported config_size.

Suggested-by: David Laight <david.laight.linux@xxxxxxxxx>
Signed-off-by: Bryam Vargas <hexlabsecurity@xxxxxxxxx>
---
drivers/nvdimm/label.c | 4 ++++
drivers/nvdimm/label.h | 7 +++++++
2 files changed, 11 insertions(+)

diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index ec12ce72cfe2..ce1e43d67bab 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -202,6 +202,10 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd)
}

nslot = __le32_to_cpu(nsindex[i]->nslot);
+ if (nslot > NSINDEX_NSLOT_MAX) {
+ dev_dbg(dev, "nsindex%d nslot: %u implausibly large\n", i, nslot);
+ continue;
+ }
if ((u64)nslot * sizeof_namespace_label(ndd)
+ 2 * sizeof_namespace_index(ndd)
> ndd->nsarea.config_size) {
diff --git a/drivers/nvdimm/label.h b/drivers/nvdimm/label.h
index 0650fb4b9821..74d7c1cc7476 100644
--- a/drivers/nvdimm/label.h
+++ b/drivers/nvdimm/label.h
@@ -28,6 +28,13 @@ enum {
ND_LABEL_MIN_SIZE = 256 * 4, /* see sizeof_namespace_index() */
ND_LABEL_ID_SIZE = 50,
ND_NSINDEX_INIT = 0x1,
+ /*
+ * A sane ceiling on the on-media slot count. The largest legitimate
+ * value is config_size / label_size -- about 1K on a real ~128K label
+ * area. A count this large cannot describe a real device; it would
+ * only drive a large allocation in nd_label_data_init(), so reject it.
+ */
+ NSINDEX_NSLOT_MAX = 64 * 1024,
};

/**

--
2.43.0