git: af805255e569 - main - rpcsec_tls/server: API refactoring between kernel and rpc.tlsservd(8)

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Sat, 01 Feb 2025 09:02:23 UTC
The branch main has been updated by glebius:

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

commit af805255e56997f9de24c050b3a40dfffe4a29cb
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-02-01 01:03:02 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-02-01 09:00:27 +0000

    rpcsec_tls/server: API refactoring between kernel and rpc.tlsservd(8)
    
    Now that the conversion of rpcsec_tls/client + rpc.tlsclntd(8) to the
    netlink(4) socket as RPC transport started using kernel socket pointer as
    a reliable cookie, we can shave off quite a lot of complexity.  We will
    utilize the same kernel-generated cookie in all RPCs.  And the need for
    the daemon generated cookie in the form of timestamp+sequence vanishes.
    
    We also stop passing notion of 'process position' from userland to
    kernel.  The TLS handshake parallelism to be reimplemented in the daemon
    without any awareness about that in the kernel.
    
    This time bump the RPC version.
    
    Reviewed by:            rmacklem
    Differential Revision:  https://reviews.freebsd.org/D48566
---
 sys/rpc/rpcsec_tls.h             |  6 ++---
 sys/rpc/rpcsec_tls/rpctls_impl.c | 49 +++++++++++++---------------------------
 sys/rpc/rpcsec_tls/rpctlssd.x    | 13 +++--------
 sys/rpc/svc.h                    |  4 ----
 sys/rpc/svc_vc.c                 |  8 ++-----
 5 files changed, 23 insertions(+), 57 deletions(-)

diff --git a/sys/rpc/rpcsec_tls.h b/sys/rpc/rpcsec_tls.h
index 6789a77bf7ff..f8ad131c3946 100644
--- a/sys/rpc/rpcsec_tls.h
+++ b/sys/rpc/rpcsec_tls.h
@@ -58,11 +58,9 @@ int	rpctls_syscall(int, const char *);
 enum clnt_stat	rpctls_connect(CLIENT *newclient, char *certname,
 		    struct socket *so, uint32_t *reterr);
 enum clnt_stat	rpctls_cl_handlerecord(void *socookie, uint32_t *reterr);
-enum clnt_stat	rpctls_srv_handlerecord(uint64_t sec, uint64_t usec,
-		    uint64_t ssl, int procpos, uint32_t *reterr);
+enum clnt_stat	rpctls_srv_handlerecord(void *socookie, uint32_t *reterr);
 enum clnt_stat	rpctls_cl_disconnect(void *socookie, uint32_t *reterr);
-enum clnt_stat	rpctls_srv_disconnect(uint64_t sec, uint64_t usec,
-		    uint64_t ssl, int procpos, uint32_t *reterr);
+enum clnt_stat	rpctls_srv_disconnect(void *socookie, uint32_t *reterr);
 
 /* Initialization function for rpcsec_tls. */
 int		rpctls_init(void);
diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c b/sys/rpc/rpcsec_tls/rpctls_impl.c
index 00a4edcdaf64..9d2d154f8738 100644
--- a/sys/rpc/rpcsec_tls/rpctls_impl.c
+++ b/sys/rpc/rpcsec_tls/rpctls_impl.c
@@ -99,10 +99,8 @@ upsock_compare(const struct upsock *a, const struct upsock *b)
 RB_GENERATE_STATIC(upsock_t, upsock, tree, upsock_compare);
 static struct mtx rpctls_lock;
 
-static enum clnt_stat	rpctls_server(SVCXPRT *xprt, struct socket *so,
-			    uint32_t *flags, uint64_t *sslp,
-			    uid_t *uid, int *ngrps, gid_t **gids,
-			    int *procposp);
+static enum clnt_stat	rpctls_server(SVCXPRT *xprt, uint32_t *flags,
+    uid_t *uid, int *ngrps, gid_t **gids);
 
 static CLIENT *
 rpctls_client_nl_create(const char *group, const rpcprog_t program,
@@ -325,8 +323,7 @@ rpctls_cl_handlerecord(void *socookie, uint32_t *reterr)
 }
 
 enum clnt_stat
-rpctls_srv_handlerecord(uint64_t sec, uint64_t usec, uint64_t ssl, int procpos,
-    uint32_t *reterr)
+rpctls_srv_handlerecord(void *socookie, uint32_t *reterr)
 {
 	struct rpctlssd_handlerecord_arg arg;
 	struct rpctlssd_handlerecord_res res;
@@ -334,10 +331,8 @@ rpctls_srv_handlerecord(uint64_t sec, uint64_t usec, uint64_t ssl, int procpos,
 	CLIENT *cl = KRPC_VNET(rpctls_server_handle);
 
 	/* Do the handlerecord upcall. */
-	arg.sec = sec;
-	arg.usec = usec;
-	arg.ssl = ssl;
-	stat = rpctlssd_handlerecord_1(&arg, &res, cl);
+	arg.socookie = (uint64_t)socookie;
+	stat = rpctlssd_handlerecord_2(&arg, &res, cl);
 	if (stat == RPC_SUCCESS)
 		*reterr = res.reterr;
 	return (stat);
@@ -361,8 +356,7 @@ rpctls_cl_disconnect(void *socookie, uint32_t *reterr)
 }
 
 enum clnt_stat
-rpctls_srv_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl, int procpos,
-    uint32_t *reterr)
+rpctls_srv_disconnect(void *socookie, uint32_t *reterr)
 {
 	struct rpctlssd_disconnect_arg arg;
 	struct rpctlssd_disconnect_res res;
@@ -370,10 +364,8 @@ rpctls_srv_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl, int procpos,
 	CLIENT *cl = KRPC_VNET(rpctls_server_handle);
 
 	/* Do the disconnect upcall. */
-	arg.sec = sec;
-	arg.usec = usec;
-	arg.ssl = ssl;
-	stat = rpctlssd_disconnect_1(&arg, &res, cl);
+	arg.socookie = (uint64_t)socookie;
+	stat = rpctlssd_disconnect_2(&arg, &res, cl);
 	if (stat == RPC_SUCCESS)
 		*reterr = res.reterr;
 	return (stat);
@@ -381,12 +373,12 @@ rpctls_srv_disconnect(uint64_t sec, uint64_t usec, uint64_t ssl, int procpos,
 
 /* Do an upcall for a new server socket using TLS. */
 static enum clnt_stat
-rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp,
-    uid_t *uid, int *ngrps, gid_t **gids, int *procposp)
+rpctls_server(SVCXPRT *xprt, uint32_t *flags, uid_t *uid, int *ngrps,
+    gid_t **gids)
 {
 	enum clnt_stat stat;
 	struct upsock ups = {
-		.so = so,
+		.so = xprt->xp_socket,
 		.xp = xprt,
 	};
 	CLIENT *cl = KRPC_VNET(rpctls_server_handle);
@@ -402,16 +394,13 @@ rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp,
 
 	/* Do the server upcall. */
 	res.gid.gid_val = NULL;
-	arg.socookie = (uint64_t)so;
-	stat = rpctlssd_connect_1(&arg, &res, cl);
+	arg.socookie = (uint64_t)xprt->xp_socket;
+	stat = rpctlssd_connect_2(&arg, &res, cl);
 	if (stat == RPC_SUCCESS) {
 #ifdef INVARIANTS
 		MPASS((RB_FIND(upsock_t, &upcall_sockets, &ups) == NULL));
 #endif
 		*flags = res.flags;
-		*sslp++ = res.sec;
-		*sslp++ = res.usec;
-		*sslp = res.ssl;
 		if ((*flags & (RPCTLS_FLAGS_CERTUSER |
 		    RPCTLS_FLAGS_DISABLED)) == RPCTLS_FLAGS_CERTUSER) {
 			*ngrps = res.gid.gid_len;
@@ -436,7 +425,7 @@ rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp,
 			 * daemon will close() the socket after SSL_accept()
 			 * returns an error.
 			 */
-			soshutdown(so, SHUT_RD);
+			soshutdown(xprt->xp_socket, SHUT_RD);
 		} else {
 			/*
 			 * The daemon has taken the socket from the tree, but
@@ -463,8 +452,7 @@ _svcauth_rpcsec_tls(struct svc_req *rqst, struct rpc_msg *msg)
 	enum clnt_stat stat;
 	SVCXPRT *xprt;
 	uint32_t flags;
-	uint64_t ssl[3];
-	int ngrps, procpos;
+	int ngrps;
 	uid_t uid;
 	gid_t *gidp;
 #ifdef KERN_TLS
@@ -523,18 +511,13 @@ _svcauth_rpcsec_tls(struct svc_req *rqst, struct rpc_msg *msg)
 	}
 
 	/* Do an upcall to do the TLS handshake. */
-	stat = rpctls_server(xprt, xprt->xp_socket, &flags,
-	    ssl, &uid, &ngrps, &gidp, &procpos);
+	stat = rpctls_server(xprt, &flags, &uid, &ngrps, &gidp);
 
 	/* Re-enable reception on the socket within the krpc. */
 	sx_xlock(&xprt->xp_lock);
 	xprt->xp_dontrcv = FALSE;
 	if (stat == RPC_SUCCESS) {
 		xprt->xp_tls = flags;
-		xprt->xp_sslsec = ssl[0];
-		xprt->xp_sslusec = ssl[1];
-		xprt->xp_sslrefno = ssl[2];
-		xprt->xp_sslproc = procpos;
 		if ((flags & (RPCTLS_FLAGS_CERTUSER |
 		    RPCTLS_FLAGS_DISABLED)) == RPCTLS_FLAGS_CERTUSER) {
 			xprt->xp_ngrps = ngrps;
diff --git a/sys/rpc/rpcsec_tls/rpctlssd.x b/sys/rpc/rpcsec_tls/rpctlssd.x
index e9afca084ada..42f94a863a77 100644
--- a/sys/rpc/rpcsec_tls/rpctlssd.x
+++ b/sys/rpc/rpcsec_tls/rpctlssd.x
@@ -33,17 +33,12 @@ struct rpctlssd_connect_arg {
 
 struct rpctlssd_connect_res {
 	uint32_t flags;
-	uint64_t sec;
-	uint64_t usec;
-	uint64_t ssl;
 	uint32_t uid;
 	uint32_t gid<>;
 };
 
 struct rpctlssd_handlerecord_arg {
-	uint64_t sec;
-	uint64_t usec;
-	uint64_t ssl;
+	uint64_t socookie;
 };
 
 struct rpctlssd_handlerecord_res {
@@ -51,9 +46,7 @@ struct rpctlssd_handlerecord_res {
 };
 
 struct rpctlssd_disconnect_arg {
-	uint64_t sec;
-	uint64_t usec;
-	uint64_t ssl;
+	uint64_t socookie;
 };
 
 struct rpctlssd_disconnect_res {
@@ -72,5 +65,5 @@ program RPCTLSSD {
 
 		rpctlssd_disconnect_res
 		RPCTLSSD_DISCONNECT(rpctlssd_disconnect_arg) = 3;
-	} = 1;
+	} = 2;
 } = 0x40677375;
diff --git a/sys/rpc/svc.h b/sys/rpc/svc.h
index 92755a198488..b0fc78d4d044 100644
--- a/sys/rpc/svc.h
+++ b/sys/rpc/svc.h
@@ -151,10 +151,6 @@ typedef struct __rpc_svcxprt {
 	uint32_t	xp_snt_cnt;	/* # of bytes sent to socket */
 	bool_t		xp_dontrcv;	/* Do not receive on the socket */
 	uint32_t	xp_tls;		/* RPC-over-TLS on socket */
-	uint64_t	xp_sslsec;	/* Userland SSL * */
-	uint64_t	xp_sslusec;
-	uint64_t	xp_sslrefno;
-	int		xp_sslproc;	/* Which upcall daemon being used */
 	int		xp_ngrps;	/* Cred. from TLS cert. */
 	uid_t		xp_uid;
 	gid_t		*xp_gidp;
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
index 44c61a9141a6..7e30582c59e0 100644
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -501,9 +501,7 @@ svc_vc_destroy_common(SVCXPRT *xprt)
 				 * daemon having crashed or been
 				 * restarted, so just ignore returned stat.
 				 */
-				rpctls_srv_disconnect(xprt->xp_sslsec,
-				    xprt->xp_sslusec, xprt->xp_sslrefno,
-				    xprt->xp_sslproc, &reterr);
+				rpctls_srv_disconnect(xprt->xp_socket, &reterr);
 			}
 			/* Must sorele() to get rid of reference. */
 			sorele(xprt->xp_socket);
@@ -856,9 +854,7 @@ tryagain:
 			/* Disable reception. */
 			xprt->xp_dontrcv = TRUE;
 			sx_xunlock(&xprt->xp_lock);
-			ret = rpctls_srv_handlerecord(xprt->xp_sslsec,
-			    xprt->xp_sslusec, xprt->xp_sslrefno,
-			    xprt->xp_sslproc, &reterr);
+			ret = rpctls_srv_handlerecord(so, &reterr);
 			KRPC_CURVNET_RESTORE();
 			sx_xlock(&xprt->xp_lock);
 			xprt->xp_dontrcv = FALSE;