Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111650053
D37777.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D37777.diff
View Options
diff --git a/sys/rpc/rpc_generic.c.vnet b/sys/rpc/rpc_generic.c
--- a/sys/rpc/rpc_generic.c.vnet
+++ b/sys/rpc/rpc_generic.c
@@ -45,10 +45,12 @@
#include "opt_inet6.h"
#include <sys/param.h>
+#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
+#include <sys/osd.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/sbuf.h>
@@ -958,6 +960,10 @@
return (mhead);
}
+#ifdef VNET_NFSD
+int rpctls_prison_cleanup(void *obj, void *data __unused);
+#endif
+
/*
* Kernel module glue
*/
@@ -965,10 +971,19 @@
krpc_modevent(module_t mod, int type, void *data)
{
int error = 0;
+#ifdef VNET_NFSD
+ osd_method_t methods[PR_MAXMETHOD] = {
+ [PR_METHOD_REMOVE] = rpctls_prison_cleanup,
+ };
+#endif
switch (type) {
case MOD_LOAD:
error = rpctls_init();
+#ifdef VNET_NFSD
+ /* XXX-BZ OSD to VNET? */
+ osd_jail_register(NULL, methods);
+#endif
break;
case MOD_UNLOAD:
/*
diff --git a/sys/rpc/rpcsec_tls.h.vnet b/sys/rpc/rpcsec_tls.h
--- a/sys/rpc/rpcsec_tls.h.vnet
+++ b/sys/rpc/rpcsec_tls.h
@@ -86,6 +86,35 @@
/* ssl refno value to indicate TLS handshake being done. */
#define RPCTLS_REFNO_HANDSHAKE 0xFFFFFFFFFFFFFFFFULL
+/* Macros for VNET_NFSD. */
+#ifdef VNET_NFSD
+#if !defined(VIMAGE)
+options VNET_NFSD also requires options VIMAGE
+#endif
+/* Just define the VNET_KRPCxxx() macros as VNETxxx() macros. */
+#define KRPC_VNET_DEFINE(t, n) VNET_DEFINE(t, n)
+#define KRPC_VNET_DEFINE_STATIC(t, n) VNET_DEFINE_STATIC(t, n)
+#define KRPC_VNET(n) VNET(n)
+
+#define KRPC_CURVNET_SET(n) CURVNET_SET(n)
+#define KRPC_CURVNET_SET_QUIET(n) CURVNET_SET_QUIET(n)
+#define KRPC_CURVNET_RESTORE() CURVNET_RESTORE()
+#define KRPC_TD_TO_VNET(n) TD_TO_VNET(n)
+
+/* Jail OSD cleanup function. */
+int rpctls_prison_cleanup(void *obj, void *data __unused);
+#else /* !VNET_NFSD */
+/* Define the KRPC_VNET macros similar to !VIMAGE. */
+#define KRPC_VNET_DEFINE(t, n) t n
+#define KRPC_VNET_DEFINE_STATIC(t, n) static t n
+#define KRPC_VNET(n) (n)
+
+#define KRPC_CURVNET_SET(n)
+#define KRPC_CURVNET_SET_QUIET(n)
+#define KRPC_CURVNET_RESTORE()
+#define KRPC_TD_TO_VNET(n) NULL
+#endif /* VNET_NFSD */
+
#endif /* _KERNEL */
#endif /* _RPC_RPCSEC_TLS_H_ */
diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c.vnet b/sys/rpc/rpcsec_tls/rpctls_impl.c
--- a/sys/rpc/rpcsec_tls/rpctls_impl.c.vnet
+++ b/sys/rpc/rpcsec_tls/rpctls_impl.c
@@ -38,6 +38,7 @@
#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 @@
#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,15 +77,16 @@
static struct mtx rpctls_connect_lock;
static struct socket *rpctls_connect_so = NULL;
static CLIENT *rpctls_connect_cl = NULL;
-static CLIENT *rpctls_server_handle[RPCTLS_SRV_MAXNPROCS];
static struct mtx rpctls_server_lock;
-static struct socket *rpctls_server_so = NULL;
-static SVCXPRT *rpctls_server_xprt = NULL;
-static bool rpctls_srv_newdaemon = false;
-static int rpctls_srv_prevproc = 0;
-static bool rpctls_server_busy[RPCTLS_SRV_MAXNPROCS];
static struct opaque_auth rpctls_null_verf;
+KRPC_VNET_DEFINE_STATIC(CLIENT **, rpctls_server_handle);
+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_srv_newdaemon) = false;
+KRPC_VNET_DEFINE_STATIC(int, rpctls_srv_prevproc) = 0;
+KRPC_VNET_DEFINE_STATIC(bool *, rpctls_server_busy);
+
static CLIENT *rpctls_connect_client(void);
static CLIENT *rpctls_server_client(int procpos);
static enum clnt_stat rpctls_server(SVCXPRT *xprt, struct socket *so,
@@ -90,10 +94,27 @@
uid_t *uid, int *ngrps, gid_t **gids,
int *procposp);
+static void
+rpctls_vnetinit(const void *unused __unused)
+{
+ int i;
+
+ KRPC_VNET(rpctls_server_handle) = malloc(sizeof(CLIENT *) *
+ RPCTLS_SRV_MAXNPROCS, M_RPC, M_WAITOK | M_ZERO);
+ KRPC_VNET(rpctls_server_busy) = malloc(sizeof(bool) *
+ RPCTLS_SRV_MAXNPROCS, M_RPC, M_WAITOK | M_ZERO);
+ for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++)
+ KRPC_VNET(rpctls_server_busy)[i] = false;
+}
+#ifdef VNET_NFSD
+VNET_SYSINIT(rpctls_vnetinit, SI_SUB_VNET_DONE, SI_ORDER_ANY,
+ rpctls_vnetinit, NULL);
+#endif
+
int
rpctls_init(void)
{
- int error, i;
+ int error;
error = syscall_helper_register(rpctls_syscalls, SY_THR_STATIC_KLD);
if (error != 0) {
@@ -107,8 +128,9 @@
rpctls_null_verf.oa_flavor = AUTH_NULL;
rpctls_null_verf.oa_base = RPCTLS_START_STRING;
rpctls_null_verf.oa_length = strlen(RPCTLS_START_STRING);
- for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++)
- rpctls_server_busy[i] = false;
+#ifndef VNET_NFSD
+ rpctls_vnetinit(NULL);
+#endif
return (0);
}
@@ -133,27 +155,36 @@
if (error != 0)
return (error);
+ KRPC_CURVNET_SET(KRPC_TD_TO_VNET(td));
switch (uap->op) {
case RPCTLS_SYSC_SRVSTARTUP:
- /* Get rid of all old CLIENTs. */
- mtx_lock(&rpctls_server_lock);
- for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
- oldcl[i] = rpctls_server_handle[i];
- rpctls_server_handle[i] = NULL;
- rpctls_server_busy[i] = false;
- }
- rpctls_srv_newdaemon = true;
- rpctls_srv_prevproc = 0;
- mtx_unlock(&rpctls_server_lock);
- for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
- if (oldcl[i] != NULL) {
- CLNT_CLOSE(oldcl[i]);
- CLNT_RELEASE(oldcl[i]);
+ if (jailed(curthread->td_ucred) &&
+ !prison_check_nfsd(curthread->td_ucred))
+ error = EPERM;
+ if (error == 0) {
+ /* Get rid of all old CLIENTs. */
+ mtx_lock(&rpctls_server_lock);
+ for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
+ oldcl[i] = KRPC_VNET(rpctls_server_handle)[i];
+ KRPC_VNET(rpctls_server_handle)[i] = NULL;
+ KRPC_VNET(rpctls_server_busy)[i] = false;
}
+ KRPC_VNET(rpctls_srv_newdaemon) = true;
+ KRPC_VNET(rpctls_srv_prevproc) = 0;
+ mtx_unlock(&rpctls_server_lock);
+ for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
+ if (oldcl[i] != NULL) {
+ CLNT_CLOSE(oldcl[i]);
+ CLNT_RELEASE(oldcl[i]);
+ }
+ }
}
break;
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
@@ -209,7 +240,11 @@
}
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
@@ -254,14 +289,14 @@
for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++)
oldcl[i] = NULL;
mtx_lock(&rpctls_server_lock);
- if (rpctls_srv_newdaemon) {
+ if (KRPC_VNET(rpctls_srv_newdaemon)) {
/*
* For a new daemon, the rpctls_srv_handles have
* already been cleaned up by RPCTLS_SYSC_SRVSTARTUP.
* Scan for an available array entry to use.
*/
for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
- if (rpctls_server_handle[i] == NULL)
+ if (KRPC_VNET(rpctls_server_handle)[i] == NULL)
break;
}
if (i == RPCTLS_SRV_MAXNPROCS && error == 0)
@@ -269,14 +304,14 @@
} else {
/* For an old daemon, clear out old CLIENTs. */
for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
- oldcl[i] = rpctls_server_handle[i];
- rpctls_server_handle[i] = NULL;
- rpctls_server_busy[i] = false;
+ oldcl[i] = KRPC_VNET(rpctls_server_handle)[i];
+ KRPC_VNET(rpctls_server_handle)[i] = NULL;
+ KRPC_VNET(rpctls_server_busy)[i] = false;
}
i = 0; /* Set to use rpctls_server_handle[0]. */
}
if (error == 0)
- rpctls_server_handle[i] = cl;
+ KRPC_VNET(rpctls_server_handle)[i] = cl;
mtx_unlock(&rpctls_server_lock);
for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
@@ -300,10 +335,10 @@
case RPCTLS_SYSC_SRVSHUTDOWN:
mtx_lock(&rpctls_server_lock);
for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
- oldcl[i] = rpctls_server_handle[i];
- rpctls_server_handle[i] = NULL;
+ oldcl[i] = KRPC_VNET(rpctls_server_handle)[i];
+ KRPC_VNET(rpctls_server_handle)[i] = NULL;
}
- rpctls_srv_newdaemon = false;
+ KRPC_VNET(rpctls_srv_newdaemon) = false;
mtx_unlock(&rpctls_server_lock);
for (i = 0; i < RPCTLS_SRV_MAXNPROCS; i++) {
@@ -342,10 +377,10 @@
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);
@@ -370,6 +405,7 @@
default:
error = EINVAL;
}
+ KRPC_CURVNET_RESTORE();
return (error);
}
@@ -400,11 +436,13 @@
{
CLIENT *cl;
+ KRPC_CURVNET_SET_QUIET(KRPC_TD_TO_VNET(curthread));
mtx_lock(&rpctls_server_lock);
- cl = rpctls_server_handle[procpos];
+ cl = KRPC_VNET(rpctls_server_handle)[procpos];
if (cl != NULL)
CLNT_ACQUIRE(cl);
mtx_unlock(&rpctls_server_lock);
+ KRPC_CURVNET_RESTORE();
return (cl);
}
@@ -611,33 +649,37 @@
uint32_t *gidv;
int i, procpos;
+ KRPC_CURVNET_SET_QUIET(KRPC_TD_TO_VNET(curthread));
cl = NULL;
procpos = -1;
mtx_lock(&rpctls_server_lock);
- for (i = (rpctls_srv_prevproc + 1) % RPCTLS_SRV_MAXNPROCS;
- i != rpctls_srv_prevproc; i = (i + 1) % RPCTLS_SRV_MAXNPROCS) {
- if (rpctls_server_handle[i] != NULL)
+ for (i = (KRPC_VNET(rpctls_srv_prevproc) + 1) % RPCTLS_SRV_MAXNPROCS;
+ i != KRPC_VNET(rpctls_srv_prevproc);
+ i = (i + 1) % RPCTLS_SRV_MAXNPROCS) {
+ if (KRPC_VNET(rpctls_server_handle)[i] != NULL)
break;
}
- if (i == rpctls_srv_prevproc) {
- if (rpctls_server_handle[i] != NULL)
+ if (i == KRPC_VNET(rpctls_srv_prevproc)) {
+ if (KRPC_VNET(rpctls_server_handle)[i] != NULL)
procpos = i;
} else
- rpctls_srv_prevproc = procpos = i;
+ KRPC_VNET(rpctls_srv_prevproc) = procpos = i;
mtx_unlock(&rpctls_server_lock);
if (procpos >= 0)
cl = rpctls_server_client(procpos);
- 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[procpos])
- msleep(&rpctls_server_busy[procpos], &rpctls_server_lock, PVFS,
- "rtlssn", 0);
- rpctls_server_busy[procpos] = true;
- rpctls_server_so = so;
- rpctls_server_xprt = xprt;
+ while (KRPC_VNET(rpctls_server_busy)[procpos])
+ msleep(&KRPC_VNET(rpctls_server_busy)[procpos],
+ &rpctls_server_lock, PVFS, "rtlssn", 0);
+ KRPC_VNET(rpctls_server_busy)[procpos] = true;
+ KRPC_VNET(rpctls_server_so) = so;
+ KRPC_VNET(rpctls_server_xprt) = xprt;
mtx_unlock(&rpctls_server_lock);
/* Do the server upcall. */
@@ -672,11 +714,12 @@
/* 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[procpos] = false;
- wakeup(&rpctls_server_busy[procpos]);
+ KRPC_VNET(rpctls_server_so) = NULL;
+ KRPC_VNET(rpctls_server_xprt) = NULL;
+ KRPC_VNET(rpctls_server_busy)[procpos] = false;
+ wakeup(&KRPC_VNET(rpctls_server_busy)[procpos]);
mtx_unlock(&rpctls_server_lock);
+ KRPC_CURVNET_RESTORE();
return (stat);
}
@@ -795,9 +838,30 @@
return (false);
if (rpctlscd_run && rpctls_connect_handle == NULL)
return (false);
- if (rpctlssd_run && rpctls_server_handle[0] == NULL)
+ KRPC_CURVNET_SET_QUIET(KRPC_TD_TO_VNET(curthread));
+ if (rpctlssd_run && KRPC_VNET(rpctls_server_handle)[0] == NULL) {
+ KRPC_CURVNET_RESTORE();
return (false);
+ }
+ KRPC_CURVNET_RESTORE();
*maxlenp = maxlen;
return (enable);
}
+
+#ifdef VNET_NFSD
+/* Osd entry for prison cleanup. */
+int
+rpctls_prison_cleanup(void *obj, void *data __unused)
+{
+ struct prison *pr = obj;
+
+ if ((pr->pr_flags & PR_VNET) == 0)
+ return (0);
+ KRPC_CURVNET_SET(pr->pr_vnet);
+ free(KRPC_VNET(rpctls_server_handle), M_RPC);
+ free(KRPC_VNET(rpctls_server_busy), M_RPC);
+ KRPC_CURVNET_RESTORE();
+ return (0);
+}
+#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 7, 12:35 PM (20 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17032268
Default Alt Text
D37777.diff (12 KB)
Attached To
Mode
D37777: Add VNET_NFSD support to the rpcsec_tls so NFS-over-TLS works in vnet prisons
Attached
Detach File
Event Timeline
Log In to Comment