Skip to contentSkip to conversation

nvme: fix metadata handling in nvme-passthrough

PATCH In review Hagar Hemdan 3 participants 3 messages Feb 3, 2025 – Feb 4, 2025 Stable branch

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nvme: fix metadata handling in nvme-passthrough

From: Puranjay Mohan <[email protected]>

[ Upstream commit 7c2fd76048e95dd267055b5f5e0a48e6e7c81fd9 ]

On an NVMe namespace that does not support metadata, it is possible to send an IO command with metadata through io-passthru. This allows issues like [1] to trigger in the completion code path. nvme_map_user_request() doesn't check if the namespace supports metadata before sending it forward. It also allows admin commands with metadata to be processed as it ignores metadata when bdev == NULL and may report success.

Reject an IO command with metadata when the NVMe namespace doesn't support it and reject an admin command if it has metadata.

[1] https://lore.kernel.org/all/[email protected]/

---
Resend as all stables contain the fix except 6.1.

---
 drivers/nvme/host/ioctl.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/nvme/host/ioctl.c +7 -1
index 875dee6ecd40..19a7f0160618 100644
@@ -3,6 +3,7 @@
  * Copyright (c) 2011-2014, Intel Corporation.
  * Copyright (c) 2017-2021 Christoph Hellwig.
  */
+#include <linux/blk-integrity.h>
 #include <linux/ptrace.h>	/* for force_successful_syscall_return */
 #include <linux/nvme_ioctl.h>
 #include <linux/io_uring.h>
@@ -171,10 +172,15 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
 	struct request_queue *q = req->q;
 	struct nvme_ns *ns = q->queuedata;
 	struct block_device *bdev = ns ? ns->disk->part0 : NULL;
+	bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk);
+	bool has_metadata = meta_buffer && meta_len;
 	struct bio *bio = NULL;
 	void *meta = NULL;
 	int ret;
 
+	if (has_metadata && !supports_metadata)
+		return -EINVAL;
+
 	if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
 		struct iov_iter iter;
 
@@ -198,7 +204,7 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
 	if (bdev)
 		bio_set_dev(bio, bdev);
 
-	if (bdev && meta_buffer && meta_len) {
+	if (has_metadata) {
 		meta = nvme_add_user_metadata(req, meta_buffer, meta_len,
 				meta_seed);
 		if (IS_ERR(meta)) {
Signature · 1 line
2.40.1
maintainer
#1 lore raw

[ Sasha's backport helper bot ]

Hi,

The upstream commit SHA1 provided is correct: 7c2fd76048e95dd267055b5f5e0a48e6e7c81fd9

WARNING: Author mismatch between patch and upstream commit:
Backport author: Hagar Hemdan<[email protected]> Commit author: Puranjay Mohan<[email protected]>

Status in newer kernel trees:
6.13.y | Present (exact SHA1)
6.12.y | Present (exact SHA1)
6.6.y | Present (different SHA1: 6b42ded89ba8)
6.1.y | Not found

Note: The patch differs from the upstream commit:
---

1:  7c2fd76048e95 < -:  ------------- nvme: fix metadata handling in nvme-passthrough
-:  ------------- > 1:  93de7cb0266e2 nvme: fix metadata handling in nvme-passthrough

---

Results of testing on various branches:

| Branch                    | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.1.y        |  Success    |  Success   |
maintainer
#2 lore raw
In reply to Hagar Hemdan
Quoted 25 lines · Hagar Hemdan

From: Puranjay Mohan <[email protected]>

[ Upstream commit 7c2fd76048e95dd267055b5f5e0a48e6e7c81fd9 ]

On an NVMe namespace that does not support metadata, it is possible to send an IO command with metadata through io-passthru. This allows issues like [1] to trigger in the completion code path. nvme_map_user_request() doesn't check if the namespace supports metadata before sending it forward. It also allows admin commands with metadata to be processed as it ignores metadata when bdev == NULL and may report success.

Reject an IO command with metadata when the NVMe namespace doesn't support it and reject an admin command if it has metadata.

[1] https://lore.kernel.org/all/[email protected]/

Quoted 2 lines

---
Resend as all stables contain the fix except 6.1.

Good catch, thanks!

greg k-h