]> www.infradead.org Git - nvme.git/commitdiff
nvme-ioctl: fix leaked requests on mapping error
authorKeith Busch <kbusch@kernel.org>
Tue, 25 Feb 2025 01:13:30 +0000 (17:13 -0800)
committerKeith Busch <kbusch@kernel.org>
Tue, 25 Feb 2025 17:09:18 +0000 (09:09 -0800)
All the callers assume nvme_map_user_request() frees the request on a
failure. This wasn't happening on invalid metadata or io_uring command
flags, so we've been leaking those requests.

Fixes: 23fd22e55b767b ("nvme: wire up fixed buffer support for nvme passthrough")
Fixes: 7c2fd76048e95d ("nvme: fix metadata handling in nvme-passthrough")
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/ioctl.c

index b1b46c2713e1cc44769642687be8a80fb2d54d61..24e2c702da7a2e25c74e45c0d52dcc1ff88f7748 100644 (file)
@@ -128,8 +128,10 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
        if (!nvme_ctrl_sgl_supported(ctrl))
                dev_warn_once(ctrl->device, "using unchecked data buffer\n");
        if (has_metadata) {
-               if (!supports_metadata)
-                       return -EINVAL;
+               if (!supports_metadata) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                if (!nvme_ctrl_meta_sgl_supported(ctrl))
                        dev_warn_once(ctrl->device,
                                      "using unchecked metadata buffer\n");
@@ -139,8 +141,10 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
                struct iov_iter iter;
 
                /* fixedbufs is only for non-vectored io */
-               if (WARN_ON_ONCE(flags & NVME_IOCTL_VEC))
-                       return -EINVAL;
+               if (WARN_ON_ONCE(flags & NVME_IOCTL_VEC)) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = io_uring_cmd_import_fixed(ubuffer, bufflen,
                                rq_data_dir(req), &iter, ioucmd);
                if (ret < 0)