summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSabrina Dubroca <sd@queasysnail.net>2024-02-28 23:43:59 +0100
committerJakub Kicinski <kuba@kernel.org>2024-02-29 09:07:16 -0800
commit41532b785e9d79636b3815a64ddf6a096647d011 (patch)
treedf26ff713718d54e616ada4c47a1abbec90fb8fd
parent6caaf104423d809b49a67ee6500191d063b40dc6 (diff)
downloadlinux-41532b785e9d79636b3815a64ddf6a096647d011.tar.gz
linux-41532b785e9d79636b3815a64ddf6a096647d011.tar.bz2
linux-41532b785e9d79636b3815a64ddf6a096647d011.zip
tls: separate no-async decryption request handling from async
If we're not doing async, the handling is much simpler. There's no reference counting, we just need to wait for the completion to wake us up and return its result. We should preferably also use a separate crypto_wait. I'm not seeing a UAF as I did in the past, I think aec7961916f3 ("tls: fix race between async notify and socket close") took care of it. This will make the next fix easier. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://lore.kernel.org/r/47bde5f649707610eaef9f0d679519966fc31061.1709132643.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/tls/tls_sw.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 1394fc44f378..1fd37fe13ffd 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -274,9 +274,15 @@ static int tls_do_decryption(struct sock *sk,
DEBUG_NET_WARN_ON_ONCE(atomic_read(&ctx->decrypt_pending) < 1);
atomic_inc(&ctx->decrypt_pending);
} else {
+ DECLARE_CRYPTO_WAIT(wait);
+
aead_request_set_callback(aead_req,
CRYPTO_TFM_REQ_MAY_BACKLOG,
- crypto_req_done, &ctx->async_wait);
+ crypto_req_done, &wait);
+ ret = crypto_aead_decrypt(aead_req);
+ if (ret == -EINPROGRESS || ret == -EBUSY)
+ ret = crypto_wait_req(ret, &wait);
+ return ret;
}
ret = crypto_aead_decrypt(aead_req);
@@ -285,10 +291,7 @@ static int tls_do_decryption(struct sock *sk,
ret = ret ?: -EINPROGRESS;
}
if (ret == -EINPROGRESS) {
- if (darg->async)
- return 0;
-
- ret = crypto_wait_req(ret, &ctx->async_wait);
+ return 0;
} else if (darg->async) {
atomic_dec(&ctx->decrypt_pending);
}