Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: hisilicon - Fix double free in sec_free_hw_sgl()

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>

authored by

Yunfeng Ye and committed by
Herbert Xu
24fbf7ba 212ef6f2

+7 -6
+7 -6
drivers/crypto/hisilicon/sec/sec_algs.c
··· 215 215 dma_addr_t psec_sgl, struct sec_dev_info *info) 216 216 { 217 217 struct sec_hw_sgl *sgl_current, *sgl_next; 218 + dma_addr_t sgl_next_dma; 218 219 219 - if (!hw_sgl) 220 - return; 221 220 sgl_current = hw_sgl; 222 - while (sgl_current->next) { 221 + while (sgl_current) { 223 222 sgl_next = sgl_current->next; 224 - dma_pool_free(info->hw_sgl_pool, sgl_current, 225 - sgl_current->next_sgl); 223 + sgl_next_dma = sgl_current->next_sgl; 224 + 225 + dma_pool_free(info->hw_sgl_pool, sgl_current, psec_sgl); 226 + 226 227 sgl_current = sgl_next; 228 + psec_sgl = sgl_next_dma; 227 229 } 228 - dma_pool_free(info->hw_sgl_pool, hw_sgl, psec_sgl); 229 230 } 230 231 231 232 static int sec_alg_skcipher_setkey(struct crypto_skcipher *tfm,