From: Chuck Lever <cel@kernel.org>
To: John Fastabend <john.fastabend@gmail.com>,
Jakub Kicinski <kuba@kernel.org>,
Sabrina Dubroca <sd@queasysnail.net>,
"David S. Miller" <davem@davemloft.net>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
Chuck Lever <cel@kernel.org>, Dave Watson <davejwatson@fb.com>,
Shuah Khan <shuah@kernel.org>,
Qingfang Deng <qingfang.deng@linux.dev>,
Eric Dumazet <edumazet@kernel.org>
Cc: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [PATCH net-next v3 3/9] tls: Honor O_NONBLOCK in tls_sw_splice_read()
Date: Wed, 07 Oct 2026 15:49:32 -0400 [thread overview]
Message-ID: <20261007-tls-follow-on-v3-3-6d52d98389b3@kernel.org> (raw)
In-Reply-To: <20261007-tls-follow-on-v3-0-6d52d98389b3@kernel.org>
tls_sw_splice_read() takes its blocking behavior from
SPLICE_F_NONBLOCK alone. When splicing from a socket to a pipe,
do_splice() sets that flag from the pipe's O_NONBLOCK, not the
socket's. On a nonblocking socket, a splice(2) call without
SPLICE_F_NONBLOCK therefore sleeps in tls_rx_rec_wait() until a
record arrives. tcp_splice_read() instead reads sock->file->f_flags
and returns -EAGAIN.
Polling first does not avoid the sleep once tls_sw_splice_read()
consumes zero-length records. tls_sw_sock_is_readable() reports
the socket readable while any record sits on rx_list, including a
zero-length record that delivers no bytes to the pipe. The
strparser announces a record before decryption, when the record's
plaintext length is unknown, so the readiness test cannot screen
such a record out. A splice that consumes the record and waits for
the next stalls every connection an event loop multiplexes.
An LLM audit of the TLS read paths found this defect. With empty
records consumed, the zero_len_splice selftest, run on a
nonblocking socket, reproduces the sleep.
Treat the socket's O_NONBLOCK as nonblocking too. A caller that
sets O_NONBLOCK on the socket and splices without SPLICE_F_NONBLOCK
now gets -EAGAIN where the splice blocked before. sendfile(2) from
a TLS socket changes the same way, because do_sendfile() leaves the
input file's O_NONBLOCK out of the splice flags. Both now behave as
they do on a plain TCP socket.
Fixes: c46234ebb4d1 ("tls: RX path for ktls")
Signed-off-by: Chuck Lever <cel@kernel.org>
---
net/tls/tls_sw.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 32be5a8f80ed..6c21897b03ee 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -2022,10 +2022,14 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
struct tls_msg *tlm;
struct sk_buff *skb;
ssize_t copied = 0;
+ bool nonblock;
int chunk;
int err;
- err = tls_rx_reader_lock(sk, ctx, flags & SPLICE_F_NONBLOCK);
+ nonblock = (flags & SPLICE_F_NONBLOCK) ||
+ (sock->file->f_flags & O_NONBLOCK);
+
+ err = tls_rx_reader_lock(sk, ctx, nonblock);
if (err < 0)
return err;
@@ -2039,8 +2043,7 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
} else {
struct tls_decrypt_arg darg;
- err = tls_rx_rec_wait(sk, flags & SPLICE_F_NONBLOCK,
- true, false);
+ err = tls_rx_rec_wait(sk, nonblock, true, false);
if (err <= 0)
goto splice_read_end;
--
2.55.0
next prev parent reply other threads:[~2026-10-07 19:49 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 19:49 [PATCH net-next v3 0/9] net/tls: Receive-path fixes for zero-length data records Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 1/9] tls: Bound consecutive no-data records in tls_sw_read_sock() Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 2/9] tls: Check for a pending signal after an empty record Chuck Lever
2026-10-07 19:49 ` Chuck Lever [this message]
2026-10-07 19:49 ` [PATCH net-next v3 4/9] tls: Consume empty data records in tls_sw_splice_read() Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 5/9] tls: Consume empty data records in tls_sw_recvmsg() Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 6/9] tls: Return copied data ahead of a run of empty records Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 7/9] selftests: tls: Skip the zero_len tests when TLS is unavailable Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 8/9] selftests: tls: Add peek and splice coverage for zero-length records Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 9/9] selftests: tls: Cover splice on a nonblocking socket 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=20261007-tls-follow-on-v3-3-6d52d98389b3@kernel.org \
--to=cel@kernel.org \
--cc=davejwatson@fb.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=qingfang.deng@linux.dev \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox