git: 416611f05cc4 - main - nvme: reject namespaces formatted with metadata

From: Abdelkader Boudih <seuros_at_FreeBSD.org>
Date: Sun, 13 Sep 2026 19:54:33 UTC
The branch main has been updated by seuros:

URL: https://cgit.FreeBSD.org/src/commit/?id=416611f05cc4fc431a6f9f40fcc40171e846e8fe

commit 416611f05cc4fc431a6f9f40fcc40171e846e8fe
Author:     Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-13 19:54:00 +0000
Commit:     Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-13 19:54:00 +0000

    nvme: reject namespaces formatted with metadata
    
    The active LBA format's MS field was never examined. I/O to a
    metadata-formatted namespace carries neither interleaved metadata
    nor MPTR, so every command is malformed, yet the namespace attaches
    as a disk with the wrong sector size.
    
    Reviewed by:    imp, adrian
    Differential Revision:  https://reviews.freebsd.org/D59625
---
 sys/cam/nvme/nvme_da.c | 9 +++++++++
 sys/dev/nvme/nvme_ns.c | 9 +++++++++
 2 files changed, 18 insertions(+)

diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index de1253c78fed..31bb7c4b7d3c 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -954,12 +954,21 @@ ndaregister(struct cam_periph *periph, void *arg)
 	const struct nvme_namespace_data *nsd;
 	const struct nvme_controller_data *cd;
 	char   announce_buf[80];
+	uint32_t ms;
 	u_int maxio;
 	int quirks;
 
 	nsd = nvme_get_identify_ns(periph);
 	cd = nvme_get_identify_cntrl(periph);
 
+	ms = NVMEV(NVME_NS_DATA_LBAF_MS,
+	    nsd->lbaf[NVMEV(NVME_NS_DATA_FLBAS_FORMAT, nsd->flbas)]);
+	if (ms != 0) {
+		xpt_print(periph->path,
+		    "lba format has %u-byte metadata, unsupported\n", ms);
+		return (CAM_REQ_CMP_ERR);
+	}
+
 	softc = (struct nda_softc *)malloc(sizeof(*softc), M_DEVBUF,
 	    M_NOWAIT | M_ZERO);
 
diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c
index 0082d5cb6299..f52e75bfa243 100644
--- a/sys/dev/nvme/nvme_ns.c
+++ b/sys/dev/nvme/nvme_ns.c
@@ -523,6 +523,7 @@ nvme_ns_construct(struct nvme_namespace *ns, uint32_t id,
 	struct nvme_completion_poll_status	status;
 	int                                     res;
 	int					unit;
+	uint32_t				ms;
 	uint8_t					flbas_fmt;
 	uint8_t					vwc_present;
 
@@ -574,6 +575,14 @@ nvme_ns_construct(struct nvme_namespace *ns, uint32_t id,
 		return (ENXIO);
 	}
 
+	ms = NVMEV(NVME_NS_DATA_LBAF_MS, ns->data.lbaf[flbas_fmt]);
+	if (ms != 0) {
+		nvme_printf(ctrlr,
+		    "nsid %d lba format %d has %u-byte metadata, unsupported\n",
+		    id, flbas_fmt, ms);
+		return (ENXIO);
+	}
+
 	/*
 	 * Older Intel devices (like the PC35xxx and P45xx series) advertise in
 	 * vendor specific space an alignment that improves performance.  If