diff options
author | Eric Biggers <ebiggers@google.com> | 2017-12-20 17:28:25 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-12-22 03:02:47 -0500 |
commit | d76c68109f37cb85b243a1cf0f40313afd2bae68 (patch) | |
tree | 233b6167cb25abdb06507952a6de831f0d5ce62d | |
parent | 203f45003a3d03eea8fa28d74cfc74c354416fdb (diff) |
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.
Reported-by: syzbot <syzkaller@googlegroups.com>
Fixes: 0496f56065e0 ("crypto: pcrypt - Add support for new AEAD interface")
Cc: <stable@vger.kernel.org> # v4.2+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/pcrypt.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c index ee9cfb99fe25..f8ec3d4ba4a8 100644 --- a/crypto/pcrypt.c +++ b/crypto/pcrypt.c | |||
@@ -254,6 +254,14 @@ static void pcrypt_aead_exit_tfm(struct crypto_aead *tfm) | |||
254 | crypto_free_aead(ctx->child); | 254 | crypto_free_aead(ctx->child); |
255 | } | 255 | } |
256 | 256 | ||
257 | static void pcrypt_free(struct aead_instance *inst) | ||
258 | { | ||
259 | struct pcrypt_instance_ctx *ctx = aead_instance_ctx(inst); | ||
260 | |||
261 | crypto_drop_aead(&ctx->spawn); | ||
262 | kfree(inst); | ||
263 | } | ||
264 | |||
257 | static int pcrypt_init_instance(struct crypto_instance *inst, | 265 | static int pcrypt_init_instance(struct crypto_instance *inst, |
258 | struct crypto_alg *alg) | 266 | struct crypto_alg *alg) |
259 | { | 267 | { |
@@ -319,6 +327,8 @@ static int pcrypt_create_aead(struct crypto_template *tmpl, struct rtattr **tb, | |||
319 | inst->alg.encrypt = pcrypt_aead_encrypt; | 327 | inst->alg.encrypt = pcrypt_aead_encrypt; |
320 | inst->alg.decrypt = pcrypt_aead_decrypt; | 328 | inst->alg.decrypt = pcrypt_aead_decrypt; |
321 | 329 | ||
330 | inst->free = pcrypt_free; | ||
331 | |||
322 | err = aead_register_instance(tmpl, inst); | 332 | err = aead_register_instance(tmpl, inst); |
323 | if (err) | 333 | if (err) |
324 | goto out_drop_aead; | 334 | goto out_drop_aead; |
@@ -349,14 +359,6 @@ static int pcrypt_create(struct crypto_template *tmpl, struct rtattr **tb) | |||
349 | return -EINVAL; | 359 | return -EINVAL; |
350 | } | 360 | } |
351 | 361 | ||
352 | static void pcrypt_free(struct crypto_instance *inst) | ||
353 | { | ||
354 | struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst); | ||
355 | |||
356 | crypto_drop_aead(&ctx->spawn); | ||
357 | kfree(inst); | ||
358 | } | ||
359 | |||
360 | static int pcrypt_cpumask_change_notify(struct notifier_block *self, | 362 | static int pcrypt_cpumask_change_notify(struct notifier_block *self, |
361 | unsigned long val, void *data) | 363 | unsigned long val, void *data) |
362 | { | 364 | { |
@@ -469,7 +471,6 @@ static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt) | |||
469 | static struct crypto_template pcrypt_tmpl = { | 471 | static struct crypto_template pcrypt_tmpl = { |
470 | .name = "pcrypt", | 472 | .name = "pcrypt", |
471 | .create = pcrypt_create, | 473 | .create = pcrypt_create, |
472 | .free = pcrypt_free, | ||
473 | .module = THIS_MODULE, | 474 | .module = THIS_MODULE, |
474 | }; | 475 | }; |
475 | 476 | ||