git: 373511338d95 - main - uipc_socket.c: Modify MSG_TLSAPPDATA to only do Alert Records

From: Rick Macklem <rmacklem_at_FreeBSD.org>
Date: Sat, 14 May 2022 19:58:13 UTC
The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=373511338d954895752e957f3028a178587c8c84

commit 373511338d954895752e957f3028a178587c8c84
Author:     Rick Macklem <rmacklem@FreeBSD.org>
AuthorDate: 2022-05-14 19:56:50 +0000
Commit:     Rick Macklem <rmacklem@FreeBSD.org>
CommitDate: 2022-05-14 19:56:50 +0000

    uipc_socket.c: Modify MSG_TLSAPPDATA to only do Alert Records
    
    Without this patch, the MSG_TLSAPPDATA flag would cause
    soreceive_generic() to return ENXIO for any non-application
    data record in a TLS receive stream.
    
    This works ok for TLS1.2, since Alert records appear to be
    the only non-application data records received.
    However, for TLS1.3, there can be post-handshake handshake
    records, such as NewSessionKey sent to the client from the
    server. These handshake records cannot be handled by the
    upcall which does an SSL_read() with length == 0.
    
    It appears that the client can simply throw away these
    NewSessionKey records, but to do so, it needs to receive
    them within the kernel.
    
    This patch modifies the semantics of MSG_TLSAPPDATA slightly,
    so that it only applies to Alert records and not Handshake
    records. It is needed to allow the krpc to work with KTLS1.3.
    
    Reviewed by:    hselasky
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D35170
---
 sys/kern/uipc_socket.c | 8 ++++----
 sys/sys/ktls.h         | 2 ++
 sys/sys/socket.h       | 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 49a2b5773cc6..7351238343b3 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -2127,8 +2127,8 @@ dontblock:
 		struct tls_get_record tgr;
 
 		/*
-		 * For MSG_TLSAPPDATA, check for a non-application data
-		 * record.  If found, return ENXIO without removing
+		 * For MSG_TLSAPPDATA, check for an alert record.
+		 * If found, return ENXIO without removing
 		 * it from the receive queue.  This allows a subsequent
 		 * call without MSG_TLSAPPDATA to receive it.
 		 * Note that, for TLS, there should only be a single
@@ -2139,8 +2139,8 @@ dontblock:
 			if (cmsg->cmsg_type == TLS_GET_RECORD &&
 			    cmsg->cmsg_len == CMSG_LEN(sizeof(tgr))) {
 				memcpy(&tgr, CMSG_DATA(cmsg), sizeof(tgr));
-				/* This will need to change for TLS 1.3. */
-				if (tgr.tls_type != TLS_RLTYPE_APP) {
+				if (__predict_false(tgr.tls_type ==
+				    TLS_RLTYPE_ALERT)) {
 					SOCKBUF_UNLOCK(&so->so_rcv);
 					error = ENXIO;
 					goto release;
diff --git a/sys/sys/ktls.h b/sys/sys/ktls.h
index 6d0b391ee0a5..885e4dc38ef9 100644
--- a/sys/sys/ktls.h
+++ b/sys/sys/ktls.h
@@ -50,6 +50,8 @@ struct tls_record_layer {
 #define	TLS_CBC_IMPLICIT_IV_LEN	16
 
 /* Type values for the record layer */
+#define	TLS_RLTYPE_ALERT	21
+#define	TLS_RLTYPE_HANDSHAKE	22
 #define	TLS_RLTYPE_APP		23
 
 /*
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index 2cb76f9c6d63..de7a874b3079 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -470,7 +470,7 @@ struct msghdr {
 #endif
 #ifdef _KERNEL
 #define	MSG_MORETOCOME	 0x00100000	/* additional data pending */
-#define	MSG_TLSAPPDATA	 0x00200000	/* only soreceive() app. data (TLS) */
+#define	MSG_TLSAPPDATA	 0x00200000	/* do not soreceive() alert rec. (TLS) */
 #endif
 
 /*