crypto: Unlink and free instances when deleted
We leak the crypto instance when we unregister an instance with crypto_del_alg(). Therefore we introduce crypto_unregister_instance() to unlink the crypto instance from the template's instances list and to free the recources of the instance properly. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
505172e11f
commit
ce3fd840f5
3 changed files with 31 additions and 1 deletions
|
@ -518,6 +518,35 @@ err:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(crypto_register_instance);
|
EXPORT_SYMBOL_GPL(crypto_register_instance);
|
||||||
|
|
||||||
|
int crypto_unregister_instance(struct crypto_alg *alg)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct crypto_instance *inst = (void *)alg;
|
||||||
|
struct crypto_template *tmpl = inst->tmpl;
|
||||||
|
LIST_HEAD(users);
|
||||||
|
|
||||||
|
if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
|
||||||
|
|
||||||
|
down_write(&crypto_alg_sem);
|
||||||
|
|
||||||
|
hlist_del_init(&inst->list);
|
||||||
|
err = crypto_remove_alg(alg, &users);
|
||||||
|
|
||||||
|
up_write(&crypto_alg_sem);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
tmpl->free(inst);
|
||||||
|
crypto_remove_final(&users);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_unregister_instance);
|
||||||
|
|
||||||
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
|
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
|
||||||
struct crypto_instance *inst, u32 mask)
|
struct crypto_instance *inst, u32 mask)
|
||||||
{
|
{
|
||||||
|
|
|
@ -301,7 +301,7 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
if (atomic_read(&alg->cra_refcnt) != 1)
|
if (atomic_read(&alg->cra_refcnt) != 1)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
return crypto_unregister_alg(alg);
|
return crypto_unregister_instance(alg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
|
|
|
@ -134,6 +134,7 @@ struct crypto_template *crypto_lookup_template(const char *name);
|
||||||
|
|
||||||
int crypto_register_instance(struct crypto_template *tmpl,
|
int crypto_register_instance(struct crypto_template *tmpl,
|
||||||
struct crypto_instance *inst);
|
struct crypto_instance *inst);
|
||||||
|
int crypto_unregister_instance(struct crypto_alg *alg);
|
||||||
|
|
||||||
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
|
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
|
||||||
struct crypto_instance *inst, u32 mask);
|
struct crypto_instance *inst, u32 mask);
|
||||||
|
|
Loading…
Reference in a new issue