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,
sashiko-bot <sashiko-bot@kernel.org>,
sashiko-bot <netdev-bot+sashiko@kernel.org>
Subject: [PATCH net-next v3 0/9] net/tls: Receive-path fixes for zero-length data records
Date: Wed, 07 Oct 2026 15:49:29 -0400 [thread overview]
Message-ID: <20261007-tls-follow-on-v3-0-6d52d98389b3@kernel.org> (raw)
Commit 3be28e2c9cd0 ("net/tls: Consume empty data records in
tls_sw_read_sock()") fixed one reader. TLS 1.2 and TLS 1.3 both
permit a zero-length application_data record as a traffic-analysis
countermeasure (RFC 5246, Section 6.2.1; RFC 8446, Section 5.1), so
a peer that pads its stream emits them by design. The other two
software readers still mishandle them. splice(2) reports an empty
record as EOF, and the caller tears down a connection that is still
live. recvmsg(2) makes no progress on one, so a peer that streams
them holds the caller in the kernel past SIGKILL. With MSG_PEEK or
async decryption, each record is also queued on rx_list, which
grows without bound.
This series supersedes "[PATCH net] tls: skip empty data records in
tls_sw_splice_read()", which fixes the splice case alone:
https://lore.kernel.org/netdev/20260930052636.166007-1-qingfang.deng@linux.dev/
Which fix a reader gets depends on its caller. splice(2) and
recvmsg(2) are system calls, so consuming the record and testing
signal_pending() is enough. A signal ends the call. An in-kernel
caller of sock_recvmsg() cannot take a signal, so a flood holds
that caller as it does today. Only tls_sw_read_sock() gets a bound
of its own. Its callers hold the socket lock across the whole call
and cannot act on a signal, so nothing else can stop the loop. A
count of consecutive records that deliver no bytes supplies the
bound (patch 1). The count is scoped to read_sock deliberately. A
flood on the other two paths costs the caller CPU time and nothing
else.
The series changes user-visible behavior. splice(2) on a
nonblocking socket, and sendfile(2) from one, now return -EAGAIN
where they used to block, as they do on a plain TCP socket. A
splice that reaches a control record behind an empty one now
returns -EINVAL rather than the zero that was the false EOF. A
nonblocking recvmsg(2) or splice(2) that has copied nothing and
finds a signal pending after an empty record returns -EINTR. A
recvmsg(2) that has copied data now returns at an empty record
rather than reading the records that follow.
SO_RCVTIMEO does not bound these calls. It is applied at the
reader lock and again on each call to tls_rx_rec_wait(), so a call
that keeps retrying can wait past it. recvmsg(2) behaves this way
today. The retry added to splice(2) extends the same behavior to
that path.
Tested on x86_64. The tls selftest suite passes, 937 tests with
no skips.
---
Changes in v3:
- Run the consumer's sk_data_ready() from a work item (sashiko).
- Move the sync decrypt of empty records to the signal patch (sashiko).
- Put the O_NONBLOCK patch before the splice retry patch (sashiko).
- Reword the O_NONBLOCK patch description to match (sashiko).
- Say that the recvmsg patch does not bound the receive loop (sashiko).
- Add a patch that returns copied data ahead of empty records (sashiko).
- Put the zero_len skip patch before the coverage patch (sashiko).
- Use poll() to check for records left on rx_list (sashiko).
- Link to v2: https://patch.msgid.link/20261001-tls-follow-on-v2-0-2dd1947bb642@kernel.org
Changes in v2:
- Bound no-data records by count, not elapsed time (Jakub).
- Drop the tls_rx_empty_data_rec() helper (Sabrina).
- Keep the strparser anchor out of tls_sw.c comments (Sabrina).
- Split the recvmsg signal test into its own patch.
- Drop tls_rx_intr_errno(); a nonblocking reader now gets -EINTR.
- Say why do_splice() misses the socket's O_NONBLOCK (Sabrina).
- Point the recvmsg patch's Fixes: at the commit that added rx_list.
- Reuse the new zero_len helpers in the existing fixture (Sabrina).
- Check errno unconditionally in the zero_len tests (Sabrina).
- Split the splice crypto-error fix and its test out (Jakub):
https://patch.msgid.link/20260806-tls-splice-crypto-fix-v1-0-a2624005a286@kernel.org
- Link to v1: https://patch.msgid.link/20260726-tls-follow-on-v1-0-99bf4cc1c729@kernel.org
---
Chuck Lever (9):
tls: Bound consecutive no-data records in tls_sw_read_sock()
tls: Check for a pending signal after an empty record
tls: Honor O_NONBLOCK in tls_sw_splice_read()
tls: Consume empty data records in tls_sw_splice_read()
tls: Consume empty data records in tls_sw_recvmsg()
tls: Return copied data ahead of a run of empty records
selftests: tls: Skip the zero_len tests when TLS is unavailable
selftests: tls: Add peek and splice coverage for zero-length records
selftests: tls: Cover splice on a nonblocking socket
include/net/tls.h | 1 +
net/tls/tls_sw.c | 98 +++++++++++++--
tools/testing/selftests/net/tls.c | 256 +++++++++++++++++++++++++++++++++++---
3 files changed, 328 insertions(+), 27 deletions(-)
---
base-commit: a5e7d8e446af9803e37a3b6a4d416fb41178348f
change-id: 20260726-tls-follow-on-486f1ba8bbb0
Best regards,
--
Chuck Lever <cel@kernel.org>
next 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 Chuck Lever [this message]
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 ` [PATCH net-next v3 3/9] tls: Honor O_NONBLOCK in tls_sw_splice_read() Chuck Lever
2026-10-07 19:49 ` [PATCH net-next v3 4/9] tls: Consume empty data records " 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-0-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-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=qingfang.deng@linux.dev \
--cc=sashiko-bot@kernel.org \
--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