git: 1d88734798c2 - stable/13 - krpc: Add macros so that rpc.tlsservd can run in vnet prison
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 17 May 2023 14:46:22 UTC
The branch stable/13 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=1d88734798c252a749764e9ee314f46ce9fd2b3f commit 1d88734798c252a749764e9ee314f46ce9fd2b3f Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2023-02-15 13:58:21 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2023-05-17 14:41:53 +0000 krpc: Add macros so that rpc.tlsservd can run in vnet prison Commit 7344856e3a6d added a lot of macros that will front end vnet macros so that nfsd(8) can run in vnet prison. This patch adds similar macros named KRPC_VNETxxx so that the rpc.tlsservd(8) daemon can run in a vnet prison, once the macros front end the vnet ones. For now, they are null macros. (cherry picked from commit 6444662a563ba714fed8563645764262c6f5e90f) --- sys/rpc/rpcsec_tls.h | 18 ++++++++++ sys/rpc/rpcsec_tls/rpctls_impl.c | 77 ++++++++++++++++++++++++++-------------- 2 files changed, 68 insertions(+), 27 deletions(-) diff --git a/sys/rpc/rpcsec_tls.h b/sys/rpc/rpcsec_tls.h index 49a7e71b7514..5781424a6180 100644 --- a/sys/rpc/rpcsec_tls.h +++ b/sys/rpc/rpcsec_tls.h @@ -72,6 +72,9 @@ enum clnt_stat rpctls_srv_disconnect(uint64_t sec, uint64_t usec, /* Initialization function for rpcsec_tls. */ int rpctls_init(void); +/* Cleanup function for rpcsec_tls. */ +void rpctls_cleanup(void); + /* Get TLS information function. */ bool rpctls_getinfo(u_int *maxlen, bool rpctlscd_run, bool rpctlssd_run); @@ -82,6 +85,21 @@ bool rpctls_getinfo(u_int *maxlen, bool rpctlscd_run, /* ssl refno value to indicate TLS handshake being done. */ #define RPCTLS_REFNO_HANDSHAKE 0xFFFFFFFFFFFFFFFFULL +/* Macros for VIMAGE. */ +/* Define the KRPC_VNET macros similar to !VIMAGE. */ +#define KRPC_VNET_NAME(n) n +#define KRPC_VNET_DECLARE(t, n) extern t n +#define KRPC_VNET_DEFINE(t, n) t n +#define KRPC_VNET_DEFINE_STATIC(t, n) static t n +#define KRPC_VNET(n) (n) + +#define CTLFLAG_KRPC_VNET 0 + +#define KRPC_CURVNET_SET(n) +#define KRPC_CURVNET_SET_QUIET(n) +#define KRPC_CURVNET_RESTORE() +#define KRPC_TD_TO_VNET(n) NULL + #endif /* _KERNEL */ #endif /* _RPC_RPCSEC_TLS_H_ */ diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c b/sys/rpc/rpcsec_tls/rpctls_impl.c index c495213b08e2..3b3452a8b624 100644 --- a/sys/rpc/rpcsec_tls/rpctls_impl.c +++ b/sys/rpc/rpcsec_tls/rpctls_impl.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include <sys/capsicum.h> #include <sys/file.h> #include <sys/filedesc.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -51,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include <sys/sysent.h> #include <sys/sysproto.h> +#include <net/vnet.h> + #include <rpc/rpc.h> #include <rpc/rpc_com.h> #include <rpc/rpcsec_tls.h> @@ -74,12 +77,14 @@ static CLIENT *rpctls_connect_handle; static struct mtx rpctls_connect_lock; static struct socket *rpctls_connect_so = NULL; static CLIENT *rpctls_connect_cl = NULL; -static CLIENT *rpctls_server_handle; static struct mtx rpctls_server_lock; -static struct socket *rpctls_server_so = NULL; -static SVCXPRT *rpctls_server_xprt = NULL; static struct opaque_auth rpctls_null_verf; +KRPC_VNET_DEFINE_STATIC(CLIENT *, rpctls_server_handle) = NULL; +KRPC_VNET_DEFINE_STATIC(struct socket *, rpctls_server_so) = NULL; +KRPC_VNET_DEFINE_STATIC(SVCXPRT *, rpctls_server_xprt) = NULL; +KRPC_VNET_DEFINE_STATIC(bool, rpctls_server_busy) = false; + static CLIENT *rpctls_connect_client(void); static CLIENT *rpctls_server_client(void); static enum clnt_stat rpctls_server(SVCXPRT *xprt, struct socket *so, @@ -127,9 +132,13 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap) if (error != 0) return (error); + KRPC_CURVNET_SET(KRPC_TD_TO_VNET(td)); switch (uap->op) { case RPCTLS_SYSC_CLSETPATH: - error = copyinstr(uap->path, path, sizeof(path), NULL); + if (jailed(curthread->td_ucred)) + error = EPERM; + if (error == 0) + error = copyinstr(uap->path, path, sizeof(path), NULL); if (error == 0) { error = ENXIO; #ifdef KERN_TLS @@ -185,7 +194,11 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap) } break; case RPCTLS_SYSC_SRVSETPATH: - error = copyinstr(uap->path, path, sizeof(path), NULL); + if (jailed(curthread->td_ucred) && + !prison_check_nfsd(curthread->td_ucred)) + error = EPERM; + if (error == 0) + error = copyinstr(uap->path, path, sizeof(path), NULL); if (error == 0) { error = ENXIO; #ifdef KERN_TLS @@ -228,8 +241,8 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap) } mtx_lock(&rpctls_server_lock); - oldcl = rpctls_server_handle; - rpctls_server_handle = cl; + oldcl = KRPC_VNET(rpctls_server_handle); + KRPC_VNET(rpctls_server_handle) = cl; mtx_unlock(&rpctls_server_lock); if (oldcl != NULL) { @@ -250,8 +263,8 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap) break; case RPCTLS_SYSC_SRVSHUTDOWN: mtx_lock(&rpctls_server_lock); - oldcl = rpctls_server_handle; - rpctls_server_handle = NULL; + oldcl = KRPC_VNET(rpctls_server_handle); + KRPC_VNET(rpctls_server_handle) = NULL; mtx_unlock(&rpctls_server_lock); if (oldcl != NULL) { @@ -288,10 +301,10 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap) break; case RPCTLS_SYSC_SRVSOCKET: mtx_lock(&rpctls_server_lock); - so = rpctls_server_so; - rpctls_server_so = NULL; - xprt = rpctls_server_xprt; - rpctls_server_xprt = NULL; + so = KRPC_VNET(rpctls_server_so); + KRPC_VNET(rpctls_server_so) = NULL; + xprt = KRPC_VNET(rpctls_server_xprt); + KRPC_VNET(rpctls_server_xprt) = NULL; mtx_unlock(&rpctls_server_lock); if (so != NULL) { error = falloc(td, &fp, &fd, 0); @@ -316,6 +329,7 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap) default: error = EINVAL; } + KRPC_CURVNET_RESTORE(); return (error); } @@ -346,11 +360,13 @@ rpctls_server_client(void) { CLIENT *cl; + KRPC_CURVNET_SET_QUIET(KRPC_TD_TO_VNET(curthread)); mtx_lock(&rpctls_server_lock); - cl = rpctls_server_handle; + cl = KRPC_VNET(rpctls_server_handle); if (cl != NULL) CLNT_ACQUIRE(cl); mtx_unlock(&rpctls_server_lock); + KRPC_CURVNET_RESTORE(); return (cl); } @@ -556,20 +572,22 @@ rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp, gid_t *gidp; uint32_t *gidv; int i; - static bool rpctls_server_busy = false; + KRPC_CURVNET_SET_QUIET(KRPC_TD_TO_VNET(curthread)); cl = rpctls_server_client(); - if (cl == NULL) + if (cl == NULL) { + KRPC_CURVNET_RESTORE(); return (RPC_SYSTEMERROR); + } /* Serialize the server upcalls. */ mtx_lock(&rpctls_server_lock); - while (rpctls_server_busy) - msleep(&rpctls_server_busy, &rpctls_server_lock, PVFS, - "rtlssn", 0); - rpctls_server_busy = true; - rpctls_server_so = so; - rpctls_server_xprt = xprt; + while (KRPC_VNET(rpctls_server_busy)) + msleep(&KRPC_VNET(rpctls_server_busy), + &rpctls_server_lock, PVFS, "rtlssn", 0); + KRPC_VNET(rpctls_server_busy) = true; + KRPC_VNET(rpctls_server_so) = so; + KRPC_VNET(rpctls_server_xprt) = xprt; mtx_unlock(&rpctls_server_lock); /* Do the server upcall. */ @@ -603,11 +621,12 @@ rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp, /* Once the upcall is done, the daemon is done with the fp and so. */ mtx_lock(&rpctls_server_lock); - rpctls_server_so = NULL; - rpctls_server_xprt = NULL; - rpctls_server_busy = false; - wakeup(&rpctls_server_busy); + KRPC_VNET(rpctls_server_so) = NULL; + KRPC_VNET(rpctls_server_xprt) = NULL; + KRPC_VNET(rpctls_server_busy) = false; + wakeup(&KRPC_VNET(rpctls_server_busy)); mtx_unlock(&rpctls_server_lock); + KRPC_CURVNET_RESTORE(); return (stat); } @@ -725,8 +744,12 @@ rpctls_getinfo(u_int *maxlenp, bool rpctlscd_run, bool rpctlssd_run) return (false); if (rpctlscd_run && rpctls_connect_handle == NULL) return (false); - if (rpctlssd_run && rpctls_server_handle == NULL) + KRPC_CURVNET_SET_QUIET(KRPC_TD_TO_VNET(curthread)); + if (rpctlssd_run && KRPC_VNET(rpctls_server_handle) == NULL) { + KRPC_CURVNET_RESTORE(); return (false); + } + KRPC_CURVNET_RESTORE(); *maxlenp = maxlen; return (enable); }