From 4ea996ce19cef70177efea306466294f4414f65a Mon Sep 17 00:00:00 2001 From: Tomasz Zawadzki Date: Mon, 18 Nov 2019 09:37:34 -0500 Subject: [PATCH] nvmf/rdma: dont refer to rtransport when poll_group_create failed This issue was found by code inspection. It only occurs when pdk_nvmf_transport_poll_group_create() itself calls spdk_nvmf_transport_poll_group_destroy(). Other transports at this time do not show this issue. spdk_nvmf_rdma_poll_group_destroy() depends on rgroup being assigned a transport, which is only being done on generic nvmf layer using spdk_nvmf_transport_poll_group_create() after successful spdk_nvmf_rdma_poll_group_create(). When failure occurs during create, such assignment was not performed so any references to rtransport will segfault. Reported-by: Jacek Kalwas Signed-off-by: Tomasz Zawadzki Change-Id: Id54482d562bd6d7c71371306cf1de93bc05f4e8a Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/475002 Tested-by: SPDK CI Jenkins Reviewed-by: Ben Walker Reviewed-by: Jim Harris Reviewed-by: Shuhei Matsumoto Reviewed-by: Alexey Marchuk --- lib/nvmf/rdma.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index b16b1a752..13fab509a 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -3368,8 +3368,6 @@ spdk_nvmf_rdma_poll_group_destroy(struct spdk_nvmf_transport_poll_group *group) struct spdk_nvmf_rdma_transport *rtransport; rgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_rdma_poll_group, group); - rtransport = SPDK_CONTAINEROF(rgroup->group.transport, struct spdk_nvmf_rdma_transport, transport); - if (!rgroup) { return; } @@ -3401,6 +3399,15 @@ spdk_nvmf_rdma_poll_group_destroy(struct spdk_nvmf_transport_poll_group *group) free(poller); } + if (rgroup->group.transport == NULL) { + /* Transport can be NULL when spdk_nvmf_rdma_poll_group_create() + * calls this function directly in a failure path. */ + free(rgroup); + return; + } + + rtransport = SPDK_CONTAINEROF(rgroup->group.transport, struct spdk_nvmf_rdma_transport, transport); + pthread_mutex_lock(&rtransport->lock); next_rgroup = TAILQ_NEXT(rgroup, link); TAILQ_REMOVE(&rtransport->poll_groups, rgroup, link);