crypto: sun8i-ce-hash - fix error handling in sun8i_ce_hash_run()
[ Upstream commit ea4dd134ef332bd9e3e734c1ba0a1521f436b678 ]
Rework error handling in sun8i_ce_hash_run() to unmap the dma buffers in
case of failure. Currently, the dma unmap functions are not called if the
function errors out at various points.
Fixes: 56f6d5aee8
("crypto: sun8i-ce - support hash algorithms")
Signed-off-by: Ovidiu Panait <ovidiu.panait.oss@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5dea6398f2
commit
76c7b1407a
@@ -343,9 +343,8 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
u32 common;
|
||||
u64 byte_count;
|
||||
__le32 *bf;
|
||||
void *buf = NULL;
|
||||
void *buf, *result;
|
||||
int j, i, todo;
|
||||
void *result = NULL;
|
||||
u64 bs;
|
||||
int digestsize;
|
||||
dma_addr_t addr_res, addr_pad;
|
||||
@@ -365,14 +364,14 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
buf = kzalloc(bs * 2, GFP_KERNEL | GFP_DMA);
|
||||
if (!buf) {
|
||||
err = -ENOMEM;
|
||||
goto theend;
|
||||
goto err_out;
|
||||
}
|
||||
bf = (__le32 *)buf;
|
||||
|
||||
result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
|
||||
if (!result) {
|
||||
err = -ENOMEM;
|
||||
goto theend;
|
||||
goto err_free_buf;
|
||||
}
|
||||
|
||||
flow = rctx->flow;
|
||||
@@ -398,7 +397,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
|
||||
dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
|
||||
err = -EINVAL;
|
||||
goto theend;
|
||||
goto err_free_result;
|
||||
}
|
||||
|
||||
len = areq->nbytes;
|
||||
@@ -411,7 +410,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
if (len > 0) {
|
||||
dev_err(ce->dev, "remaining len %d\n", len);
|
||||
err = -EINVAL;
|
||||
goto theend;
|
||||
goto err_unmap_src;
|
||||
}
|
||||
addr_res = dma_map_single(ce->dev, result, digestsize, DMA_FROM_DEVICE);
|
||||
cet->t_dst[0].addr = cpu_to_le32(addr_res);
|
||||
@@ -419,7 +418,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
if (dma_mapping_error(ce->dev, addr_res)) {
|
||||
dev_err(ce->dev, "DMA map dest\n");
|
||||
err = -EINVAL;
|
||||
goto theend;
|
||||
goto err_unmap_src;
|
||||
}
|
||||
|
||||
byte_count = areq->nbytes;
|
||||
@@ -441,7 +440,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
}
|
||||
if (!j) {
|
||||
err = -EINVAL;
|
||||
goto theend;
|
||||
goto err_unmap_result;
|
||||
}
|
||||
|
||||
addr_pad = dma_map_single(ce->dev, buf, j * 4, DMA_TO_DEVICE);
|
||||
@@ -450,7 +449,7 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
if (dma_mapping_error(ce->dev, addr_pad)) {
|
||||
dev_err(ce->dev, "DMA error on padding SG\n");
|
||||
err = -EINVAL;
|
||||
goto theend;
|
||||
goto err_unmap_result;
|
||||
}
|
||||
|
||||
if (ce->variant->hash_t_dlen_in_bits)
|
||||
@@ -463,16 +462,25 @@ int sun8i_ce_hash_run(struct crypto_engine *engine, void *breq)
|
||||
err = sun8i_ce_run_task(ce, flow, crypto_ahash_alg_name(tfm));
|
||||
|
||||
dma_unmap_single(ce->dev, addr_pad, j * 4, DMA_TO_DEVICE);
|
||||
dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
|
||||
|
||||
err_unmap_result:
|
||||
dma_unmap_single(ce->dev, addr_res, digestsize, DMA_FROM_DEVICE);
|
||||
|
||||
|
||||
if (!err)
|
||||
memcpy(areq->result, result, algt->alg.hash.base.halg.digestsize);
|
||||
theend:
|
||||
kfree(buf);
|
||||
|
||||
err_unmap_src:
|
||||
dma_unmap_sg(ce->dev, areq->src, ns, DMA_TO_DEVICE);
|
||||
|
||||
err_free_result:
|
||||
kfree(result);
|
||||
|
||||
err_free_buf:
|
||||
kfree(buf);
|
||||
|
||||
err_out:
|
||||
local_bh_disable();
|
||||
crypto_finalize_hash_request(engine, breq, err);
|
||||
local_bh_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user