mirror of https://github.com/torvalds/linux.git
crypto: hash - Fix clone error handling
Do not copy the exit function in crypto_clone_tfm as it should only be set after init_tfm or clone_tfm has succeeded. Move the setting into crypto_clone_ahash and crypto_clone_shash instead. Also clone the fb if necessary. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
19da081a28
commit
2cfe41630a
|
|
@ -877,6 +877,7 @@ struct crypto_ahash *crypto_clone_ahash(struct crypto_ahash *hash)
|
||||||
{
|
{
|
||||||
struct hash_alg_common *halg = crypto_hash_alg_common(hash);
|
struct hash_alg_common *halg = crypto_hash_alg_common(hash);
|
||||||
struct crypto_tfm *tfm = crypto_ahash_tfm(hash);
|
struct crypto_tfm *tfm = crypto_ahash_tfm(hash);
|
||||||
|
struct crypto_ahash *fb = NULL;
|
||||||
struct crypto_ahash *nhash;
|
struct crypto_ahash *nhash;
|
||||||
struct ahash_alg *alg;
|
struct ahash_alg *alg;
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -906,22 +907,36 @@ struct crypto_ahash *crypto_clone_ahash(struct crypto_ahash *hash)
|
||||||
err = PTR_ERR(shash);
|
err = PTR_ERR(shash);
|
||||||
goto out_free_nhash;
|
goto out_free_nhash;
|
||||||
}
|
}
|
||||||
|
crypto_ahash_tfm(nhash)->exit = crypto_exit_ahash_using_shash;
|
||||||
nhash->using_shash = true;
|
nhash->using_shash = true;
|
||||||
*nctx = shash;
|
*nctx = shash;
|
||||||
return nhash;
|
return nhash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ahash_is_async(hash)) {
|
||||||
|
fb = crypto_clone_ahash(crypto_ahash_fb(hash));
|
||||||
|
err = PTR_ERR(fb);
|
||||||
|
if (IS_ERR(fb))
|
||||||
|
goto out_free_nhash;
|
||||||
|
|
||||||
|
crypto_ahash_tfm(nhash)->fb = crypto_ahash_tfm(fb);
|
||||||
|
}
|
||||||
|
|
||||||
err = -ENOSYS;
|
err = -ENOSYS;
|
||||||
alg = crypto_ahash_alg(hash);
|
alg = crypto_ahash_alg(hash);
|
||||||
if (!alg->clone_tfm)
|
if (!alg->clone_tfm)
|
||||||
goto out_free_nhash;
|
goto out_free_fb;
|
||||||
|
|
||||||
err = alg->clone_tfm(nhash, hash);
|
err = alg->clone_tfm(nhash, hash);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_free_nhash;
|
goto out_free_fb;
|
||||||
|
|
||||||
|
crypto_ahash_tfm(nhash)->exit = crypto_ahash_exit_tfm;
|
||||||
|
|
||||||
return nhash;
|
return nhash;
|
||||||
|
|
||||||
|
out_free_fb:
|
||||||
|
crypto_free_ahash(fb);
|
||||||
out_free_nhash:
|
out_free_nhash:
|
||||||
crypto_free_ahash(nhash);
|
crypto_free_ahash(nhash);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
|
||||||
|
|
@ -570,7 +570,7 @@ void *crypto_clone_tfm(const struct crypto_type *frontend,
|
||||||
|
|
||||||
tfm = (struct crypto_tfm *)(mem + frontend->tfmsize);
|
tfm = (struct crypto_tfm *)(mem + frontend->tfmsize);
|
||||||
tfm->crt_flags = otfm->crt_flags;
|
tfm->crt_flags = otfm->crt_flags;
|
||||||
tfm->exit = otfm->exit;
|
tfm->fb = tfm;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return mem;
|
return mem;
|
||||||
|
|
|
||||||
|
|
@ -413,6 +413,9 @@ struct crypto_shash *crypto_clone_shash(struct crypto_shash *hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alg->exit_tfm)
|
||||||
|
crypto_shash_tfm(nhash)->exit = crypto_shash_exit_tfm;
|
||||||
|
|
||||||
return nhash;
|
return nhash;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(crypto_clone_shash);
|
EXPORT_SYMBOL_GPL(crypto_clone_shash);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue