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 /crypto/pcrypt.c | |
| 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>
Diffstat (limited to 'crypto/pcrypt.c')
| -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 | ||
