]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: api - Ensure cra_type->destroy is done in process context
authorHerbert Xu <herbert@gondor.apana.org.au>
Mon, 17 Mar 2025 08:33:57 +0000 (16:33 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Mon, 7 Apr 2025 05:22:25 +0000 (13:22 +0800)
Move the cra_type->destroy call out of crypto_alg_put and into
crypto_unregister_alg and crypto_free_instance.  This ensures
that it's always done in process context so calls such as flush_work
can be done.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/algapi.c
crypto/api.c
crypto/internal.h

index 22bf80aad82b6fb825e87d17e8e79cff88893ffb..5b8a4c78738796f100029cd9ddf5ec8a027c940e 100644 (file)
@@ -66,7 +66,13 @@ static int crypto_check_alg(struct crypto_alg *alg)
 
 static void crypto_free_instance(struct crypto_instance *inst)
 {
-       inst->alg.cra_type->free(inst);
+       struct crypto_alg *alg = &inst->alg;
+       const struct crypto_type *type;
+
+       type = alg->cra_type;
+       if (type->destroy)
+               type->destroy(alg);
+       type->free(inst);
 }
 
 static void crypto_destroy_instance_workfn(struct work_struct *w)
@@ -150,7 +156,6 @@ static void crypto_remove_instance(struct crypto_instance *inst,
        list_del_init(&inst->alg.cra_list);
        hlist_del(&inst->list);
        hlist_add_head(&inst->list, &tmpl->dead);
-       inst->alg.cra_destroy = crypto_destroy_instance;
 
        BUG_ON(!list_empty(&inst->alg.cra_users));
 
@@ -479,7 +484,8 @@ void crypto_unregister_alg(struct crypto_alg *alg)
        if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1))
                return;
 
-       crypto_alg_put(alg);
+       if (alg->cra_type && alg->cra_type->destroy)
+               alg->cra_type->destroy(alg);
 
        crypto_remove_final(&list);
 }
@@ -637,6 +643,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
 
        inst->alg.cra_module = tmpl->module;
        inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
+       inst->alg.cra_destroy = crypto_destroy_instance;
 
        down_write(&crypto_alg_sem);
 
index 3416e98128a059208d6288511bebd62adc46b160..2880aa04bb99309d00240657b4ed81af887733d3 100644 (file)
@@ -703,15 +703,5 @@ void crypto_req_done(void *data, int err)
 }
 EXPORT_SYMBOL_GPL(crypto_req_done);
 
-void crypto_destroy_alg(struct crypto_alg *alg)
-{
-       if (alg->cra_type && alg->cra_type->destroy)
-               alg->cra_type->destroy(alg);
-
-       if (alg->cra_destroy)
-               alg->cra_destroy(alg);
-}
-EXPORT_SYMBOL_GPL(crypto_destroy_alg);
-
 MODULE_DESCRIPTION("Cryptographic core API");
 MODULE_LICENSE("GPL");
index 11567ea24fc337388412fb91f20481dc4f03b3b4..2edefb546ad405f07dbf11730712736356204bbf 100644 (file)
@@ -128,7 +128,6 @@ void *crypto_create_tfm_node(struct crypto_alg *alg,
                        const struct crypto_type *frontend, int node);
 void *crypto_clone_tfm(const struct crypto_type *frontend,
                       struct crypto_tfm *otfm);
-void crypto_destroy_alg(struct crypto_alg *alg);
 
 static inline void *crypto_create_tfm(struct crypto_alg *alg,
                        const struct crypto_type *frontend)
@@ -166,7 +165,7 @@ static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
 static inline void crypto_alg_put(struct crypto_alg *alg)
 {
        if (refcount_dec_and_test(&alg->cra_refcnt))
-               crypto_destroy_alg(alg);
+               alg->cra_destroy(alg);
 }
 
 static inline int crypto_tmpl_get(struct crypto_template *tmpl)