aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorHoria Geantă <horia.geanta@nxp.com>2017-02-10 07:07:23 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-05-14 08:00:13 -0400
commitccef31d22e802f98bd161aa7e54f2ad98bc5ba17 (patch)
tree20aa45ad5ff050b352b6ba0515b7244007004a77 /drivers/crypto
parent819e3601d3c5e483d8c42839a2acfbfb2eafe784 (diff)
crypto: caam - fix error path for ctx_dma mapping failure
commit 87ec02e7409d787348c244039aa3536a812dfa8b upstream. In case ctx_dma dma mapping fails, ahash_unmap_ctx() tries to dma unmap an invalid address: map_seq_out_ptr_ctx() / ctx_map_to_sec4_sg() -> goto unmap_ctx -> -> ahash_unmap_ctx() -> dma unmap ctx_dma There is also possible to reach ahash_unmap_ctx() with ctx_dma uninitialzed or to try to unmap the same address twice. Fix these by setting ctx_dma = 0 where needed: -initialize ctx_dma in ahash_init() -clear ctx_dma in case of mapping error (instead of holding the error code returned by the dma map function) -clear ctx_dma after each unmapping Fixes: 32686d34f8fb6 ("crypto: caam - ensure that we clean up after an error") Signed-off-by: Horia Geantă <horia.geanta@nxp.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/caamhash.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 660dc206969f..2474f1494955 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -154,6 +154,7 @@ static inline int map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev,
154 ctx_len, DMA_FROM_DEVICE); 154 ctx_len, DMA_FROM_DEVICE);
155 if (dma_mapping_error(jrdev, state->ctx_dma)) { 155 if (dma_mapping_error(jrdev, state->ctx_dma)) {
156 dev_err(jrdev, "unable to map ctx\n"); 156 dev_err(jrdev, "unable to map ctx\n");
157 state->ctx_dma = 0;
157 return -ENOMEM; 158 return -ENOMEM;
158 } 159 }
159 160
@@ -214,6 +215,7 @@ static inline int ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
214 state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, ctx_len, flag); 215 state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, ctx_len, flag);
215 if (dma_mapping_error(jrdev, state->ctx_dma)) { 216 if (dma_mapping_error(jrdev, state->ctx_dma)) {
216 dev_err(jrdev, "unable to map ctx\n"); 217 dev_err(jrdev, "unable to map ctx\n");
218 state->ctx_dma = 0;
217 return -ENOMEM; 219 return -ENOMEM;
218 } 220 }
219 221
@@ -620,8 +622,10 @@ static inline void ahash_unmap_ctx(struct device *dev,
620 struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); 622 struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
621 struct caam_hash_state *state = ahash_request_ctx(req); 623 struct caam_hash_state *state = ahash_request_ctx(req);
622 624
623 if (state->ctx_dma) 625 if (state->ctx_dma) {
624 dma_unmap_single(dev, state->ctx_dma, ctx->ctx_len, flag); 626 dma_unmap_single(dev, state->ctx_dma, ctx->ctx_len, flag);
627 state->ctx_dma = 0;
628 }
625 ahash_unmap(dev, edesc, req, dst_len); 629 ahash_unmap(dev, edesc, req, dst_len);
626} 630}
627 631
@@ -1605,6 +1609,7 @@ static int ahash_init(struct ahash_request *req)
1605 state->finup = ahash_finup_first; 1609 state->finup = ahash_finup_first;
1606 state->final = ahash_final_no_ctx; 1610 state->final = ahash_final_no_ctx;
1607 1611
1612 state->ctx_dma = 0;
1608 state->current_buf = 0; 1613 state->current_buf = 0;
1609 state->buf_dma = 0; 1614 state->buf_dma = 0;
1610 state->buflen_0 = 0; 1615 state->buflen_0 = 0;