| From d76c68109f37cb85b243a1cf0f40313afd2bae68 Mon Sep 17 00:00:00 2001 |
| From: Eric Biggers <ebiggers@google.com> |
| Date: Wed, 20 Dec 2017 14:28:25 -0800 |
| Subject: crypto: pcrypt - fix freeing pcrypt instances |
| |
| From: Eric Biggers <ebiggers@google.com> |
| |
| commit d76c68109f37cb85b243a1cf0f40313afd2bae68 upstream. |
| |
| pcrypt is using the old way of freeing instances, where the ->free() |
| method specified in the 'struct crypto_template' is passed a pointer to |
| the 'struct crypto_instance'. But the crypto_instance is being |
| kfree()'d directly, which is incorrect because the memory was actually |
| allocated as an aead_instance, which contains the crypto_instance at a |
| nonzero offset. Thus, the wrong pointer was being kfree()'d. |
| |
| Fix it by switching to the new way to free aead_instance's where the |
| ->free() method is specified in the aead_instance itself. |
| |
| Reported-by: syzbot <syzkaller@googlegroups.com> |
| Fixes: 0496f56065e0 ("crypto: pcrypt - Add support for new AEAD interface") |
| Signed-off-by: Eric Biggers <ebiggers@google.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| crypto/pcrypt.c | 19 ++++++++++--------- |
| 1 file changed, 10 insertions(+), 9 deletions(-) |
| |
| --- a/crypto/pcrypt.c |
| +++ b/crypto/pcrypt.c |
| @@ -254,6 +254,14 @@ static void pcrypt_aead_exit_tfm(struct |
| crypto_free_aead(ctx->child); |
| } |
| |
| +static void pcrypt_free(struct aead_instance *inst) |
| +{ |
| + struct pcrypt_instance_ctx *ctx = aead_instance_ctx(inst); |
| + |
| + crypto_drop_aead(&ctx->spawn); |
| + kfree(inst); |
| +} |
| + |
| static int pcrypt_init_instance(struct crypto_instance *inst, |
| struct crypto_alg *alg) |
| { |
| @@ -319,6 +327,8 @@ static int pcrypt_create_aead(struct cry |
| inst->alg.encrypt = pcrypt_aead_encrypt; |
| inst->alg.decrypt = pcrypt_aead_decrypt; |
| |
| + inst->free = pcrypt_free; |
| + |
| err = aead_register_instance(tmpl, inst); |
| if (err) |
| goto out_drop_aead; |
| @@ -349,14 +359,6 @@ static int pcrypt_create(struct crypto_t |
| return -EINVAL; |
| } |
| |
| -static void pcrypt_free(struct crypto_instance *inst) |
| -{ |
| - struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst); |
| - |
| - crypto_drop_aead(&ctx->spawn); |
| - kfree(inst); |
| -} |
| - |
| static int pcrypt_cpumask_change_notify(struct notifier_block *self, |
| unsigned long val, void *data) |
| { |
| @@ -469,7 +471,6 @@ static void pcrypt_fini_padata(struct pa |
| static struct crypto_template pcrypt_tmpl = { |
| .name = "pcrypt", |
| .create = pcrypt_create, |
| - .free = pcrypt_free, |
| .module = THIS_MODULE, |
| }; |
| |