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);
}