From: Chuck Lever <cel@kernel.org>
To: Trond Myklebust <trondmy@kernel.org>,
Anna Schumaker <anna@kernel.org>,
Jeff Layton <jlayton@kernel.org>, NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>
Cc: linux-nfs@vger.kernel.org, netdev@vger.kernel.org,
Chuck Lever <cel@kernel.org>
Subject: [PATCH 2/5] SUNRPC: Close the transport on an unhandled TLS record type
Date: Fri, 21 Aug 2026 13:22:40 -0400 [thread overview]
Message-ID: <20260821-tls-read-sock-2-v1-2-7ffce164eb45@kernel.org> (raw)
In-Reply-To: <20260821-tls-read-sock-2-v1-0-7ffce164eb45@kernel.org>
svc_tcp_sock_recv_cmsg() drains a TLS record that is neither an alert
nor application data, then returns -EAGAIN so the receive loop retries.
It runs only on an established TLS session. A handshake record there
carries a post-handshake message, and the server has no handler for
one. Draining a KeyUpdate only delays the close. kTLS sets
key_update_pending when it decrypts that record, and a later receive
returns -EKEYEXPIRED. kTLS flags only a KeyUpdate, so any other
post-handshake message disappears and the connection keeps running.
Return -EPROTO for an unhandled record type. Any error but -EAGAIN
closes the transport. An application data record keeps its -EAGAIN
return. No NFS client is known to send a handshake record on an
established connection.
Signed-off-by: Chuck Lever <cel@kernel.org>
---
net/sunrpc/svcsock.c | 47 +++++++----------------------------------------
1 file changed, 7 insertions(+), 40 deletions(-)
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index b402923c40f1..ae1f3c474f8b 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -238,39 +238,6 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining)
return len;
}
-/*
- * kTLS delivers a record only up to the caller's buffer and keeps
- * the remainder on its receive list, where no further data_ready
- * announces it. Consume the whole record.
- */
-static void
-svc_tcp_sock_drain_record(struct socket *sock)
-{
- union {
- struct cmsghdr cmsg;
- u8 buf[CMSG_SPACE(sizeof(u8))];
- } u;
- u8 discard[64];
- struct kvec discard_kvec = {
- .iov_base = discard,
- .iov_len = sizeof(discard),
- };
-
- for (;;) {
- struct msghdr msg = {
- .msg_control = &u,
- .msg_controllen = sizeof(u),
- };
-
- iov_iter_kvec(&msg.msg_iter, ITER_DEST, &discard_kvec, 1,
- discard_kvec.iov_len);
- if (sock_recvmsg(sock, &msg, MSG_DONTWAIT) <= 0)
- break;
- if (msg.msg_flags & MSG_EOR)
- break;
- }
-}
-
static int svc_tcp_recv_cmsg(struct socket *sock, int flags,
struct kvec *payload, u8 *type,
unsigned int *msg_flags)
@@ -312,14 +279,14 @@ svc_tcp_sock_recv_cmsg(struct socket *sock)
&msg_flags);
if (ret < 0 || !type)
return ret;
- if (type != TLS_RECORD_TYPE_ALERT) {
- /* An application data record carries RPC payload.
- * Draining one breaks RPC fragment framing.
- */
- if (type != TLS_RECORD_TYPE_DATA && !(msg_flags & MSG_EOR))
- svc_tcp_sock_drain_record(sock);
+ /* A data record reaches here only when kTLS queued an empty one
+ * ahead of the control record. Consuming it takes no payload,
+ * and the retry picks up the control record.
+ */
+ if (type == TLS_RECORD_TYPE_DATA)
return -EAGAIN;
- }
+ if (type != TLS_RECORD_TYPE_ALERT)
+ return -EPROTO;
/* An Alert record carries exactly one two-octet message (RFC
* 8446 Section 5.1). recv_kvec caps the receive at two, so a
* longer record produces the same count. MSG_EOR appears only
--
2.54.0
next prev parent reply other threads:[~2026-08-21 17:22 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-21 17:22 [PATCH 0/5] SUNRPC: Receive svcsock TCP records with ->read_sock Chuck Lever
2026-08-21 17:22 ` [PATCH 1/5] SUNRPC: Separate the TLS control-record receive from its policy Chuck Lever
2026-08-21 17:22 ` Chuck Lever [this message]
2026-08-21 17:22 ` [PATCH 3/5] SUNRPC: Flush a received record's pages once it is complete Chuck Lever
2026-08-21 17:22 ` [PATCH 4/5] SUNRPC: Receive RPC records with ->read_sock Chuck Lever
2026-08-21 17:22 ` [PATCH 5/5] SUNRPC: Bypass sock_recvmsg() for the TLS control-record receive 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=20260821-tls-read-sock-2-v1-2-7ffce164eb45@kernel.org \
--to=cel@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=anna@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jlayton@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=netdev@vger.kernel.org \
--cc=okorniev@redhat.com \
--cc=pabeni@redhat.com \
--cc=tom@talpey.com \
--cc=trondmy@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