| From 612929c62a0da79bd758bcf0c749a9a5b9e41118 Mon Sep 17 00:00:00 2001 |
| From: Prabhath Sajeepa <psajeepa@purestorage.com> |
| Date: Mon, 9 Mar 2020 15:07:53 -0600 |
| Subject: [PATCH] nvme-rdma: Avoid double freeing of async event data |
| |
| commit 9134ae2a2546cb96abddcd4469a79c77ee3a4480 upstream. |
| |
| 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> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c |
| index f441320b2ea0..d4d131661e54 100644 |
| --- a/drivers/nvme/host/rdma.c |
| +++ b/drivers/nvme/host/rdma.c |
| @@ -843,9 +843,11 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl, |
| 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; |
| -- |
| 2.7.4 |
| |