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. MFC after: 3 months
This commit is contained in:
parent
c3821149f4
commit
6444662a56
@ -76,6 +76,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);
|
||||
@ -86,6 +89,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_ */
|
||||
|
@ -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,15 +77,16 @@ 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[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,25 @@ static enum clnt_stat rpctls_server(SVCXPRT *xprt, struct socket *so,
|
||||
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;
|
||||
}
|
||||
SYSINIT(rpctls_vnetinit, SI_SUB_VNET_DONE, SI_ORDER_ANY,
|
||||
rpctls_vnetinit, NULL);
|
||||
|
||||
int
|
||||
rpctls_init(void)
|
||||
{
|
||||
int error, i;
|
||||
int error;
|
||||
|
||||
error = syscall_helper_register(rpctls_syscalls, SY_THR_STATIC_KLD);
|
||||
if (error != 0) {
|
||||
@ -107,8 +126,6 @@ rpctls_init(void)
|
||||
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;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -133,27 +150,36 @@ 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_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 +235,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
|
||||
@ -254,14 +284,14 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap)
|
||||
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 +299,14 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap)
|
||||
} 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 +330,10 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap)
|
||||
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 +372,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);
|
||||
@ -370,6 +400,7 @@ sys_rpctls_syscall(struct thread *td, struct rpctls_syscall_args *uap)
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
KRPC_CURVNET_RESTORE();
|
||||
|
||||
return (error);
|
||||
}
|
||||
@ -400,11 +431,13 @@ rpctls_server_client(int procpos)
|
||||
{
|
||||
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 +644,37 @@ rpctls_server(SVCXPRT *xprt, struct socket *so, uint32_t *flags, uint64_t *sslp,
|
||||
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 +709,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[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 +833,21 @@ 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[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);
|
||||
}
|
||||
|
||||
void
|
||||
rpctls_cleanup(void)
|
||||
{
|
||||
|
||||
free(KRPC_VNET(rpctls_server_handle), M_RPC);
|
||||
free(KRPC_VNET(rpctls_server_busy), M_RPC);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user