]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
crypto: ccree - don't map MAC key on stack
authorGilad Ben-Yossef <gilad@benyossef.com>
Thu, 18 Apr 2019 13:39:04 +0000 (16:39 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 May 2019 05:38:45 +0000 (07:38 +0200)
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

index 2c4ddc8fb76b24829e9e2c34053b7c0e39f2eee0..657fad4031a80e51c620b668e7c1e64f8f1c2cb8 100644 (file)
@@ -69,6 +69,7 @@ struct cc_hash_alg {
 struct hash_key_req_ctx {
        u32 keylen;
        dma_addr_t key_dma_addr;
+       u8 *key;
 };
 
 /* hash per-session context */
@@ -730,13 +731,20 @@ static int cc_hash_setkey(struct crypto_ahash *ahash, const u8 *key,
        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",
@@ -887,6 +895,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;
 }
 
@@ -913,11 +924,16 @@ static int cc_xcbc_setkey(struct crypto_ahash *ahash,
 
        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",
@@ -969,6 +985,8 @@ static int cc_xcbc_setkey(struct crypto_ahash *ahash,
        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;
 }