summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYunfeng Ye <yeyunfeng@huawei.com>2019-09-15 17:26:56 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-10-07 18:59:36 +0200
commit26235380e6333746c63ea88e5d97d39e8d3c3537 (patch)
tree40c43eab718da728a865320ab70e7283c337d4e5
parentef1bb2f3c68c6a2262b6a66c57a2ab477b68e34f (diff)
downloadlinux-stable-26235380e6333746c63ea88e5d97d39e8d3c3537.tar.gz
linux-stable-26235380e6333746c63ea88e5d97d39e8d3c3537.tar.bz2
linux-stable-26235380e6333746c63ea88e5d97d39e8d3c3537.zip
crypto: hisilicon - Fix double free in sec_free_hw_sgl()
[ Upstream commit 24fbf7bad888767bed952f540ac963bc57e47e15 ] There are two problems in sec_free_hw_sgl(): First, when sgl_current->next is valid, @hw_sgl will be freed in the first loop, but it free again after the loop. Second, sgl_current and sgl_current->next_sgl is not match when dma_pool_free() is invoked, the third parameter should be the dma address of sgl_current, but sgl_current->next_sgl is the dma address of next chain, so use sgl_current->next_sgl is wrong. Fix this by deleting the last dma_pool_free() in sec_free_hw_sgl(), modifying the condition for while loop, and matching the address for dma_pool_free(). Fixes: 915e4e8413da ("crypto: hisilicon - SEC security accelerator driver") Signed-off-by: Yunfeng Ye <yeyunfeng@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/crypto/hisilicon/sec/sec_algs.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c
index 02768af0dccd..8c789b8671fc 100644
--- a/drivers/crypto/hisilicon/sec/sec_algs.c
+++ b/drivers/crypto/hisilicon/sec/sec_algs.c
@@ -215,17 +215,18 @@ static void sec_free_hw_sgl(struct sec_hw_sgl *hw_sgl,
dma_addr_t psec_sgl, struct sec_dev_info *info)
{
struct sec_hw_sgl *sgl_current, *sgl_next;
+ dma_addr_t sgl_next_dma;
- if (!hw_sgl)
- return;
sgl_current = hw_sgl;
- while (sgl_current->next) {
+ while (sgl_current) {
sgl_next = sgl_current->next;
- dma_pool_free(info->hw_sgl_pool, sgl_current,
- sgl_current->next_sgl);
+ sgl_next_dma = sgl_current->next_sgl;
+
+ dma_pool_free(info->hw_sgl_pool, sgl_current, psec_sgl);
+
sgl_current = sgl_next;
+ psec_sgl = sgl_next_dma;
}
- dma_pool_free(info->hw_sgl_pool, hw_sgl, psec_sgl);
}
static int sec_alg_skcipher_setkey(struct crypto_skcipher *tfm,