| From fa6e355cb3bf12dc4d9f2ecd8363787bd0a55f58 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sun, 21 Jun 2020 14:19:57 +0300 |
| Subject: crypto: ccree - fix resource leak on error path |
| |
| From: Gilad Ben-Yossef <gilad@benyossef.com> |
| |
| [ Upstream commit 9bc6165d608d676f05d8bf156a2c9923ee38d05b ] |
| |
| Fix a small resource leak on the error path of cipher processing. |
| |
| Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com> |
| Fixes: 63ee04c8b491e ("crypto: ccree - add skcipher support") |
| Cc: Markus Elfring <Markus.Elfring@web.de> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/crypto/ccree/cc_cipher.c | 30 ++++++++++++++++++------------ |
| 1 file changed, 18 insertions(+), 12 deletions(-) |
| |
| diff --git a/drivers/crypto/ccree/cc_cipher.c b/drivers/crypto/ccree/cc_cipher.c |
| index a84335328f371..89f7661f0dce8 100644 |
| --- a/drivers/crypto/ccree/cc_cipher.c |
| +++ b/drivers/crypto/ccree/cc_cipher.c |
| @@ -159,7 +159,6 @@ static int cc_cipher_init(struct crypto_tfm *tfm) |
| skcipher_alg.base); |
| struct device *dev = drvdata_to_dev(cc_alg->drvdata); |
| unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; |
| - int rc = 0; |
| |
| dev_dbg(dev, "Initializing context @%p for %s\n", ctx_p, |
| crypto_tfm_alg_name(tfm)); |
| @@ -171,10 +170,19 @@ static int cc_cipher_init(struct crypto_tfm *tfm) |
| ctx_p->flow_mode = cc_alg->flow_mode; |
| ctx_p->drvdata = cc_alg->drvdata; |
| |
| + if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { |
| + /* Alloc hash tfm for essiv */ |
| + ctx_p->shash_tfm = crypto_alloc_shash("sha256-generic", 0, 0); |
| + if (IS_ERR(ctx_p->shash_tfm)) { |
| + dev_err(dev, "Error allocating hash tfm for ESSIV.\n"); |
| + return PTR_ERR(ctx_p->shash_tfm); |
| + } |
| + } |
| + |
| /* Allocate key buffer, cache line aligned */ |
| ctx_p->user.key = kmalloc(max_key_buf_size, GFP_KERNEL); |
| if (!ctx_p->user.key) |
| - return -ENOMEM; |
| + goto free_shash; |
| |
| dev_dbg(dev, "Allocated key buffer in context. key=@%p\n", |
| ctx_p->user.key); |
| @@ -186,21 +194,19 @@ static int cc_cipher_init(struct crypto_tfm *tfm) |
| if (dma_mapping_error(dev, ctx_p->user.key_dma_addr)) { |
| dev_err(dev, "Mapping Key %u B at va=%pK for DMA failed\n", |
| max_key_buf_size, ctx_p->user.key); |
| - return -ENOMEM; |
| + goto free_key; |
| } |
| dev_dbg(dev, "Mapped key %u B at va=%pK to dma=%pad\n", |
| max_key_buf_size, ctx_p->user.key, &ctx_p->user.key_dma_addr); |
| |
| - if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { |
| - /* Alloc hash tfm for essiv */ |
| - ctx_p->shash_tfm = crypto_alloc_shash("sha256-generic", 0, 0); |
| - if (IS_ERR(ctx_p->shash_tfm)) { |
| - dev_err(dev, "Error allocating hash tfm for ESSIV.\n"); |
| - return PTR_ERR(ctx_p->shash_tfm); |
| - } |
| - } |
| + return 0; |
| |
| - return rc; |
| +free_key: |
| + kfree(ctx_p->user.key); |
| +free_shash: |
| + crypto_free_shash(ctx_p->shash_tfm); |
| + |
| + return -ENOMEM; |
| } |
| |
| static void cc_cipher_exit(struct crypto_tfm *tfm) |
| -- |
| 2.25.1 |
| |