diff mbox series

[4.19,046/105] crypto: ccree - dont map MAC key on stack

Message ID 20190520115250.198221588@linuxfoundation.org
State Superseded
Headers show
Series None | expand

Commit Message

Greg Kroah-Hartman May 20, 2019, 12:13 p.m. UTC
From: Gilad Ben-Yossef <gilad@benyossef.com>


commit 874e163759f27e0a9988c5d1f4605e3f25564fd2 upstream.

The MAC hash key might be passed to us on stack. Copy it to
a slab buffer before mapping to gurantee proper DMA mapping.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>

Cc: stable@vger.kernel.org # v4.19+
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


---
 drivers/crypto/ccree/cc_hash.c |   24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

Comments

Pavel Machek May 22, 2019, 8:49 a.m. UTC | #1
Hi!

> The MAC hash key might be passed to us on stack. Copy it to

> a slab buffer before mapping to gurantee proper DMA mapping.

> 

> Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>

> Cc: stable@vger.kernel.org # v4.19+

> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

> 

> ---

>  drivers/crypto/ccree/cc_hash.c |   24 +++++++++++++++++++++---

>  1 file changed, 21 insertions(+), 3 deletions(-)

> 

> --- a/drivers/crypto/ccree/cc_hash.c

> +++ b/drivers/crypto/ccree/cc_hash.c

> @@ -64,6 +64,7 @@ struct cc_hash_alg {

>  struct hash_key_req_ctx {

>  	u32 keylen;

>  	dma_addr_t key_dma_addr;

> +	u8 *key;

>  };

>  

>  /* hash per-session context */


AFAICT, key is used just as a local variable in cc_hash_setkey() and
cc_xcbc_setkey() functions. Could we make it local variable to save a
bit of memory (and make code less confusing)?

Thanks,
								Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
diff mbox series

Patch

--- a/drivers/crypto/ccree/cc_hash.c
+++ b/drivers/crypto/ccree/cc_hash.c
@@ -64,6 +64,7 @@  struct cc_hash_alg {
 struct hash_key_req_ctx {
 	u32 keylen;
 	dma_addr_t key_dma_addr;
+	u8 *key;
 };
 
 /* hash per-session context */
@@ -724,13 +725,20 @@  static int cc_hash_setkey(struct crypto_
 	ctx->key_params.keylen = keylen;
 	ctx->key_params.key_dma_addr = 0;
 	ctx->is_hmac = true;
+	ctx->key_params.key = NULL;
 
 	if (keylen) {
+		ctx->key_params.key = kmemdup(key, keylen, GFP_KERNEL);
+		if (!ctx->key_params.key)
+			return -ENOMEM;
+
 		ctx->key_params.key_dma_addr =
-			dma_map_single(dev, (void *)key, keylen, DMA_TO_DEVICE);
+			dma_map_single(dev, (void *)ctx->key_params.key, keylen,
+				       DMA_TO_DEVICE);
 		if (dma_mapping_error(dev, ctx->key_params.key_dma_addr)) {
 			dev_err(dev, "Mapping key va=0x%p len=%u for DMA failed\n",
-				key, keylen);
+				ctx->key_params.key, keylen);
+			kzfree(ctx->key_params.key);
 			return -ENOMEM;
 		}
 		dev_dbg(dev, "mapping key-buffer: key_dma_addr=%pad keylen=%u\n",
@@ -881,6 +889,9 @@  out:
 		dev_dbg(dev, "Unmapped key-buffer: key_dma_addr=%pad keylen=%u\n",
 			&ctx->key_params.key_dma_addr, ctx->key_params.keylen);
 	}
+
+	kzfree(ctx->key_params.key);
+
 	return rc;
 }
 
@@ -907,11 +918,16 @@  static int cc_xcbc_setkey(struct crypto_
 
 	ctx->key_params.keylen = keylen;
 
+	ctx->key_params.key = kmemdup(key, keylen, GFP_KERNEL);
+	if (!ctx->key_params.key)
+		return -ENOMEM;
+
 	ctx->key_params.key_dma_addr =
-		dma_map_single(dev, (void *)key, keylen, DMA_TO_DEVICE);
+		dma_map_single(dev, ctx->key_params.key, keylen, DMA_TO_DEVICE);
 	if (dma_mapping_error(dev, ctx->key_params.key_dma_addr)) {
 		dev_err(dev, "Mapping key va=0x%p len=%u for DMA failed\n",
 			key, keylen);
+		kzfree(ctx->key_params.key);
 		return -ENOMEM;
 	}
 	dev_dbg(dev, "mapping key-buffer: key_dma_addr=%pad keylen=%u\n",
@@ -963,6 +979,8 @@  static int cc_xcbc_setkey(struct crypto_
 	dev_dbg(dev, "Unmapped key-buffer: key_dma_addr=%pad keylen=%u\n",
 		&ctx->key_params.key_dma_addr, ctx->key_params.keylen);
 
+	kzfree(ctx->key_params.key);
+
 	return rc;
 }