From nobody Wed Feb 15 13:59:52 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PH07r6LMvz3q6ZF; Wed, 15 Feb 2023 13:59:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PH07r5r1tz4PSV; Wed, 15 Feb 2023 13:59:52 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1676469592; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vuhmZcyUFlybO35urzA3kpnruQ49FEHt1UYJ5YftFzk=; b=L6D73l2wuVmb0yGZgMzjSkD2DxdCgm1nYE0fYgVIS/tdZM81KkbqBB4Rt5pNwPHvHDF3VX CqkemcgGe9AcS6L9TU8A35utTOgUFwHi/gSsBwoNhQUTsjT/oNcA/0tRA8dGPex4wexYUg ZEQ+FFu3aoIFuVvZooTlCChrFohQagw3EtnZPmLQiJfhUJAohPAfiu6CPUQWYVVGnvqUHG 8AGCQ/XPmUtb21NB8zJUCAAlPmwZWvbgvu8gelx6LI0TcvyNFWjQCNfpf8E2veVj0gigo9 eAn7c0gFfWli3TAjy0cVkl4XIrwmoKW6e8sd0MNH3we7ONRcuC5/3mMYnpsxuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1676469592; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vuhmZcyUFlybO35urzA3kpnruQ49FEHt1UYJ5YftFzk=; b=kGvTdQk/NLuU8H/I1sDGfkDlxYLHqYVAwWh56lQ/wD2TG96FBBsb3IuFERQcii11JgI1eM AVFAd+MLtE/1W+c3aXB61f+abIrZr6q97oEDh1OoMaEB/rPXISIP1zerE9MRVnZq+M/rPq BdXd/7oONSaBNQsI+gUX8s3ne+GSgQUlV7r6+ISa5hLXdqq6LI0w9MZUoPvFVQYQyg7jot aTyiR52hdXHhtpjFa9gMk+ogbt1OVCCq/nBZDE6NLR2yeyz1X8ih9J0MiYraHwqjmWxH93 W5H5mSfqdEaAPoFPGeaXTIFawWltete5QOJFVxiFiHSuG724QNol3vLPGkGJRw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1676469592; a=rsa-sha256; cv=none; b=Ej5kfUUvREX3U+7buwWQajKjxWAo5zTcaPrxhbVf/x0KVKptn+Wko0eQlOIUjxhwo3EHb1 ZvFWuUHSsBNmEU/uuagAeHaGgjMNqgayrJjT/cjkPqi51xC9pAAr9379iiSObNEwimE3hY WBC81pUB9qD8MdL4ES98D6XiR/rb7WBAoAVEqnC4KUb9AipfrimJkEPHyG2/nkCRKDgxnR FCIHTNK5/4pBZW3Fm+9pueuQbvJPgF2vz7GIF2VOfic5UKKajGDhMrPVs/XA2471uhrh8y K+rWPd6SbSXyNb2lxGhqyqMnrwgbxem2OGNiTs+fZkrLWnYirbjZfb24AcAg9w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4PH07r4tb4zR4q; Wed, 15 Feb 2023 13:59:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 31FDxqN8059363; Wed, 15 Feb 2023 13:59:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 31FDxqIN059362; Wed, 15 Feb 2023 13:59:52 GMT (envelope-from git) Date: Wed, 15 Feb 2023 13:59:52 GMT Message-Id: <202302151359.31FDxqIN059362@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Rick Macklem Subject: git: 6444662a563b - main - krpc: Add macros so that rpc.tlsservd can run in vnet prison List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6444662a563ba714fed8563645764262c6f5e90f Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=6444662a563ba714fed8563645764262c6f5e90f commit 6444662a563ba714fed8563645764262c6f5e90f Author: Rick Macklem AuthorDate: 2023-02-15 13:58:21 +0000 Commit: Rick Macklem CommitDate: 2023-02-15 13:58:21 +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. MFC after: 3 months --- sys/rpc/rpcsec_tls.h | 18 +++++ sys/rpc/rpcsec_tls/rpctls_impl.c | 164 +++++++++++++++++++++++++-------------- 2 files changed, 125 insertions(+), 57 deletions(-) diff --git a/sys/rpc/rpcsec_tls.h b/sys/rpc/rpcsec_tls.h index 6c49f9577cc8..ac2fee1b09fc 100644 --- a/sys/rpc/rpcsec_tls.h +++ b/sys/rpc/rpcsec_tls.h @@ -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_ */ diff --git a/sys/rpc/rpcsec_tls/rpctls_impl.c b/sys/rpc/rpcsec_tls/rpctls_impl.c index 9d7f686af768..4e9d52bf5d48 100644 --- a/sys/rpc/rpcsec_tls/rpctls_impl.c +++ b/sys/rpc/rpcsec_tls/rpctls_impl.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -51,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include #include @@ -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); +} +