Torsten Duwe 8e9d0d
From: Eric Biggers <ebiggers@google.com>
Torsten Duwe 8e9d0d
Subject: crypto: pcrypt - fix freeing pcrypt instances
Torsten Duwe 8e9d0d
Git-commit: d76c68109f37cb85b243a1cf0f40313afd2bae68
Benjamin Poirier 2767cf
Patch-mainline: v4.15-rc7
Torsten Duwe 8e9d0d
References: bsc#1077402,CVE-2017-18075
Torsten Duwe 8e9d0d
Torsten Duwe 8e9d0d
 crypto: pcrypt - fix freeing pcrypt instances
Torsten Duwe 8e9d0d
Torsten Duwe 8e9d0d
pcrypt is using the old way of freeing instances, where the ->free()
Torsten Duwe 8e9d0d
method specified in the 'struct crypto_template' is passed a pointer to
Torsten Duwe 8e9d0d
the 'struct crypto_instance'.  But the crypto_instance is being
Torsten Duwe 8e9d0d
kfree()'d directly, which is incorrect because the memory was actually
Torsten Duwe 8e9d0d
allocated as an aead_instance, which contains the crypto_instance at a
Torsten Duwe 8e9d0d
nonzero offset.  Thus, the wrong pointer was being kfree()'d.
Torsten Duwe 8e9d0d
Torsten Duwe 8e9d0d
Fix it by switching to the new way to free aead_instance's where the
Torsten Duwe 8e9d0d
->free() method is specified in the aead_instance itself.
Torsten Duwe 8e9d0d
Torsten Duwe 8e9d0d
Reported-by: syzbot <syzkaller@googlegroups.com>
Torsten Duwe 8e9d0d
Fixes: 0496f56065e0 ("crypto: pcrypt - Add support for new AEAD interface")
Torsten Duwe 8e9d0d
Cc: <stable@vger.kernel.org> # v4.2+
Torsten Duwe 8e9d0d
Signed-off-by: Eric Biggers <ebiggers@google.com>
Torsten Duwe 8e9d0d
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Torsten Duwe 8e9d0d
Acked-by: Torsten Duwe <duwe@suse.de>
Torsten Duwe 8e9d0d
Torsten Duwe 8e9d0d
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
Torsten Duwe 8e9d0d
index ee9cfb9..f8ec3d4 100644
Torsten Duwe 8e9d0d
--- a/crypto/pcrypt.c
Torsten Duwe 8e9d0d
+++ b/crypto/pcrypt.c
Torsten Duwe 8e9d0d
@@ -254,6 +254,14 @@ static void pcrypt_aead_exit_tfm(struct crypto_aead *tfm)
Torsten Duwe 8e9d0d
 	crypto_free_aead(ctx->child);
Torsten Duwe 8e9d0d
 }
Torsten Duwe 8e9d0d
 
Torsten Duwe 8e9d0d
+static void pcrypt_free(struct aead_instance *inst)
Torsten Duwe 8e9d0d
+{
Torsten Duwe 8e9d0d
+	struct pcrypt_instance_ctx *ctx = aead_instance_ctx(inst);
Torsten Duwe 8e9d0d
+
Torsten Duwe 8e9d0d
+	crypto_drop_aead(&ctx->spawn);
Torsten Duwe 8e9d0d
+	kfree(inst);
Torsten Duwe 8e9d0d
+}
Torsten Duwe 8e9d0d
+
Torsten Duwe 8e9d0d
 static int pcrypt_init_instance(struct crypto_instance *inst,
Torsten Duwe 8e9d0d
 				struct crypto_alg *alg)
Torsten Duwe 8e9d0d
 {
Torsten Duwe 8e9d0d
@@ -319,6 +327,8 @@ static int pcrypt_create_aead(struct crypto_template *tmpl, struct rtattr **tb,
Torsten Duwe 8e9d0d
 	inst->alg.encrypt = pcrypt_aead_encrypt;
Torsten Duwe 8e9d0d
 	inst->alg.decrypt = pcrypt_aead_decrypt;
Torsten Duwe 8e9d0d
 
Torsten Duwe 8e9d0d
+	inst->free = pcrypt_free;
Torsten Duwe 8e9d0d
+
Torsten Duwe 8e9d0d
 	err = aead_register_instance(tmpl, inst);
Torsten Duwe 8e9d0d
 	if (err)
Torsten Duwe 8e9d0d
 		goto out_drop_aead;
Torsten Duwe 8e9d0d
@@ -349,14 +359,6 @@ static int pcrypt_create(struct crypto_template *tmpl, struct rtattr **tb)
Torsten Duwe 8e9d0d
 	return -EINVAL;
Torsten Duwe 8e9d0d
 }
Torsten Duwe 8e9d0d
 
Torsten Duwe 8e9d0d
-static void pcrypt_free(struct crypto_instance *inst)
Torsten Duwe 8e9d0d
-{
Torsten Duwe 8e9d0d
-	struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);
Torsten Duwe 8e9d0d
-
Torsten Duwe 8e9d0d
-	crypto_drop_aead(&ctx->spawn);
Torsten Duwe 8e9d0d
-	kfree(inst);
Torsten Duwe 8e9d0d
-}
Torsten Duwe 8e9d0d
-
Torsten Duwe 8e9d0d
 static int pcrypt_cpumask_change_notify(struct notifier_block *self,
Torsten Duwe 8e9d0d
 					unsigned long val, void *data)
Torsten Duwe 8e9d0d
 {
Torsten Duwe 8e9d0d
@@ -469,7 +471,6 @@ static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt)
Torsten Duwe 8e9d0d
 static struct crypto_template pcrypt_tmpl = {
Torsten Duwe 8e9d0d
 	.name = "pcrypt",
Torsten Duwe 8e9d0d
 	.create = pcrypt_create,
Torsten Duwe 8e9d0d
-	.free = pcrypt_free,
Torsten Duwe 8e9d0d
 	.module = THIS_MODULE,
Torsten Duwe 8e9d0d
 };
Torsten Duwe 8e9d0d