OSDN Git Service

crypto: pcrypt - fix freeing pcrypt instances
authorEric Biggers <ebiggers@google.com>
Wed, 20 Dec 2017 22:28:25 +0000 (14:28 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Jan 2018 08:29:51 +0000 (09:29 +0100)
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

index ee9cfb9..f8ec3d4 100644 (file)
@@ -254,6 +254,14 @@ static void pcrypt_aead_exit_tfm(struct crypto_aead *tfm)
        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 crypto_template *tmpl, struct rtattr **tb,
        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_template *tmpl, struct rtattr **tb)
        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 padata_pcrypt *pcrypt)
 static struct crypto_template pcrypt_tmpl = {
        .name = "pcrypt",
        .create = pcrypt_create,
-       .free = pcrypt_free,
        .module = THIS_MODULE,
 };