From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
andrew+netdev@lunn.ch, horms@kernel.org, sd@queasysnail.net,
shuah@kernel.org, cel@kernel.org,
linux-kselftest@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net 2/5] tls: Consume empty data records in tls_sw_splice_read()
Date: Mon, 9 Nov 2026 09:58:33 -0800 [thread overview]
Message-ID: <20261109175836.1246840-3-kuba@kernel.org> (raw)
In-Reply-To: <20261109175836.1246840-1-kuba@kernel.org>
From: Chuck Lever <cel@kernel.org>
A zero-length application_data record decrypts to full_len == 0,
so tls_sw_splice_read() splices zero bytes and returns zero. A zero
return from a splice read means EOF, and the caller tears down a
connection that is still live.
Consume the record and fetch the next one, as tls_sw_read_sock()
does. The cap on consecutive empty records bounds the loop.
When an empty record precedes a close_notify, splice(2) now returns
-EINVAL from the control-record test instead of a false EOF. A
splice that reaches an alert record already reports -EINVAL.
Fixes: c46234ebb4d1 ("tls: RX path for ktls")
Reported-by: Sabrina Dubroca <sd@queasysnail.net>
Closes: https://lore.kernel.org/netdev/akaoXcfamBp8_mYe@krikkit/
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
Jakub:
- rewrite as a loop to avoid the non-error-handling goto
---
net/tls/tls_sw.c | 48 ++++++++++++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 20 deletions(-)
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index adf3b26b8a75..b05b9e76bd25 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -2044,32 +2044,40 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
if (err)
goto splice_read_end;
- if (!skb_queue_empty(&ctx->rx_list)) {
- skb = __skb_dequeue(&ctx->rx_list);
- } else {
- struct tls_decrypt_arg darg;
+ for (;;) {
+ if (!skb_queue_empty(&ctx->rx_list)) {
+ skb = __skb_dequeue(&ctx->rx_list);
+ } else {
+ struct tls_decrypt_arg darg;
- err = tls_rx_rec_wait(sk, nonblock, true, false);
- if (err <= 0)
- goto splice_read_end;
+ err = tls_rx_rec_wait(sk, nonblock, true, false);
+ if (err <= 0)
+ goto splice_read_end;
- memset(&darg.inargs, 0, sizeof(darg.inargs));
+ memset(&darg.inargs, 0, sizeof(darg.inargs));
- err = tls_rx_one_record(sk, NULL, &darg);
- if (err < 0)
- goto splice_read_end;
+ err = tls_rx_one_record(sk, NULL, &darg);
+ if (err < 0)
+ goto splice_read_end;
- tls_rx_rec_done(ctx);
- skb = darg.skb;
- }
+ tls_rx_rec_done(ctx);
+ skb = darg.skb;
+ }
- rxm = strp_msg(skb);
- tlm = tls_msg(skb);
+ rxm = strp_msg(skb);
+ tlm = tls_msg(skb);
- /* splice does not support reading control messages */
- if (tlm->control != TLS_RECORD_TYPE_DATA) {
- err = -EINVAL;
- goto splice_requeue;
+ /* splice does not support reading control messages */
+ if (tlm->control != TLS_RECORD_TYPE_DATA) {
+ err = -EINVAL;
+ goto splice_requeue;
+ }
+
+ /* Splicing zero bytes would read as EOF */
+ if (rxm->full_len)
+ break;
+
+ consume_skb(skb);
}
chunk = min_t(unsigned int, rxm->full_len, len);
--
2.56.0
next prev parent reply other threads:[~2026-11-09 17:58 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 17:58 [PATCH net 0/5] net: tls: break the connection after a burst of empty data records Jakub Kicinski
2026-11-09 17:58 ` [PATCH net 1/5] " Jakub Kicinski
2026-11-13 0:00 ` netdev-bot+sashiko
2026-11-09 17:58 ` Jakub Kicinski [this message]
2026-11-09 17:58 ` [PATCH net 3/5] selftests: tls: Skip the zero_len tests when TLS is unavailable Jakub Kicinski
2026-11-09 17:58 ` [PATCH net 4/5] selftests: tls: Extend coverage for zero-length records Jakub Kicinski
2026-11-13 0:00 ` netdev-bot+sashiko
2026-11-09 17:58 ` [PATCH net 5/5] selftests: tls: Cover the cap on consecutive empty records Jakub Kicinski
2026-11-09 20:16 ` [PATCH net 0/5] net: tls: break the connection after a burst of empty data records Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261109175836.1246840-3-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=cel@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sd@queasysnail.net \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.