]> git.baikalelectronics.ru Git - kernel.git/commit
net/tls: fix race condition causing kernel panic
authorVinay Kumar Yadav <vinay.yadav@chelsio.com>
Fri, 22 May 2020 20:10:31 +0000 (01:40 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 26 May 2020 00:41:40 +0000 (17:41 -0700)
commite3146b54532cd571bde00a36172a5b5592be1a71
treeb70ced59cccdd83f314dcad840393c2026e6e557
parent2d12d0dfcbf951bc1cda180a944e18419c8fe944
net/tls: fix race condition causing kernel panic

tls_sw_recvmsg() and tls_decrypt_done() can be run concurrently.
// tls_sw_recvmsg()
if (atomic_read(&ctx->decrypt_pending))
crypto_wait_req(-EINPROGRESS, &ctx->async_wait);
else
reinit_completion(&ctx->async_wait.completion);

//tls_decrypt_done()
   pending = atomic_dec_return(&ctx->decrypt_pending);

   if (!pending && READ_ONCE(ctx->async_notify))
   complete(&ctx->async_wait.completion);

Consider the scenario tls_decrypt_done() is about to run complete()

if (!pending && READ_ONCE(ctx->async_notify))

and tls_sw_recvmsg() reads decrypt_pending == 0, does reinit_completion(),
then tls_decrypt_done() runs complete(). This sequence of execution
results in wrong completion. Consequently, for next decrypt request,
it will not wait for completion, eventually on connection close, crypto
resources freed, there is no way to handle pending decrypt response.

This race condition can be avoided by having atomic_read() mutually
exclusive with atomic_dec_return(),complete().Intoduced spin lock to
ensure the mutual exclution.

Addressed similar problem in tx direction.

v1->v2:
- More readable commit message.
- Corrected the lock to fix new race scenario.
- Removed barrier which is not needed now.

Fixes: b574142da9d5 ("net/tls: Add support for async encryption of records for performance")
Signed-off-by: Vinay Kumar Yadav <vinay.yadav@chelsio.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/tls.h
net/tls/tls_sw.c