linux/crypto
Herbert Xu e7a4142b35 crypto: api - Fix generic algorithm self-test races
On Fri, Aug 30, 2024 at 10:51:54AM -0700, Eric Biggers wrote:
>
> Given below in defconfig form, use 'make olddefconfig' to apply.  The failures
> are nondeterministic and sometimes there are different ones, for example:
>
> [    0.358017] alg: skcipher: failed to allocate transform for cbc(twofish-generic): -2
> [    0.358365] alg: self-tests for cbc(twofish) using cbc(twofish-generic) failed (rc=-2)
> [    0.358535] alg: skcipher: failed to allocate transform for cbc(camellia-generic): -2
> [    0.358918] alg: self-tests for cbc(camellia) using cbc(camellia-generic) failed (rc=-2)
> [    0.371533] alg: skcipher: failed to allocate transform for xts(ecb(aes-generic)): -2
> [    0.371922] alg: self-tests for xts(aes) using xts(ecb(aes-generic)) failed (rc=-2)
>
> Modules are not enabled, maybe that matters (I haven't checked yet).

Yes I think that was the key.  This triggers a massive self-test
run which executes in parallel and reveals a few race conditions
in the system.  I think it boils down to the following scenario:

Base algorithm X-generic, X-optimised
Template Y
Optimised algorithm Y-X-optimised

Everything gets registered, and then the self-tests are started.
When Y-X-optimised gets tested, it requests the creation of the
generic Y(X-generic).  Which then itself undergoes testing.

The race is that after Y(X-generic) gets registered, but just
before it gets tested, X-optimised finally finishes self-testing
which then causes all spawns of X-generic to be destroyed.  So
by the time the self-test for Y(X-generic) comes along, it can
no longer find the algorithm.  This error then bubbles up all
the way up to the self-test of Y-X-optimised which then fails.

Note that there is some complexity that I've omitted here because
when the generic self-test fails to find Y(X-generic) it actually
triggers the construction of it again which then fails for various
other reasons (these are not important because the construction
should *not* be triggered at this point).

So in a way the error is expected, and we should probably remove
the pr_err for the case where ENOENT is returned for the algorithm
that we're currently testing.

The solution is two-fold.  First when an algorithm undergoes
self-testing it should not trigger its construction.  Secondly
if an instance larval fails to materialise due to it being destroyed
by a more optimised algorithm coming along, it should obviously
retry the construction.

Remove the check in __crypto_alg_lookup that stops a larval from
matching new requests based on differences in the mask.  It is better
to block new requests even if it is wrong and then simply retry the
lookup.  If this ends up being the wrong larval it will sort iself
out during the retry.

Reduce the CRYPTO_ALG_TYPE_MASK bits in type during larval creation
as otherwise LSKCIPHER algorithms may not match SKCIPHER larvals.

Also block the instance creation during self-testing in the function
crypto_larval_lookup by checking for CRYPTO_ALG_TESTED in the mask
field.

Finally change the return value when crypto_alg_lookup fails in
crypto_larval_wait to EAGAIN to redo the lookup.

Fixes: 37da5d0ffa ("crypto: api - Do not wait for tests during registration")
Reported-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2024-09-06 14:50:46 +08:00
..
asymmetric_keys crypto: sm2 - Remove sm2 algorithm 2024-06-07 19:46:39 +08:00
async_tx
842.c
acompress.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
adiantum.c crypto: adiantum - flush destination page before unmapping 2023-11-01 12:58:42 +08:00
aead.c crypto: aead,cipher - zeroize key buffer after use 2024-04-26 17:26:09 +08:00
aegis128-core.c
aegis128-neon-inner.c crypto: aegis128-neon - add header for internal prototypes 2023-05-24 18:12:33 +08:00
aegis128-neon.c crypto: aegis128-neon - add header for internal prototypes 2023-05-24 18:12:33 +08:00
aegis-neon.h crypto: aegis128-neon - add header for internal prototypes 2023-05-24 18:12:33 +08:00
aegis.h
aes_generic.c
aes_ti.c
af_alg.c crypto: Add missing MODULE_DESCRIPTION() macros 2024-05-31 17:34:56 +08:00
ahash.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
akcipher.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
algapi.c crypto: api - Do not wait for tests during registration 2024-08-24 21:39:15 +08:00
algboss.c crypto: api - Remove instance larval fulfilment 2024-08-24 21:39:15 +08:00
algif_aead.c sock: Remove ->sendpage*() in favour of sendmsg(MSG_SPLICE_PAGES) 2023-06-24 15:50:13 -07:00
algif_hash.c crypto: Add missing MODULE_DESCRIPTION() macros 2024-05-31 17:34:56 +08:00
algif_rng.c sock: Remove ->sendpage*() in favour of sendmsg(MSG_SPLICE_PAGES) 2023-06-24 15:50:13 -07:00
algif_skcipher.c crypto: Add missing MODULE_DESCRIPTION() macros 2024-05-31 17:34:56 +08:00
ansi_cprng.c
anubis.c
api.c crypto: api - Fix generic algorithm self-test races 2024-09-06 14:50:46 +08:00
arc4.c crypto: arc4 - Add internal state 2023-12-08 11:59:46 +08:00
aria_generic.c
authenc.c crypto: authenc - stop using alignmask of ahash 2023-10-27 18:04:29 +08:00
authencesn.c crypto: authencesn - stop using alignmask of ahash 2023-10-27 18:04:29 +08:00
blake2b_generic.c treewide: update LLVM Bugzilla links 2024-02-22 15:38:51 -08:00
blowfish_common.c
blowfish_generic.c
bpf_crypto_skcipher.c bpf: crypto: add skcipher to bpf crypto 2024-04-24 16:01:10 -07:00
camellia_generic.c
cast5_generic.c
cast6_generic.c
cast_common.c crypto: Add missing MODULE_DESCRIPTION() macros 2024-05-31 17:34:56 +08:00
cbc.c crypto: cbc - Ensure statesize is zero 2024-02-02 18:08:12 +08:00
ccm.c crypto: ccm - stop using alignmask of ahash 2023-10-27 18:04:29 +08:00
chacha20poly1305.c crypto: chacha20poly1305 - Annotate struct chachapoly_ctx with __counted_by() 2024-08-17 13:55:49 +08:00
chacha_generic.c
cipher.c crypto: aead,cipher - zeroize key buffer after use 2024-04-26 17:26:09 +08:00
cmac.c crypto: cmac - remove unnecessary alignment logic 2023-10-27 18:04:24 +08:00
compress.c
compress.h crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
crc32_generic.c
crc32c_generic.c
crc64_rocksoft_generic.c
crct10dif_common.c
crct10dif_generic.c
cryptd.c crypto: cryptd - Only access common skcipher fields on spawn 2023-10-13 18:27:26 +08:00
crypto_engine.c crypto: engine - Make crypto_engine_exit() return void 2023-10-01 16:28:15 +08:00
crypto_null.c
crypto_user.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
ctr.c crypto: ctr - Only access common skcipher fields on spawn 2023-10-13 18:27:27 +08:00
cts.c crypto: cts - Only access common skcipher fields on spawn 2023-10-13 18:27:27 +08:00
curve25519-generic.c crypto: Add missing MODULE_DESCRIPTION() macros 2024-05-31 17:34:56 +08:00
deflate.c crypto: deflate - Add aliases to deflate 2024-06-28 11:35:47 +10:00
des_generic.c
dh_helper.c
dh.c crypto: dh - Check mpi_rshift errors 2024-08-17 13:55:50 +08:00
drbg.c crypto: drbg - Remove SHA1 from drbg 2023-11-17 19:16:29 +08:00
ecb.c crypto: skcipher - Add internal state support 2023-12-08 11:59:46 +08:00
ecc_curve_defs.h crypto: ecc - Add NIST P521 curve parameters 2024-04-12 15:07:52 +08:00
ecc.c crypto: ecc - Fix off-by-one missing to clear most significant digit 2024-06-16 13:41:53 +08:00
ecdh_helper.c
ecdh.c crypto: ecdh - Initialize ctx->private_key in proper byte order 2024-04-26 17:26:09 +08:00
ecdsa.c crypto: ecdsa - Use ecc_digits_from_bytes to convert signature 2024-06-07 19:46:39 +08:00
ecdsasignature.asn1
echainiv.c
ecrdsa_defs.h crypto: ecc - Add nbits field to ecc_curve structure 2024-04-12 15:07:52 +08:00
ecrdsa_params.asn1
ecrdsa_pub_key.asn1
ecrdsa.c crypto: ecrdsa - Fix module auto-load on add_key 2024-04-02 10:49:38 +08:00
essiv.c crypto: essiv - Handle lskcipher spawns 2023-10-13 18:27:26 +08:00
fcrypt.c
fips.c crypto: fips - Remove the now superfluous sentinel element from ctl_table array 2024-04-05 15:46:33 +08:00
gcm.c crypto: gcm - stop using alignmask of ahash 2023-10-27 18:04:29 +08:00
geniv.c
ghash-generic.c
hash_info.c crypto: FIPS 202 SHA-3 register in hash info for IMA 2023-10-27 18:04:30 +08:00
hash.h crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
hctr2.c crypto: hctr2 - stop using alignmask of shash_alg 2023-10-27 18:04:25 +08:00
hmac.c crypto: hmac - remove unnecessary alignment logic 2023-10-27 18:04:24 +08:00
internal.h crypto: api - Do not wait for tests during registration 2024-08-24 21:39:15 +08:00
jitterentropy-kcapi.c crypto: jitter - Use kvfree_sensitive() to fix Coccinelle warning 2024-04-05 15:46:33 +08:00
jitterentropy-testing.c crypto: jitter - add interface for gathering of raw entropy 2023-05-12 18:48:01 +08:00
jitterentropy.c crypto: jitter - Use min() to simplify jent_read_entropy() 2024-08-30 18:22:30 +08:00
jitterentropy.h crypto: jitter - reuse allocated entropy collector 2023-10-13 18:31:07 +08:00
Kconfig crypto: jitter - set default OSR to 3 2024-08-24 21:36:07 +08:00
kdf_sp800108.c
keywrap.c
khazad.c
kpp.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
lrw.c crypto: lrw - Only access common skcipher fields on spawn 2023-10-13 18:27:27 +08:00
lskcipher.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
lz4.c
lz4hc.c
lzo-rle.c
lzo.c
Makefile crypto: sm2 - Remove sm2 algorithm 2024-06-07 19:46:39 +08:00
md4.c
md5.c
michael_mic.c
nhpoly1305.c
pcbc.c crypto: pcbc - remove redundant assignment to nbytes 2024-01-26 16:39:32 +08:00
pcrypt.c crypto: pcrypt - Fix hungtask for PADATA_RESET 2023-09-15 18:29:45 +08:00
poly1305_generic.c
polyval-generic.c
proc.c
ripemd.h
rmd160.c
rng.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
rsa_helper.c
rsa-pkcs1pad.c crypto: rsa-pkcs1pad - Add FIPS 202 SHA-3 support 2023-10-27 18:04:30 +08:00
rsa.c crypto: rsa - Check MPI allocation errors 2024-08-17 13:55:50 +08:00
rsaprivkey.asn1 treewide: Add SPDX identifier to IETF ASN.1 modules 2023-10-27 18:04:28 +08:00
rsapubkey.asn1 treewide: Add SPDX identifier to IETF ASN.1 modules 2023-10-27 18:04:28 +08:00
scatterwalk.c
scompress.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
seed.c
seqiv.c
serpent_generic.c
sha1_generic.c
sha3_generic.c
sha256_generic.c
sha512_generic.c
shash.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
sig.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
simd.c crypto: simd - Do not call crypto_alloc_tfm during registration 2024-08-24 21:39:15 +08:00
skcipher.c crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
skcipher.h crypto: remove CONFIG_CRYPTO_STATS 2024-04-02 10:49:38 +08:00
sm3_generic.c
sm3.c
sm4_generic.c
sm4.c
streebog_generic.c
tcrypt.c crypto: tcrypt - add skcipher speed for given alg 2024-06-28 11:35:46 +10:00
tcrypt.h
tea.c
testmgr.c crypto: testmgr - generate power-of-2 lengths more often 2024-07-13 11:50:28 +12:00
testmgr.h crypto: sm2 - Remove sm2 algorithm 2024-06-07 19:46:39 +08:00
twofish_common.c
twofish_generic.c
vmac.c crypto: vmac - don't set alignmask 2023-10-27 18:04:24 +08:00
wp512.c
xcbc.c crypto: xcbc - remove unnecessary alignment logic 2023-10-27 18:04:25 +08:00
xctr.c
xor.c crypto: xor - fix template benchmarking 2024-08-02 20:53:25 +08:00
xts.c crypto: xts - use 'spawn' for underlying single-block cipher 2023-10-20 13:39:25 +08:00
xxhash_generic.c
zstd.c