aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/crypto/aesni-intel_glue.c
diff options
context:
space:
mode:
authorJesper Juhl <jj@chaosbits.net>2011-01-23 02:56:36 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2011-01-23 02:59:17 -0500
commit7efd95f6270e210be90b94466bd3405b81e8d667 (patch)
tree6bd08a0e6ba2ce88dbdecdee0f7ea24e3f891587 /arch/x86/crypto/aesni-intel_glue.c
parent1bae4ce27c9c90344f23c65ea6966c50ffeae2f5 (diff)
crypto: aesni-intel - Don't leak memory in rfc4106_set_hash_subkey
There's a small memory leak in arch/x86/crypto/aesni-intel_glue.c::rfc4106_set_hash_subkey(). If the call to kmalloc() fails and returns NULL then the memory allocated previously by ablkcipher_request_alloc() is not freed when we leave the function. I could have just added a call to ablkcipher_request_free() before we return -ENOMEM, but that started to look too much like the code we already had at the end of the function, so I chose instead to rework the code a bit so that there are now a few labels at the end that we goto when various allocations fail, so we don't have to repeat the same blocks of code (this also reduces the object code size slightly). Signed-off-by: Jesper Juhl <jj@chaosbits.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'arch/x86/crypto/aesni-intel_glue.c')
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index e1e60c7d5813..e0135526345d 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -873,21 +873,19 @@ rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len)
873 crypto_ablkcipher_clear_flags(ctr_tfm, ~0); 873 crypto_ablkcipher_clear_flags(ctr_tfm, ~0);
874 874
875 ret = crypto_ablkcipher_setkey(ctr_tfm, key, key_len); 875 ret = crypto_ablkcipher_setkey(ctr_tfm, key, key_len);
876 if (ret) { 876 if (ret)
877 crypto_free_ablkcipher(ctr_tfm); 877 goto out;
878 return ret;
879 }
880 878
881 req = ablkcipher_request_alloc(ctr_tfm, GFP_KERNEL); 879 req = ablkcipher_request_alloc(ctr_tfm, GFP_KERNEL);
882 if (!req) { 880 if (!req) {
883 crypto_free_ablkcipher(ctr_tfm); 881 ret = -EINVAL;
884 return -EINVAL; 882 goto out_free_ablkcipher;
885 } 883 }
886 884
887 req_data = kmalloc(sizeof(*req_data), GFP_KERNEL); 885 req_data = kmalloc(sizeof(*req_data), GFP_KERNEL);
888 if (!req_data) { 886 if (!req_data) {
889 crypto_free_ablkcipher(ctr_tfm); 887 ret = -ENOMEM;
890 return -ENOMEM; 888 goto out_free_request;
891 } 889 }
892 memset(req_data->iv, 0, sizeof(req_data->iv)); 890 memset(req_data->iv, 0, sizeof(req_data->iv));
893 891
@@ -913,9 +911,12 @@ rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len)
913 if (!ret) 911 if (!ret)
914 ret = req_data->result.err; 912 ret = req_data->result.err;
915 } 913 }
914out_free_request:
916 ablkcipher_request_free(req); 915 ablkcipher_request_free(req);
917 kfree(req_data); 916 kfree(req_data);
917out_free_ablkcipher:
918 crypto_free_ablkcipher(ctr_tfm); 918 crypto_free_ablkcipher(ctr_tfm);
919out:
919 return ret; 920 return ret;
920} 921}
921 922