| From e569b0c4e71535a6838047831f7b6a4f3ccc39e0 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 20 May 2021 22:20:23 -0400 |
| Subject: crypto: qce: skcipher: Fix incorrect sg count for dma transfers |
| |
| From: Thara Gopinath <thara.gopinath@linaro.org> |
| |
| [ Upstream commit 1339a7c3ba05137a2d2fe75f602311bbfc6fab33 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/crypto/qce/skcipher.c | 15 ++++++++------- |
| 1 file changed, 8 insertions(+), 7 deletions(-) |
| |
| diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c |
| index a2d3da0ad95f..5a6559131eac 100644 |
| --- a/drivers/crypto/qce/skcipher.c |
| +++ b/drivers/crypto/qce/skcipher.c |
| @@ -71,7 +71,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); |
| @@ -122,21 +122,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; |
| -- |
| 2.30.2 |
| |