| From: Eric Biggers <ebiggers@google.com> |
| Date: Tue, 2 Jul 2019 14:17:00 -0700 |
| Subject: crypto: user - prevent operating on larval algorithms |
| |
| commit 21d4120ec6f5b5992b01b96ac484701163917b63 upstream. |
| |
| Michal Suchanek reported [1] that running the pcrypt_aead01 test from |
| LTP [2] in a loop and holding Ctrl-C causes a NULL dereference of |
| alg->cra_users.next in crypto_remove_spawns(), via crypto_del_alg(). |
| The test repeatedly uses CRYPTO_MSG_NEWALG and CRYPTO_MSG_DELALG. |
| |
| The crash occurs when the instance that CRYPTO_MSG_DELALG is trying to |
| unregister isn't a real registered algorithm, but rather is a "test |
| larval", which is a special "algorithm" added to the algorithms list |
| while the real algorithm is still being tested. Larvals don't have |
| initialized cra_users, so that causes the crash. Normally pcrypt_aead01 |
| doesn't trigger this because CRYPTO_MSG_NEWALG waits for the algorithm |
| to be tested; however, CRYPTO_MSG_NEWALG returns early when interrupted. |
| |
| Everything else in the "crypto user configuration" API has this same bug |
| too, i.e. it inappropriately allows operating on larval algorithms |
| (though it doesn't look like the other cases can cause a crash). |
| |
| Fix this by making crypto_alg_match() exclude larval algorithms. |
| |
| [1] https://lkml.kernel.org/r/20190625071624.27039-1-msuchanek@suse.de |
| [2] https://github.com/linux-test-project/ltp/blob/20190517/testcases/kernel/crypto/pcrypt_aead01.c |
| |
| Reported-by: Michal Suchanek <msuchanek@suse.de> |
| Fixes: a38f7907b926 ("crypto: Add userspace configuration API") |
| Cc: Steffen Klassert <steffen.klassert@secunet.com> |
| Signed-off-by: Eric Biggers <ebiggers@google.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| [bwh: Backported to 3.16: adjust filename] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| crypto/crypto_user.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/crypto/crypto_user.c |
| +++ b/crypto/crypto_user.c |
| @@ -53,6 +53,9 @@ static struct crypto_alg *crypto_alg_mat |
| list_for_each_entry(q, &crypto_alg_list, cra_list) { |
| int match = 0; |
| |
| + if (crypto_is_larval(q)) |
| + continue; |
| + |
| if ((q->cra_flags ^ p->cru_type) & p->cru_mask) |
| continue; |
| |