Netdev List
 help / color / mirror / Atom feed
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


  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