Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Sep 2021 19:12:32 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: bf25678226f0 - main - ktls: Fix error/mode confusion in TCP_*TLS_MODE getsockopt handlers
Message-ID:  <202109171912.18HJCWIj068220@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj:

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

commit bf25678226f0d9b52c27610c734c97d76a7cae59
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-09-17 16:14:29 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-09-17 18:19:05 +0000

    ktls: Fix error/mode confusion in TCP_*TLS_MODE getsockopt handlers
    
    ktls_get_(rx|tx)_mode() can return an errno value or a TLS mode, so
    errors are effectively hidden.  Fix this by using a separate output
    parameter.  Convert to the new socket buffer locking macros while here.
    
    Note that the socket buffer lock is not needed to synchronize the
    SOLISTENING check here, we can rely on the PCB lock.
    
    Reviewed by:    jhb
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D31977
---
 sys/kern/uipc_ktls.c     | 26 ++++++++++++--------------
 sys/netinet/tcp_usrreq.c | 12 ++++++++----
 sys/sys/ktls.h           |  4 ++--
 3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c
index 9e9a6b5b60fb..bc21e6fe2493 100644
--- a/sys/kern/uipc_ktls.c
+++ b/sys/kern/uipc_ktls.c
@@ -1199,45 +1199,43 @@ ktls_enable_tx(struct socket *so, struct tls_enable *en)
 }
 
 int
-ktls_get_rx_mode(struct socket *so)
+ktls_get_rx_mode(struct socket *so, int *modep)
 {
 	struct ktls_session *tls;
 	struct inpcb *inp;
-	int mode;
 
 	if (SOLISTENING(so))
 		return (EINVAL);
 	inp = so->so_pcb;
 	INP_WLOCK_ASSERT(inp);
-	SOCKBUF_LOCK(&so->so_rcv);
+	SOCK_RECVBUF_LOCK(so);
 	tls = so->so_rcv.sb_tls_info;
 	if (tls == NULL)
-		mode = TCP_TLS_MODE_NONE;
+		*modep = TCP_TLS_MODE_NONE;
 	else
-		mode = tls->mode;
-	SOCKBUF_UNLOCK(&so->so_rcv);
-	return (mode);
+		*modep = tls->mode;
+	SOCK_RECVBUF_UNLOCK(so);
+	return (0);
 }
 
 int
-ktls_get_tx_mode(struct socket *so)
+ktls_get_tx_mode(struct socket *so, int *modep)
 {
 	struct ktls_session *tls;
 	struct inpcb *inp;
-	int mode;
 
 	if (SOLISTENING(so))
 		return (EINVAL);
 	inp = so->so_pcb;
 	INP_WLOCK_ASSERT(inp);
-	SOCKBUF_LOCK(&so->so_snd);
+	SOCK_SENDBUF_LOCK(so);
 	tls = so->so_snd.sb_tls_info;
 	if (tls == NULL)
-		mode = TCP_TLS_MODE_NONE;
+		*modep = TCP_TLS_MODE_NONE;
 	else
-		mode = tls->mode;
-	SOCKBUF_UNLOCK(&so->so_snd);
-	return (mode);
+		*modep = tls->mode;
+	SOCK_SENDBUF_UNLOCK(so);
+	return (0);
 }
 
 /*
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 3a1608cc106a..e9f7fa541461 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -2563,14 +2563,18 @@ unhold:
 #endif
 #ifdef KERN_TLS
 		case TCP_TXTLS_MODE:
-			optval = ktls_get_tx_mode(so);
+			error = ktls_get_tx_mode(so, &optval);
 			INP_WUNLOCK(inp);
-			error = sooptcopyout(sopt, &optval, sizeof(optval));
+			if (error == 0)
+				error = sooptcopyout(sopt, &optval,
+				    sizeof(optval));
 			break;
 		case TCP_RXTLS_MODE:
-			optval = ktls_get_rx_mode(so);
+			error = ktls_get_rx_mode(so, &optval);
 			INP_WUNLOCK(inp);
-			error = sooptcopyout(sopt, &optval, sizeof(optval));
+			if (error == 0)
+				error = sooptcopyout(sopt, &optval,
+				    sizeof(optval));
 			break;
 #endif
 		case TCP_LRD:
diff --git a/sys/sys/ktls.h b/sys/sys/ktls.h
index 9729fd6fe8c4..71d55ee1b3d8 100644
--- a/sys/sys/ktls.h
+++ b/sys/sys/ktls.h
@@ -212,9 +212,9 @@ void ktls_frame(struct mbuf *m, struct ktls_session *tls, int *enqueue_cnt,
 void ktls_seq(struct sockbuf *sb, struct mbuf *m);
 void ktls_enqueue(struct mbuf *m, struct socket *so, int page_count);
 void ktls_enqueue_to_free(struct mbuf *m);
-int ktls_get_rx_mode(struct socket *so);
+int ktls_get_rx_mode(struct socket *so, int *modep);
 int ktls_set_tx_mode(struct socket *so, int mode);
-int ktls_get_tx_mode(struct socket *so);
+int ktls_get_tx_mode(struct socket *so, int *modep);
 int ktls_output_eagain(struct inpcb *inp, struct ktls_session *tls);
 #ifdef RATELIMIT
 int ktls_modify_txrtlmt(struct ktls_session *tls, uint64_t max_pacing_rate);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109171912.18HJCWIj068220>