summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPrabhath Sajeepa <psajeepa@purestorage.com>2020-03-09 22:07:53 +0100
committerKeith Busch <kbusch@kernel.org>2020-03-10 21:57:39 +0100
commit9134ae2a2546cb96abddcd4469a79c77ee3a4480 (patch)
tree754f9cc01c8d3c671a63d23ed841aa36d5e4a7d8 /drivers
parentblk-iocost: fix incorrect vtime comparison in iocg_is_idle() (diff)
downloadlinux-9134ae2a2546cb96abddcd4469a79c77ee3a4480.tar.xz
linux-9134ae2a2546cb96abddcd4469a79c77ee3a4480.zip
nvme-rdma: Avoid double freeing of async event data
The timeout of identify cmd, which is invoked as part of admin queue creation, can result in freeing of async event data both in nvme_rdma_timeout handler and error handling path of nvme_rdma_configure_admin queue thus causing NULL pointer reference. Call Trace: ? nvme_rdma_setup_ctrl+0x223/0x800 [nvme_rdma] nvme_rdma_create_ctrl+0x2ba/0x3f7 [nvme_rdma] nvmf_dev_write+0xa54/0xcc6 [nvme_fabrics] __vfs_write+0x1b/0x40 vfs_write+0xb2/0x1b0 ksys_write+0x61/0xd0 __x64_sys_write+0x1a/0x20 do_syscall_64+0x60/0x1e0 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reviewed-by: Roland Dreier <roland@purestorage.com> Reviewed-by: Max Gurtovoy <maxg@mellanox.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Prabhath Sajeepa <psajeepa@purestorage.com> Signed-off-by: Keith Busch <kbusch@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nvme/host/rdma.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 3e85c5cacefd..0fe08c4dfd2f 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -850,9 +850,11 @@ out_free_tagset:
if (new)
blk_mq_free_tag_set(ctrl->ctrl.admin_tagset);
out_free_async_qe:
- nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe,
- sizeof(struct nvme_command), DMA_TO_DEVICE);
- ctrl->async_event_sqe.data = NULL;
+ if (ctrl->async_event_sqe.data) {
+ nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe,
+ sizeof(struct nvme_command), DMA_TO_DEVICE);
+ ctrl->async_event_sqe.data = NULL;
+ }
out_free_queue:
nvme_rdma_free_queue(&ctrl->queues[0]);
return error;