From 1003e28623e8e2d1aafbceac922715688e66199d Mon Sep 17 00:00:00 2001 From: Alexey Marchuk Date: Mon, 16 May 2022 18:50:57 +0300 Subject: [PATCH] nvme/rdma: Fix qpair destroy/disconnect race When qpair is attached to a poll group, disconnect process is async - we are waiting for the DISCONNECTED event from rdmacm to destroy rdma resources. However the user (nvme_perf) can destroy qpair immediatelly, so memory allocated for qpair is freed but rdma resouces are still allocated. That means that we may receive rdmacm event (DISCONNECTED) for the destroyed qpair, that leads to use-after-free. To fix this problem, add a check for internal qpair state when qpair is destroyed, if disconnect is not finished, then we forcefully destroy rdma resources. Fixes issue #2515 Signed-off-by: Alexey Marchuk Reported-by: Or Gerlitz Change-Id: I7bfa53c9f6fe6ed787323a8941f1f2db17ea0c20 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12700 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- lib/nvme/nvme_rdma.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index 0d7757772..2686d6cf9 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -2188,6 +2188,15 @@ nvme_rdma_ctrlr_delete_io_qpair(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ assert(qpair != NULL); rqpair = nvme_rdma_qpair(qpair); + if (rqpair->state != NVME_RDMA_QPAIR_STATE_EXITED) { + int rc __attribute__((unused)); + + /* qpair was removed from the poll group while the disconnect is not finished. + * Destroy rdma resources forcefully. */ + rc = nvme_rdma_qpair_disconnected(rqpair, 0); + assert(rc == 0); + } + nvme_rdma_qpair_abort_reqs(qpair, 0); nvme_qpair_deinit(qpair);