Commit 74c3af84 authored by Yankun Li's avatar Yankun Li Committed by Tomasz Zawadzki
Browse files

lib/nvmf: fix memory error, check whether rpoller has been removed



Before destroying poller, check again whether it has been removed,
When conducting a network fault test, i encountered segmentation
fault:

If the creation of rpoller fails, nvmf_rdma_poller_destroy will be
called immediately to destroy it in _nvmf_rdma_register_poller_in_group
function. However, if a network card failure is detected and
_nvmf_rdma_remove_poller_in_group is called to delete this rpoller,
it will lead to illegal memory access.

Fixes issue #3662

Change-Id: I126e70f6c1b95a5163ed15ccda35e1922b2e9b38
Signed-off-by: default avatarYankun Li <yankun@staff.sina.com>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/25948


Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
Tested-by: default avatarSPDK Automated Test System <spdkbot@gmail.com>
parent b0dc8772
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -4895,15 +4895,29 @@ static void
_nvmf_rdma_remove_poller_in_group(void *c)
{
	struct poller_manage_ctx		*ctx = c;
	struct spdk_nvmf_rdma_poller            *rpoller;

	ctx->rpoller->need_destroy = true;
	ctx->rpoller->destroy_cb_ctx = ctx;
	ctx->rpoller->destroy_cb = _nvmf_rdma_remove_poller_in_group_cb;
	/* Check if the poller referred to by this context was already removed.
	 * If it was already removed, simply call the usual destroy_cb function
	 * directly.
	 */
	TAILQ_FOREACH(rpoller, &ctx->rgroup->pollers, link) {
		if (rpoller == ctx->rpoller) {
			break;
		}
	}

	if (rpoller != NULL) {
		rpoller->need_destroy = true;
		rpoller->destroy_cb_ctx = ctx;
		rpoller->destroy_cb = _nvmf_rdma_remove_poller_in_group_cb;
		/* qp will be disconnected after receiving a RDMA_CM_EVENT_DEVICE_REMOVAL event. */
		if (RB_EMPTY(&ctx->rpoller->qpairs)) {
			nvmf_rdma_poller_destroy(ctx->rpoller);
		}
	} else {
		_nvmf_rdma_remove_poller_in_group_cb(ctx);
	}
}

static int