summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThara Gopinath <thara.gopinath@linaro.org>2021-05-20 22:20:23 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2021-05-28 15:11:45 +0800
commit1339a7c3ba05137a2d2fe75f602311bbfc6fab33 (patch)
treed4f32635cd154120c2dc5140ebef144cf546e2f1 /drivers
parent9b7b94683a9b9c42a743d591e48b9f51f505dd1f (diff)
downloadlinux-stable-1339a7c3ba05137a2d2fe75f602311bbfc6fab33.tar.gz
linux-stable-1339a7c3ba05137a2d2fe75f602311bbfc6fab33.tar.bz2
linux-stable-1339a7c3ba05137a2d2fe75f602311bbfc6fab33.zip
crypto: qce: skcipher: Fix incorrect sg count for dma transfers
Use the sg count returned by dma_map_sg to call into dmaengine_prep_slave_sg rather than using the original sg count. dma_map_sg can merge consecutive sglist entries, thus making the original sg count wrong. This is a fix for memory coruption issues observed while testing encryption/decryption of large messages using libkcapi framework. Patch has been tested further by running full suite of tcrypt.ko tests including fuzz tests. Signed-off-by: Thara Gopinath <thara.gopinath@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/qce/skcipher.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
index c0a0d8c4fce1..259418479227 100644
--- a/drivers/crypto/qce/skcipher.c
+++ b/drivers/crypto/qce/skcipher.c
@@ -72,7 +72,7 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
struct scatterlist *sg;
bool diff_dst;
gfp_t gfp;
- int ret;
+ int dst_nents, src_nents, ret;
rctx->iv = req->iv;
rctx->ivsize = crypto_skcipher_ivsize(skcipher);
@@ -123,21 +123,22 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req)
sg_mark_end(sg);
rctx->dst_sg = rctx->dst_tbl.sgl;
- ret = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
- if (ret < 0)
+ dst_nents = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
+ if (dst_nents < 0)
goto error_free;
if (diff_dst) {
- ret = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src);
- if (ret < 0)
+ src_nents = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src);
+ if (src_nents < 0)
goto error_unmap_dst;
rctx->src_sg = req->src;
} else {
rctx->src_sg = rctx->dst_sg;
+ src_nents = dst_nents - 1;
}
- ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents,
- rctx->dst_sg, rctx->dst_nents,
+ ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, src_nents,
+ rctx->dst_sg, dst_nents,
qce_skcipher_done, async_req);
if (ret)
goto error_unmap_src;