From e4746ad40fa59518724a75acacab8d6e5bca4b94 Mon Sep 17 00:00:00 2001 From: Zhiqiang Liu Date: Fri, 18 Jun 2021 17:11:16 +0800 Subject: [PATCH] idxd: fix memleak problem in spdk_idxd_configure_chan() In spdk_idxd_configure_chan(), if memory allocation fails in TAILQ_FOREACH() {} code range, we will goto err_user_comp and err_user_desc tag, in which we donot free chan->completions and confused batch->user_completions with chan->completions. Memleak problem and double free problem may occurs. Signed-off-by: Zhiqiang Liu Change-Id: I0e588a35184d97cab0ea6b6c013ca8b3342f940a Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8432 Tested-by: SPDK CI Jenkins Reviewed-by: Ziye Yang Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Community-CI: Mellanox Build Bot --- lib/idxd/idxd.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/idxd/idxd.c b/lib/idxd/idxd.c index 95937d340..2fe50ee13 100644 --- a/lib/idxd/idxd.c +++ b/lib/idxd/idxd.c @@ -215,7 +215,7 @@ spdk_idxd_configure_chan(struct spdk_idxd_io_channel *chan) if (batch->user_desc == NULL) { SPDK_ERRLOG("Failed to allocate batch descriptor memory\n"); rc = -ENOMEM; - goto err_user_desc; + goto err_user_desc_or_comp; } batch->user_completions = spdk_zmalloc(DESC_PER_BATCH * sizeof(struct idxd_comp), @@ -224,7 +224,7 @@ spdk_idxd_configure_chan(struct spdk_idxd_io_channel *chan) if (batch->user_completions == NULL) { SPDK_ERRLOG("Failed to allocate user completion memory\n"); rc = -ENOMEM; - goto err_user_comp; + goto err_user_desc_or_comp; } } @@ -232,16 +232,18 @@ spdk_idxd_configure_chan(struct spdk_idxd_io_channel *chan) return 0; -err_user_comp: +err_user_desc_or_comp: TAILQ_FOREACH(batch, &chan->batch_pool, link) { spdk_free(batch->user_desc); + batch->user_desc = NULL; + spdk_free(batch->user_completions); + batch->user_completions = NULL; } -err_user_desc: - TAILQ_FOREACH(batch, &chan->batch_pool, link) { - spdk_free(chan->completions); - } + spdk_free(chan->completions); + chan->completions = NULL; err_comp: spdk_free(chan->desc); + chan->desc = NULL; err_desc: spdk_bit_array_free(&chan->ring_slots);