Re: [v3 PATCH] crypto: api - fix unexpectedly getting generic implementation

Eric Biggers
2019-12-05T04:04:45Z

On Thu, Dec 05, 2019 at 09:58:11AM +0800, Herbert Xu wrote:
> + /* Only satisfy larval waiters if we are the best. */
> + list_for_each_entry(q, &crypto_alg_list, cra_list) {
> + struct crypto_larval *larval;
> +
> + if (crypto_is_moribund(q) || !crypto_is_larval(q))
> + continue;
> +
> + if (strcmp(alg->cra_name, q->cra_name))
> + continue;
> +
> + larval = (void *)q;
> + if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
> + continue;
> +
> + if (q->cra_priority > alg->cra_priority)
> + goto complete;
> + }
> +

This logic doesn't make sense to me either. It's supposed to be looking for a
"test larval", not a "request larval", right? But it seems that larval->mask is
always 0 for "test larvals", so the flags check will never do anything...

Also, different "request larvals" can use different flags and masks. So I don't
think it's possible to know whether 'q' can fulfill every outstanding request
that 'alg' can without actually going through and looking at the requests. So
that's another case where users can start incorrectly getting ENOENT.

If we don't try to skip setting larval->adult, but rather override the existing
value (as my patch does), the incorrect ENOENTs are prevented.

- Eric