Re: [PATCH] crypto: api - Fix built-in testing dependency failures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Sep 13, 2021 at 03:12:51PM +0800, Herbert Xu wrote:
> When complex algorithms that depend on other algorithms are built
> into the kernel, the order of registration must be done such that
> the underlying algorithms are ready before the ones on top are
> registered.  As otherwise they would fail during the self-test
> which is required during registration.
> 
> In the past we have used subsystem initialisation ordering to
> guarantee this.  The number of such precedence levels are limited
> and they may cause ripple effects in other subsystems.
> 
> This patch solves this problem by delaying all self-tests during
> boot-up for built-in algorithms.  They will be tested either when
> something else in the kernel requests for them, or when we have
> finished registering all built-in algorithms, whichever comes
> earlier.

Are there any specific examples that you could give?

>  int crypto_register_alg(struct crypto_alg *alg)
>  {
>  	struct crypto_larval *larval;
> +	bool tested;
>  	int err;
>  
>  	alg->cra_flags &= ~CRYPTO_ALG_DEAD;
> @@ -421,12 +402,15 @@ int crypto_register_alg(struct crypto_alg *alg)
>  
>  	down_write(&crypto_alg_sem);
>  	larval = __crypto_register_alg(alg);
> +	tested = static_key_enabled(&crypto_boot_test_finished);
> +	larval->tested = tested;

'tested' is set before the algorithm has actually been tested, and it sounds
like the same as CRYPTO_ALG_TESTED which already exists.  Maybe it should be
called something else, like 'test_started'?

> +static void __init crypto_start_tests(void)
> +{
> +	for (;;) {
> +		struct crypto_larval *larval = NULL;
> +		struct crypto_alg *q;
> +
> +		down_write(&crypto_alg_sem);
> +
> +		list_for_each_entry(q, &crypto_alg_list, cra_list) {
> +			struct crypto_larval *l;
> +
> +			if (!crypto_is_larval(q))
> +				continue;
> +
> +			l = (void *)q;
> +
> +			if (!crypto_is_test_larval(l))
> +				continue;
> +
> +			if (l->tested)
> +				continue;
> +
> +			l->tested = true;
> +			larval = l;
> +			break;
> +		}
> +
> +		up_write(&crypto_alg_sem);
> +
> +		if (!larval)
> +			break;
> +
> +		crypto_wait_for_test(larval);
> +	}

Is there a way to continue iterating from the previous algorithm, so that this
doesn't take quadratic time?

> +
> +	static_branch_enable(&crypto_boot_test_finished);
> +}
> +
>  static int __init crypto_algapi_init(void)
>  {
>  	crypto_init_proc();
> +	crypto_start_tests();

A comment explaining why the tests aren't run until late_initcall would be
helpful.  People shouldn't have to dig through commit messages to understand the
code.

Also, did you check whether there is anything that relies on the crypto API
being available before or during late_initcall?  That wouldn't work with this
new approach, right?

- Eric



[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux