The branch main has been updated by glebius:

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

commit 765ad4f03937cb90ea3cc138535bab872e30b0c4
Author:     Gleb Smirnoff <gleb...@freebsd.org>
AuthorDate: 2025-02-01 01:03:27 +0000
Commit:     Gleb Smirnoff <gleb...@freebsd.org>
CommitDate: 2025-02-01 09:00:28 +0000

    rpcsec_tls: cleanup the rpctls_syscall()
    
    With all the recent changes we don't need extra argument that specifies
    what exactly the syscalls does, neither we need a copyout-able pointer,
    just a pointer sized integer.
    
    Reviewed by:            rmacklem
    Differential Revision:  https://reviews.freebsd.org/D48649
---
 sys/kern/syscalls.master             |  3 +-
 sys/rpc/rpcsec_tls.h                 |  8 +--
 sys/rpc/rpcsec_tls/rpctls_impl.c     | 94 ++++++++++++++++++------------------
 usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c |  2 +-
 usr.sbin/rpc.tlsservd/rpc.tlsservd.c |  2 +-
 5 files changed, 53 insertions(+), 56 deletions(-)

diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 9628745da304..52502fc662be 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -3249,8 +3249,7 @@
 ; 576 is initialised by the krpc code, if present.
 576    AUE_NULL        NOSTD {
                int rpctls_syscall(
-                   int op,
-                   _In_z_ const char *path
+                   uint64_t socookie
                );
        }
 577    AUE_SPECIALFD   STD|CAPENABLED {
diff --git a/sys/rpc/rpcsec_tls.h b/sys/rpc/rpcsec_tls.h
index 024fb2fe68ee..97c49dc32245 100644
--- a/sys/rpc/rpcsec_tls.h
+++ b/sys/rpc/rpcsec_tls.h
@@ -28,12 +28,8 @@
 #ifndef        _RPC_RPCSEC_TLS_H_
 #define        _RPC_RPCSEC_TLS_H_
 
-/* Operation values for rpctls syscall. */
-#define        RPCTLS_SYSC_CLSOCKET    2
-#define        RPCTLS_SYSC_SRVSOCKET   5
-
-/* System call used by the rpctlscd, rpctlssd daemons. */
-int    rpctls_syscall(int, const char *);
+/* System call used by the rpc.tlsclntd(8), rpc.tlsservd(8) daemons. */
+int    rpctls_syscall(uint64_t);
 
 /* Flag bits to indicate certificate results. */
 #define        RPCTLS_FLAGS_HANDSHAKE  0x01
diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c b/sys/rpc/rpcsec_tls/rpctls_impl.c
index 49464495ad58..adca24c3e3d5 100644
--- a/sys/rpc/rpcsec_tls/rpctls_impl.c
+++ b/sys/rpc/rpcsec_tls/rpctls_impl.c
@@ -88,6 +88,7 @@ struct upsock {
                CLIENT *cl;
                SVCXPRT *xp;
        };
+       bool server;
 };
 
 static RB_HEAD(upsock_t, upsock) upcall_sockets;
@@ -169,7 +170,7 @@ int
 sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap)
 {
        struct file *fp;
-       struct upsock *ups;
+       struct upsock *upsp, ups;
        int fd = -1, error;
         
        error = priv_check(td, PRIV_NFS_DAEMON);
@@ -177,52 +178,51 @@ sys_rpctls_syscall(struct thread *td, struct 
rpctls_syscall_args *uap)
                return (error);
 
        KRPC_CURVNET_SET(KRPC_TD_TO_VNET(td));
-       switch (uap->op) {
-       case RPCTLS_SYSC_CLSOCKET:
-       case RPCTLS_SYSC_SRVSOCKET:
-               mtx_lock(&rpctls_lock);
-               ups = RB_FIND(upsock_t, &upcall_sockets,
-                   &(struct upsock){
-                   .so = __DECONST(struct socket *, uap->path) });
-               if (__predict_true(ups != NULL))
-                       RB_REMOVE(upsock_t, &upcall_sockets, ups);
-               mtx_unlock(&rpctls_lock);
-               if (ups == NULL) {
-                       printf("%s: socket lookup failed\n", __func__);
-                       error = EPERM;
-                       break;
-               }
-               if ((error = falloc(td, &fp, &fd, 0)) != 0)
-                       break;
-               soref(ups->so);
-               switch (uap->op) {
-               case RPCTLS_SYSC_CLSOCKET:
-                       /*
-                        * Initialize TLS state so that clnt_vc_destroy() will
-                        * not close the socket and will leave that for the
-                        * daemon to do.
-                        */
-                       CLNT_CONTROL(ups->cl, CLSET_TLS,
-                           &(int){RPCTLS_INHANDSHAKE});
-                       break;
-               case RPCTLS_SYSC_SRVSOCKET:
-                       /*
-                        * Once this file descriptor is associated
-                        * with the socket, it cannot be closed by
-                        * the server side krpc code (svc_vc.c).
-                        */
-                       sx_xlock(&ups->xp->xp_lock);
-                       ups->xp->xp_tls = RPCTLS_FLAGS_HANDSHFAIL;
-                       sx_xunlock(&ups->xp->xp_lock);
-                       break;
-               }
-               finit(fp, FREAD | FWRITE, DTYPE_SOCKET, ups->so, &socketops);
-               fdrop(fp, td);  /* Drop fp reference. */
-               td->td_retval[0] = fd;
-               break;
-       default:
-               error = EINVAL;
+       mtx_lock(&rpctls_lock);
+       upsp = RB_FIND(upsock_t, &upcall_sockets,
+           &(struct upsock){
+           .so = __DECONST(struct socket *, uap->socookie) });
+       if (__predict_true(upsp != NULL)) {
+               RB_REMOVE(upsock_t, &upcall_sockets, upsp);
+               /*
+                * The upsp points to stack of NFS mounting thread.  Even
+                * though we removed it from the tree, we still don't own it.
+                * Make a copy before releasing the lock.  The mounting thread
+                * may timeout the RPC and unroll its stack.
+                */
+               ups = *upsp;
+       }
+       mtx_unlock(&rpctls_lock);
+       if (upsp == NULL) {
+               KRPC_CURVNET_RESTORE();
+               printf("%s: socket lookup failed\n", __func__);
+               return (EPERM);
+       }
+       if ((error = falloc(td, &fp, &fd, 0)) != 0) {
+               KRPC_CURVNET_RESTORE();
+               return (error);
+       }
+       soref(ups.so);
+       if (ups.server) {
+               /*
+                * Once this file descriptor is associated
+                * with the socket, it cannot be closed by
+                * the server side krpc code (svc_vc.c).
+                */
+               sx_xlock(&ups.xp->xp_lock);
+               ups.xp->xp_tls = RPCTLS_FLAGS_HANDSHFAIL;
+               sx_xunlock(&ups.xp->xp_lock);
+       } else {
+               /*
+                * Initialize TLS state so that clnt_vc_destroy() will
+                * not close the socket and will leave that for the
+                * daemon to do.
+                */
+               CLNT_CONTROL(ups.cl, CLSET_TLS, &(int){RPCTLS_INHANDSHAKE});
        }
+       finit(fp, FREAD | FWRITE, DTYPE_SOCKET, ups.so, &socketops);
+       fdrop(fp, td);  /* Drop fp reference. */
+       td->td_retval[0] = fd;
        KRPC_CURVNET_RESTORE();
 
        return (error);
@@ -269,6 +269,7 @@ rpctls_connect(CLIENT *newclient, char *certname, struct 
socket *so,
        struct upsock ups = {
                .so = so,
                .cl = newclient,
+               .server = false,
        };
        CLIENT *cl = KRPC_VNET(rpctls_connect_handle);
 
@@ -390,6 +391,7 @@ rpctls_server(SVCXPRT *xprt, uint32_t *flags, uid_t *uid, 
int *ngrps,
        struct upsock ups = {
                .so = xprt->xp_socket,
                .xp = xprt,
+               .server = true,
        };
        CLIENT *cl = KRPC_VNET(rpctls_server_handle);
        struct rpctlssd_connect_arg arg;
diff --git a/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c 
b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c
index e8df84a382b5..37e0c2013ef1 100644
--- a/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c
+++ b/usr.sbin/rpc.tlsclntd/rpc.tlsclntd.c
@@ -258,7 +258,7 @@ rpctlscd_connect_2_svc(struct rpctlscd_connect_arg *argp,
 
        rpctls_verbose_out("rpctlsd_connect: started\n");
        /* Get the socket fd from the kernel. */
-       s = rpctls_syscall(RPCTLS_SYSC_CLSOCKET, (char *)argp->socookie);
+       s = rpctls_syscall(argp->socookie);
        if (s < 0) {
                result->reterr = RPCTLSERR_NOSOCKET;
                return (TRUE);
diff --git a/usr.sbin/rpc.tlsservd/rpc.tlsservd.c 
b/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
index 61f8601c36f5..438b745fb5de 100644
--- a/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
+++ b/usr.sbin/rpc.tlsservd/rpc.tlsservd.c
@@ -403,7 +403,7 @@ rpctlssd_connect_thread(void *v)
        }
 
        /* Get the socket fd from the kernel. */
-       s = rpctls_syscall(RPCTLS_SYSC_SRVSOCKET, (char *)socookie);
+       s = rpctls_syscall(socookie);
        if (s < 0) {
                rpctls_verbose_out("rpctlssd_connect_svc: rpctls_syscall "
                    "accept failed\n");

Reply via email to