]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: api - Allow delayed algorithm destruction
authorHerbert Xu <herbert@gondor.apana.org.au>
Wed, 9 Apr 2025 03:29:03 +0000 (11:29 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 16 Apr 2025 07:16:22 +0000 (15:16 +0800)
The current algorithm unregistration mechanism originated from
software crypto.  The code relies on module reference counts to
stop in-use algorithms from being unregistered.  Therefore if
the unregistration function is reached, it is assumed that the
module reference count has hit zero and thus the algorithm reference
count should be exactly 1.

This is completely broken for hardware devices, which can be
unplugged at random.

Fix this by allowing algorithms to be destroyed later if a destroy
callback is provided.

Reported-by: Sean Anderson <sean.anderson@linux.dev>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/algapi.c

index 5b8a4c78738796f100029cd9ddf5ec8a027c940e..f368c0dc0d6d22a1b8b1626d236f33dd725d4772 100644 (file)
@@ -481,10 +481,10 @@ void crypto_unregister_alg(struct crypto_alg *alg)
        if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name))
                return;
 
-       if (WARN_ON(refcount_read(&alg->cra_refcnt) != 1))
-               return;
-
-       if (alg->cra_type && alg->cra_type->destroy)
+       if (alg->cra_destroy)
+               crypto_alg_put(alg);
+       else if (!WARN_ON(refcount_read(&alg->cra_refcnt) != 1) &&
+                alg->cra_type && alg->cra_type->destroy)
                alg->cra_type->destroy(alg);
 
        crypto_remove_final(&list);