From 8dd458cbc5be9ce4427ffce7a9dcdbff4dfc4ac9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 15 Nov 2024 09:29:02 +0800 Subject: crypto: api - Fix boot-up self-test race During the boot process self-tests are postponed so that all algorithms are registered when the test starts. In the event that algorithms are still being registered during these tests, which can occur either because the algorithm is registered at late_initcall, or because a self-test itself triggers the creation of an instance, some self-tests may never start at all. Fix this by setting the flag at the start of crypto_start_tests. Note that this race is theoretical and has never been observed in practice. Fixes: adad556efcdd ("crypto: api - Fix built-in testing dependency failures") Signed-off-by: Herbert Xu Signed-off-by: Herbert Xu --- crypto/algapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crypto/algapi.c') diff --git a/crypto/algapi.c b/crypto/algapi.c index 16f7c7a9d8ab..7e061d8a1d52 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -1016,6 +1016,8 @@ static void __init crypto_start_tests(void) if (IS_ENABLED(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)) return; + set_crypto_boot_test_finished(); + for (;;) { struct crypto_larval *larval = NULL; struct crypto_alg *q; @@ -1047,8 +1049,6 @@ static void __init crypto_start_tests(void) if (!larval) break; } - - set_crypto_boot_test_finished(); } static int __init crypto_algapi_init(void) -- cgit v1.2.3 From b7685262884c9aaedd622fab974c0820b62eb608 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 15 Nov 2024 09:56:28 +0800 Subject: crypto: api - Call crypto_schedule_test outside of mutex There is no need to hold the crypto mutex when scheduling a self- test. In fact prior to the patch introducing asynchronous testing, this was done outside of the locked area. Move the crypto_schedule_test call back out of the locked area. Also move crypto_remove_final to the else branch under the schedule- test call as the list of algorithms to be removed is non-empty only when the test larval is NULL (i.e., testing is disabled). Signed-off-by: Herbert Xu --- crypto/algapi.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'crypto/algapi.c') diff --git a/crypto/algapi.c b/crypto/algapi.c index 7e061d8a1d52..5318c214debb 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -407,6 +407,7 @@ EXPORT_SYMBOL_GPL(crypto_remove_final); int crypto_register_alg(struct crypto_alg *alg) { struct crypto_larval *larval; + bool test_started = false; LIST_HEAD(algs_to_put); int err; @@ -418,17 +419,19 @@ int crypto_register_alg(struct crypto_alg *alg) down_write(&crypto_alg_sem); larval = __crypto_register_alg(alg, &algs_to_put); if (!IS_ERR_OR_NULL(larval)) { - bool test_started = crypto_boot_test_finished(); - + test_started = crypto_boot_test_finished(); larval->test_started = test_started; - if (test_started) - crypto_schedule_test(larval); } up_write(&crypto_alg_sem); if (IS_ERR(larval)) return PTR_ERR(larval); - crypto_remove_final(&algs_to_put); + + if (test_started) + crypto_schedule_test(larval); + else + crypto_remove_final(&algs_to_put); + return 0; } EXPORT_SYMBOL_GPL(crypto_register_alg); @@ -642,10 +645,8 @@ int crypto_register_instance(struct crypto_template *tmpl, larval = __crypto_register_alg(&inst->alg, &algs_to_put); if (IS_ERR(larval)) goto unlock; - else if (larval) { + else if (larval) larval->test_started = true; - crypto_schedule_test(larval); - } hlist_add_head(&inst->list, &tmpl->instances); inst->tmpl = tmpl; @@ -655,7 +656,12 @@ unlock: if (IS_ERR(larval)) return PTR_ERR(larval); - crypto_remove_final(&algs_to_put); + + if (larval) + crypto_schedule_test(larval); + else + crypto_remove_final(&algs_to_put); + return 0; } EXPORT_SYMBOL_GPL(crypto_register_instance); @@ -1040,7 +1046,6 @@ static void __init crypto_start_tests(void) l->test_started = true; larval = l; - crypto_schedule_test(larval); break; } @@ -1048,6 +1053,8 @@ static void __init crypto_start_tests(void) if (!larval) break; + + crypto_schedule_test(larval); } } -- cgit v1.2.3