]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
crypto: api - Fix larval relookup type and mask
authorHerbert Xu <herbert@gondor.apana.org.au>
Fri, 14 Feb 2025 02:31:25 +0000 (10:31 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Sat, 22 Feb 2025 07:56:03 +0000 (15:56 +0800)
When the lookup is retried after instance construction, it uses
the type and mask from the larval, which may not match the values
used by the caller.  For example, if the caller is requesting for
a !NEEDS_FALLBACK algorithm, it may end up getting an algorithm
that needs fallbacks.

Fix this by making the caller supply the type/mask and using that
for the lookup.

Reported-by: Coiby Xu <coxu@redhat.com>
Fixes: 96ad59552059 ("crypto: api - Remove instance larval fulfilment")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/api.c

index bfd177a4313a01bc5c2953722be2384c31d468a3..c2c4eb14ef955f0761ea442b399307a44933daa5 100644 (file)
@@ -36,7 +36,8 @@ EXPORT_SYMBOL_GPL(crypto_chain);
 DEFINE_STATIC_KEY_FALSE(__crypto_boot_test_finished);
 #endif
 
-static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
+static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg,
+                                            u32 type, u32 mask);
 static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
                                            u32 mask);
 
@@ -145,7 +146,7 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
        if (alg != &larval->alg) {
                kfree(larval);
                if (crypto_is_larval(alg))
-                       alg = crypto_larval_wait(alg);
+                       alg = crypto_larval_wait(alg, type, mask);
        }
 
        return alg;
@@ -197,7 +198,8 @@ static void crypto_start_test(struct crypto_larval *larval)
        crypto_schedule_test(larval);
 }
 
-static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
+static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg,
+                                            u32 type, u32 mask)
 {
        struct crypto_larval *larval;
        long time_left;
@@ -219,12 +221,7 @@ again:
                        crypto_larval_kill(larval);
                alg = ERR_PTR(-ETIMEDOUT);
        } else if (!alg) {
-               u32 type;
-               u32 mask;
-
                alg = &larval->alg;
-               type = alg->cra_flags & ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
-               mask = larval->mask;
                alg = crypto_alg_lookup(alg->cra_name, type, mask) ?:
                      ERR_PTR(-EAGAIN);
        } else if (IS_ERR(alg))
@@ -304,7 +301,7 @@ static struct crypto_alg *crypto_larval_lookup(const char *name, u32 type,
        }
 
        if (!IS_ERR_OR_NULL(alg) && crypto_is_larval(alg))
-               alg = crypto_larval_wait(alg);
+               alg = crypto_larval_wait(alg, type, mask);
        else if (alg)
                ;
        else if (!(mask & CRYPTO_ALG_TESTED))
@@ -352,7 +349,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
        ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval);
 
        if (ok == NOTIFY_STOP)
-               alg = crypto_larval_wait(larval);
+               alg = crypto_larval_wait(larval, type, mask);
        else {
                crypto_mod_put(larval);
                alg = ERR_PTR(-ENOENT);