Skip to content

Commit 94e4221

Browse files
sagigrimbergChristoph Hellwig
authored andcommitted
nvme-rdma: fix possible free of a non-allocated async event buffer
If nvme_rdma_configure_admin_queue fails before we allocated the async event buffer, we will falsly free it because nvme_rdma_free_queue is freeing it. Fix it by allocating the buffer right after nvme_rdma_alloc_queue and free it right before nvme_rdma_queue_free to maintain orderly reverse cleanup sequence. Reported-by: Israel Rukshin <[email protected]> Signed-off-by: Sagi Grimberg <[email protected]> Reviewed-by: Max Gurtovoy <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 3d06410 commit 94e4221

File tree

1 file changed

+11
-13
lines changed

1 file changed

+11
-13
lines changed

drivers/nvme/host/rdma.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -560,12 +560,6 @@ static void nvme_rdma_free_queue(struct nvme_rdma_queue *queue)
560560
if (!test_and_clear_bit(NVME_RDMA_Q_ALLOCATED, &queue->flags))
561561
return;
562562

563-
if (nvme_rdma_queue_idx(queue) == 0) {
564-
nvme_rdma_free_qe(queue->device->dev,
565-
&queue->ctrl->async_event_sqe,
566-
sizeof(struct nvme_command), DMA_TO_DEVICE);
567-
}
568-
569563
nvme_rdma_destroy_queue_ib(queue);
570564
rdma_destroy_id(queue->cm_id);
571565
}
@@ -739,6 +733,8 @@ static void nvme_rdma_destroy_admin_queue(struct nvme_rdma_ctrl *ctrl,
739733
blk_cleanup_queue(ctrl->ctrl.admin_q);
740734
nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.admin_tagset);
741735
}
736+
nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe,
737+
sizeof(struct nvme_command), DMA_TO_DEVICE);
742738
nvme_rdma_free_queue(&ctrl->queues[0]);
743739
}
744740

@@ -755,11 +751,16 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl,
755751

756752
ctrl->max_fr_pages = nvme_rdma_get_max_fr_pages(ctrl->device->dev);
757753

754+
error = nvme_rdma_alloc_qe(ctrl->device->dev, &ctrl->async_event_sqe,
755+
sizeof(struct nvme_command), DMA_TO_DEVICE);
756+
if (error)
757+
goto out_free_queue;
758+
758759
if (new) {
759760
ctrl->ctrl.admin_tagset = nvme_rdma_alloc_tagset(&ctrl->ctrl, true);
760761
if (IS_ERR(ctrl->ctrl.admin_tagset)) {
761762
error = PTR_ERR(ctrl->ctrl.admin_tagset);
762-
goto out_free_queue;
763+
goto out_free_async_qe;
763764
}
764765

765766
ctrl->ctrl.admin_q = blk_mq_init_queue(&ctrl->admin_tag_set);
@@ -795,12 +796,6 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl,
795796
if (error)
796797
goto out_stop_queue;
797798

798-
error = nvme_rdma_alloc_qe(ctrl->queues[0].device->dev,
799-
&ctrl->async_event_sqe, sizeof(struct nvme_command),
800-
DMA_TO_DEVICE);
801-
if (error)
802-
goto out_stop_queue;
803-
804799
return 0;
805800

806801
out_stop_queue:
@@ -811,6 +806,9 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl,
811806
out_free_tagset:
812807
if (new)
813808
nvme_rdma_free_tagset(&ctrl->ctrl, ctrl->ctrl.admin_tagset);
809+
out_free_async_qe:
810+
nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe,
811+
sizeof(struct nvme_command), DMA_TO_DEVICE);
814812
out_free_queue:
815813
nvme_rdma_free_queue(&ctrl->queues[0]);
816814
return error;

0 commit comments

Comments
 (0)