Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adb64e0a authored by Eric Biggers's avatar Eric Biggers Committed by Usaamah Patel
Browse files

CVE-2017-18075: crypto: pcrypt - fix freeing pcrypt instances



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.

Change-Id: Ia072fa391205a4ba42249cf439eb7bad90241c95
Reported-by: default avatarsyzbot <syzkaller@googlegroups.com>
Fixes: 0496f56065e0 ("crypto: pcrypt - Add support for new AEAD interface")
Cc: <stable@vger.kernel.org> # v4.2+
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent fda1d0ec
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -344,6 +344,14 @@ out_free_inst:
	goto out;
}

static void pcrypt_free(struct crypto_instance *inst)
{
	struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);

	crypto_drop_spawn(&ctx->spawn);
	kfree(inst);
}

static struct crypto_instance *pcrypt_alloc_aead(struct rtattr **tb,
						 u32 type, u32 mask)
{
@@ -376,6 +384,8 @@ static struct crypto_instance *pcrypt_alloc_aead(struct rtattr **tb,
	inst->alg.cra_aead.decrypt = pcrypt_aead_decrypt;
	inst->alg.cra_aead.givencrypt = pcrypt_aead_givencrypt;

	inst->free = pcrypt_free;

out_put_alg:
	crypto_mod_put(alg);
	return inst;
@@ -397,14 +407,6 @@ static struct crypto_instance *pcrypt_alloc(struct rtattr **tb)
	return ERR_PTR(-EINVAL);
}

static void pcrypt_free(struct crypto_instance *inst)
{
	struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);

	crypto_drop_spawn(&ctx->spawn);
	kfree(inst);
}

static int pcrypt_cpumask_change_notify(struct notifier_block *self,
					unsigned long val, void *data)
{
@@ -517,7 +519,6 @@ static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt)
static struct crypto_template pcrypt_tmpl = {
	.name = "pcrypt",
	.alloc = pcrypt_alloc,
	.free = pcrypt_free,
	.module = THIS_MODULE,
};