Skip to content

Commit 6fad84a

Browse files
committed
nvme-pci: use sgls for all user requests if possible
If the device supports SGLs, use these for all user requests. This format encodes the expected transfer length so it can catch short buffer errors in a user command, whether it occurred accidently or maliciously. For controllers that support SGL data mode, this is a viable mitigation to CVE-2023-6238. For controllers that don't support SGLs, log a warning in the passthrough path since not having the capability can corrupt data if the interface is not used correctly. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org>
1 parent 6399a0d commit 6fad84a

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

drivers/nvme/host/ioctl.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,20 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
120120
struct nvme_ns *ns = q->queuedata;
121121
struct block_device *bdev = ns ? ns->disk->part0 : NULL;
122122
bool supports_metadata = bdev && blk_get_integrity(bdev->bd_disk);
123+
struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
123124
bool has_metadata = meta_buffer && meta_len;
124125
struct bio *bio = NULL;
125126
int ret;
126127

127-
if (has_metadata && !supports_metadata)
128-
return -EINVAL;
128+
if (!nvme_ctrl_sgl_supported(ctrl))
129+
dev_warn_once(ctrl->device, "using unchecked data buffer\n");
130+
if (has_metadata) {
131+
if (!supports_metadata)
132+
return -EINVAL;
133+
if (!nvme_ctrl_meta_sgl_supported(ctrl))
134+
dev_warn_once(ctrl->device,
135+
"using unchecked metadata buffer\n");
136+
}
129137

130138
if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
131139
struct iov_iter iter;

drivers/nvme/host/pci.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ static inline bool nvme_pci_metadata_use_sgls(struct nvme_dev *dev,
515515
{
516516
if (!nvme_ctrl_meta_sgl_supported(&dev->ctrl))
517517
return false;
518-
return req->nr_integrity_segments > 1;
518+
return req->nr_integrity_segments > 1 ||
519+
nvme_req(req)->flags & NVME_REQ_USERCMD;
519520
}
520521

521522
static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req,
@@ -533,7 +534,7 @@ static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req,
533534
if (nvme_pci_metadata_use_sgls(dev, req))
534535
return true;
535536
if (!sgl_threshold || avg_seg_size < sgl_threshold)
536-
return false;
537+
return nvme_req(req)->flags & NVME_REQ_USERCMD;
537538
return true;
538539
}
539540

0 commit comments

Comments
 (0)