git: f0db2b6022df - main - nfsd: Continue adding macros so nfsd can run in a vnet prison
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 14 Feb 2023 21:38:04 UTC
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=f0db2b6022dfa15f375f5fcdd278b9df21cb88f5 commit f0db2b6022dfa15f375f5fcdd278b9df21cb88f5 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2023-02-14 21:33:35 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2023-02-14 21:33:35 +0000 nfsd: Continue adding macros so nfsd can run in a 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 some more, to allow the nfsuserd(8) daemon to run in vnet prison, once the macros map to vnet ones. This is the last commit for NFSD_VNET_xxx macros, but there are still some for KRPC_VNET_xxx and KGSS_VNET_xx to allow the rpc.tlsservd(8) and gssd(8) daemons to run in a vnet prison. MFC after: 3 months --- sys/fs/nfs/nfs_commonport.c | 14 ++- sys/fs/nfs/nfs_commonsubs.c | 289 ++++++++++++++++++++++++-------------------- 2 files changed, 169 insertions(+), 134 deletions(-) diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index e45f26d53799..2a2869641d25 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -56,8 +56,6 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> extern int nfscl_ticks; -extern nfsuserd_state nfsrv_nfsuserd; -extern struct nfssockreq nfsrv_nfsuserdsock; extern void (*nfsd_call_recall)(struct vnode *, int, struct ucred *, struct thread *); extern int nfsrv_useacl; @@ -77,6 +75,9 @@ uint32_t nfs_srvmaxio = NFS_SRVMAXIO; NFSD_VNET_DEFINE(struct nfsstatsv1 *, nfsstatsv1_p); +NFSD_VNET_DECLARE(struct nfssockreq, nfsrv_nfsuserdsock); +NFSD_VNET_DECLARE(nfsuserd_state, nfsrv_nfsuserd); + int nfs_pnfsio(task_fn_t *, void *); static int nfs_realign_test; @@ -857,6 +858,7 @@ nfs_clean(struct prison *pr) { NFSD_CURVNET_SET(pr->pr_vnet); + mtx_destroy(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx); if (pr != &prison0) free(NFSD_VNET(nfsstatsv1_p), M_TEMP); /* Clean out the name<-->id cache. */ @@ -876,6 +878,8 @@ nfs_vnetinit(const void *unused __unused) else NFSD_VNET(nfsstatsv1_p) = malloc(sizeof(struct nfsstatsv1), M_TEMP, M_WAITOK | M_ZERO); + mtx_init(&NFSD_VNET(nfsrv_nfsuserdsock).nr_mtx, "nfsuserd", + NULL, MTX_DEF); } SYSINIT(nfs_vnetinit, SI_SUB_VNET_DONE, SI_ORDER_ANY, nfs_vnetinit, NULL); @@ -900,8 +904,6 @@ nfscommon_modevent(module_t mod, int type, void *data) mtx_init(&nfs_sockl_mutex, "nfs_sockl_mutex", NULL, MTX_DEF); mtx_init(&nfs_slock_mutex, "nfs_slock_mutex", NULL, MTX_DEF); mtx_init(&nfs_req_mutex, "nfs_req_mutex", NULL, MTX_DEF); - mtx_init(&nfsrv_nfsuserdsock.nr_mtx, "nfsuserd", NULL, - MTX_DEF); mtx_init(&nfsrv_dslock_mtx, "nfs4ds", NULL, MTX_DEF); TAILQ_INIT(&nfsrv_devidhead); newnfs_init(); @@ -910,7 +912,8 @@ nfscommon_modevent(module_t mod, int type, void *data) break; case MOD_UNLOAD: - if (newnfs_numnfsd != 0 || nfsrv_nfsuserd != NOTRUNNING || + if (newnfs_numnfsd != 0 || + NFSD_VNET(nfsrv_nfsuserd) != NOTRUNNING || nfs_numnfscbd != 0) { error = EBUSY; break; @@ -926,7 +929,6 @@ nfscommon_modevent(module_t mod, int type, void *data) mtx_destroy(&nfs_sockl_mutex); mtx_destroy(&nfs_slock_mutex); mtx_destroy(&nfs_req_mutex); - mtx_destroy(&nfsrv_nfsuserdsock.nr_mtx); mtx_destroy(&nfsrv_dslock_mtx); loaded = 0; break; diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index c974e029efa8..e2e15063cf99 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -66,17 +66,10 @@ enum vtype nv34tov_type[8]={ VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO }; struct timeval nfsboottime; /* Copy boottime once, so it never changes */ int nfscl_ticks; int nfsrv_useacl = 1; -struct nfssockreq nfsrv_nfsuserdsock; -nfsuserd_state nfsrv_nfsuserd = NOTRUNNING; -static int nfsrv_userdupcalls = 0; struct nfsreqhead nfsd_reqq; -uid_t nfsrv_defaultuid = UID_NOBODY; -gid_t nfsrv_defaultgid = GID_NOGROUP; int nfsrv_lease = NFSRV_LEASE; int ncl_mbuf_mlen = MLEN; -int nfsd_enable_stringtouid = 0; int nfsrv_doflexfile = 0; -static int nfs_enable_uidtostring = 0; NFSNAMEIDMUTEX; NFSSOCKMUTEX; extern int nfsrv_lughashsize; @@ -87,9 +80,20 @@ extern struct nfsdevicehead nfsrv_devidhead; extern struct nfsstatsv1 nfsstatsv1; extern uint32_t nfs_srvmaxio; +NFSD_VNET_DEFINE(int, nfsd_enable_stringtouid) = 0; +NFSD_VNET_DEFINE(struct nfssockreq, nfsrv_nfsuserdsock); +NFSD_VNET_DEFINE(nfsuserd_state, nfsrv_nfsuserd) = NOTRUNNING; +NFSD_VNET_DEFINE(uid_t, nfsrv_defaultuid) = UID_NOBODY; +NFSD_VNET_DEFINE(gid_t, nfsrv_defaultgid) = GID_NOGROUP; + +NFSD_VNET_DEFINE_STATIC(int, nfsrv_userdupcalls) = 0; + SYSCTL_DECL(_vfs_nfs); -SYSCTL_INT(_vfs_nfs, OID_AUTO, enable_uidtostring, CTLFLAG_RW, - &nfs_enable_uidtostring, 0, "Make nfs always send numeric owner_names"); + +NFSD_VNET_DEFINE_STATIC(int, nfs_enable_uidtostring) = 0; +SYSCTL_INT(_vfs_nfs, OID_AUTO, enable_uidtostring, + CTLFLAG_NFSD_VNET | CTLFLAG_RW, &NFSD_VNET_NAME(nfs_enable_uidtostring), 0, + "Make nfs always send numeric owner_names"); int nfsrv_maxpnfsmirror = 1; SYSCTL_INT(_vfs_nfs, OID_AUTO, pnfsmirror, CTLFLAG_RD, @@ -192,18 +196,19 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = { }; static int ncl_mbuf_mhlen = MHLEN; -static int nfsrv_usercnt = 0; -static int nfsrv_dnsnamelen; -static u_char *nfsrv_dnsname = NULL; -static int nfsrv_usermax = 999999999; struct nfsrv_lughash { struct mtx mtx; struct nfsuserhashhead lughead; }; -static struct nfsrv_lughash *nfsuserhash; -static struct nfsrv_lughash *nfsusernamehash; -static struct nfsrv_lughash *nfsgrouphash; -static struct nfsrv_lughash *nfsgroupnamehash; + +NFSD_VNET_DEFINE_STATIC(int, nfsrv_usercnt) = 0; +NFSD_VNET_DEFINE_STATIC(int, nfsrv_dnsnamelen) = 0; +NFSD_VNET_DEFINE_STATIC(int, nfsrv_usermax) = 999999999; +NFSD_VNET_DEFINE_STATIC(struct nfsrv_lughash *, nfsuserhash) = NULL; +NFSD_VNET_DEFINE_STATIC(struct nfsrv_lughash *, nfsusernamehash) = NULL; +NFSD_VNET_DEFINE_STATIC(struct nfsrv_lughash *, nfsgrouphash) = NULL; +NFSD_VNET_DEFINE_STATIC(struct nfsrv_lughash *, nfsgroupnamehash) = NULL; +NFSD_VNET_DEFINE_STATIC(u_char *, nfsrv_dnsname) = NULL; /* * This static array indicates whether or not the RPC generates a large @@ -1245,6 +1250,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, #endif CTASSERT(sizeof(ino_t) == sizeof(uint64_t)); + NFSD_CURVNET_SET_QUIET(NFSD_TD_TO_VNET(curthread)); if (compare) { retnotsup = 0; error = nfsrv_getattrbits(nd, &attrbits, NULL, &retnotsup); @@ -1870,7 +1876,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, } } else if (nap != NULL) { if (nfsv4_strtouid(nd, cp, j, &uid)) - nap->na_uid = nfsrv_defaultuid; + nap->na_uid = + NFSD_VNET(nfsrv_defaultuid); else nap->na_uid = uid; } @@ -1903,7 +1910,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, } } else if (nap != NULL) { if (nfsv4_strtogid(nd, cp, j, &gid)) - nap->na_gid = nfsrv_defaultgid; + nap->na_gid = + NFSD_VNET(nfsrv_defaultgid); else nap->na_gid = gid; } @@ -2266,6 +2274,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, error = nfsm_advance(nd, attrsize - attrsum, -1); } nfsmout: + NFSD_CURVNET_RESTORE(); NFSEXITCODE2(error, nd); return (error); } @@ -3142,14 +3151,16 @@ nfsv4_uidtostr(uid_t uid, u_char **cpp, int *retlenp) int cnt, hasampersand, len = NFSV4_SMALLSTR, ret; struct nfsrv_lughash *hp; + NFSD_CURVNET_SET_QUIET(NFSD_TD_TO_VNET(curthread)); cnt = 0; tryagain: - if (nfsrv_dnsnamelen > 0 && !nfs_enable_uidtostring) { + if (NFSD_VNET(nfsrv_dnsnamelen) > 0 && + !NFSD_VNET(nfs_enable_uidtostring)) { /* * Always map nfsrv_defaultuid to "nobody". */ - if (uid == nfsrv_defaultuid) { - i = nfsrv_dnsnamelen + 7; + if (uid == NFSD_VNET(nfsrv_defaultuid)) { + i = NFSD_VNET(nfsrv_dnsnamelen) + 7; if (i > len) { if (len > NFSV4_SMALLSTR) free(cp, M_NFSSTRING); @@ -3161,7 +3172,9 @@ tryagain: *retlenp = i; NFSBCOPY("nobody@", cp, 7); cp += 7; - NFSBCOPY(nfsrv_dnsname, cp, nfsrv_dnsnamelen); + NFSBCOPY(NFSD_VNET(nfsrv_dnsname), cp, + NFSD_VNET(nfsrv_dnsnamelen)); + NFSD_CURVNET_RESTORE(); return; } hasampersand = 0; @@ -3185,7 +3198,7 @@ tryagain: i = usrp->lug_namelen; else i = usrp->lug_namelen + - nfsrv_dnsnamelen + 1; + NFSD_VNET(nfsrv_dnsnamelen) + 1; if (i > len) { mtx_unlock(&hp->mtx); if (len > NFSV4_SMALLSTR) @@ -3200,12 +3213,14 @@ tryagain: if (!hasampersand) { cp += usrp->lug_namelen; *cp++ = '@'; - NFSBCOPY(nfsrv_dnsname, cp, nfsrv_dnsnamelen); + NFSBCOPY(NFSD_VNET(nfsrv_dnsname), cp, + NFSD_VNET(nfsrv_dnsnamelen)); } TAILQ_REMOVE(&hp->lughead, usrp, lug_numhash); TAILQ_INSERT_TAIL(&hp->lughead, usrp, lug_numhash); mtx_unlock(&hp->mtx); + NFSD_CURVNET_RESTORE(); return; } } @@ -3233,6 +3248,7 @@ tryagain: *cp-- = '0' + (tmp % 10); tmp /= 10; } + NFSD_CURVNET_RESTORE(); return; } @@ -3253,7 +3269,7 @@ nfsrv_getgrpscred(struct ucred *oldcred) cnt = 0; uid = oldcred->cr_uid; tryagain: - if (nfsrv_dnsnamelen > 0) { + if (NFSD_VNET(nfsrv_dnsnamelen) > 0) { hp = NFSUSERHASH(uid); mtx_lock(&hp->mtx); TAILQ_FOREACH(usrp, &hp->lughead, lug_numhash) { @@ -3300,6 +3316,7 @@ nfsv4_strtouid(struct nfsrv_descript *nd, u_char *str, int len, uid_t *uidp) uid_t tuid; struct nfsrv_lughash *hp, *hp2; + NFSD_CURVNET_SET_QUIET(NFSD_TD_TO_VNET(curthread)); if (len == 0) { error = NFSERR_BADOWNER; goto out; @@ -3311,7 +3328,7 @@ nfsv4_strtouid(struct nfsrv_descript *nd, u_char *str, int len, uid_t *uidp) /* A numeric string. */ if ((nd->nd_flag & ND_KERBV) == 0 && ((nd->nd_flag & ND_NFSCL) != 0 || - nfsd_enable_stringtouid != 0)) + NFSD_VNET(nfsd_enable_stringtouid) != 0)) *uidp = tuid; else error = NFSERR_BADOWNER; @@ -3328,7 +3345,7 @@ nfsv4_strtouid(struct nfsrv_descript *nd, u_char *str, int len, uid_t *uidp) cnt = 0; tryagain: - if (nfsrv_dnsnamelen > 0) { + if (NFSD_VNET(nfsrv_dnsnamelen) > 0) { /* * If an '@' is found and the domain name matches, search for * the name with dns stripped off. @@ -3336,9 +3353,10 @@ tryagain: * all upper case will not. */ if (cnt == 0 && i < len && i > 0 && - (len - 1 - i) == nfsrv_dnsnamelen && - !nfsrv_cmpmixedcase(cp, nfsrv_dnsname, nfsrv_dnsnamelen)) { - len -= (nfsrv_dnsnamelen + 1); + (len - 1 - i) == NFSD_VNET(nfsrv_dnsnamelen) && + !nfsrv_cmpmixedcase(cp, + NFSD_VNET(nfsrv_dnsname), NFSD_VNET(nfsrv_dnsnamelen))) { + len -= (NFSD_VNET(nfsrv_dnsnamelen) + 1); *(cp - 1) = '\0'; } @@ -3346,7 +3364,7 @@ tryagain: * Check for the special case of "nobody". */ if (len == 6 && !NFSBCMP(str, "nobody", 6)) { - *uidp = nfsrv_defaultuid; + *uidp = NFSD_VNET(nfsrv_defaultuid); error = 0; goto out; } @@ -3380,6 +3398,7 @@ tryagain: error = NFSERR_BADOWNER; out: + NFSD_CURVNET_RESTORE(); NFSEXITCODE(error); return (error); } @@ -3401,14 +3420,16 @@ nfsv4_gidtostr(gid_t gid, u_char **cpp, int *retlenp) int cnt, hasampersand, len = NFSV4_SMALLSTR, ret; struct nfsrv_lughash *hp; + NFSD_CURVNET_SET_QUIET(NFSD_TD_TO_VNET(curthread)); cnt = 0; tryagain: - if (nfsrv_dnsnamelen > 0 && !nfs_enable_uidtostring) { + if (NFSD_VNET(nfsrv_dnsnamelen) > 0 && + !NFSD_VNET(nfs_enable_uidtostring)) { /* * Always map nfsrv_defaultgid to "nogroup". */ - if (gid == nfsrv_defaultgid) { - i = nfsrv_dnsnamelen + 8; + if (gid == NFSD_VNET(nfsrv_defaultgid)) { + i = NFSD_VNET(nfsrv_dnsnamelen) + 8; if (i > len) { if (len > NFSV4_SMALLSTR) free(cp, M_NFSSTRING); @@ -3420,7 +3441,9 @@ tryagain: *retlenp = i; NFSBCOPY("nogroup@", cp, 8); cp += 8; - NFSBCOPY(nfsrv_dnsname, cp, nfsrv_dnsnamelen); + NFSBCOPY(NFSD_VNET(nfsrv_dnsname), cp, + NFSD_VNET(nfsrv_dnsnamelen)); + NFSD_CURVNET_RESTORE(); return; } hasampersand = 0; @@ -3444,7 +3467,7 @@ tryagain: i = usrp->lug_namelen; else i = usrp->lug_namelen + - nfsrv_dnsnamelen + 1; + NFSD_VNET(nfsrv_dnsnamelen) + 1; if (i > len) { mtx_unlock(&hp->mtx); if (len > NFSV4_SMALLSTR) @@ -3459,12 +3482,14 @@ tryagain: if (!hasampersand) { cp += usrp->lug_namelen; *cp++ = '@'; - NFSBCOPY(nfsrv_dnsname, cp, nfsrv_dnsnamelen); + NFSBCOPY(NFSD_VNET(nfsrv_dnsname), cp, + NFSD_VNET(nfsrv_dnsnamelen)); } TAILQ_REMOVE(&hp->lughead, usrp, lug_numhash); TAILQ_INSERT_TAIL(&hp->lughead, usrp, lug_numhash); mtx_unlock(&hp->mtx); + NFSD_CURVNET_RESTORE(); return; } } @@ -3492,6 +3517,7 @@ tryagain: *cp-- = '0' + (tmp % 10); tmp /= 10; } + NFSD_CURVNET_RESTORE(); return; } @@ -3514,6 +3540,7 @@ nfsv4_strtogid(struct nfsrv_descript *nd, u_char *str, int len, gid_t *gidp) gid_t tgid; struct nfsrv_lughash *hp, *hp2; + NFSD_CURVNET_SET_QUIET(NFSD_TD_TO_VNET(curthread)); if (len == 0) { error = NFSERR_BADOWNER; goto out; @@ -3525,7 +3552,7 @@ nfsv4_strtogid(struct nfsrv_descript *nd, u_char *str, int len, gid_t *gidp) /* A numeric string. */ if ((nd->nd_flag & ND_KERBV) == 0 && ((nd->nd_flag & ND_NFSCL) != 0 || - nfsd_enable_stringtouid != 0)) + NFSD_VNET(nfsd_enable_stringtouid) != 0)) *gidp = tgid; else error = NFSERR_BADOWNER; @@ -3542,15 +3569,16 @@ nfsv4_strtogid(struct nfsrv_descript *nd, u_char *str, int len, gid_t *gidp) cnt = 0; tryagain: - if (nfsrv_dnsnamelen > 0) { + if (NFSD_VNET(nfsrv_dnsnamelen) > 0) { /* * If an '@' is found and the dns name matches, search for the * name with the dns stripped off. */ if (cnt == 0 && i < len && i > 0 && - (len - 1 - i) == nfsrv_dnsnamelen && - !nfsrv_cmpmixedcase(cp, nfsrv_dnsname, nfsrv_dnsnamelen)) { - len -= (nfsrv_dnsnamelen + 1); + (len - 1 - i) == NFSD_VNET(nfsrv_dnsnamelen) && + !nfsrv_cmpmixedcase(cp, + NFSD_VNET(nfsrv_dnsname), NFSD_VNET(nfsrv_dnsnamelen))) { + len -= (NFSD_VNET(nfsrv_dnsnamelen) + 1); *(cp - 1) = '\0'; } @@ -3558,7 +3586,7 @@ tryagain: * Check for the special case of "nogroup". */ if (len == 7 && !NFSBCMP(str, "nogroup", 7)) { - *gidp = nfsrv_defaultgid; + *gidp = NFSD_VNET(nfsrv_defaultgid); error = 0; goto out; } @@ -3592,6 +3620,7 @@ tryagain: error = NFSERR_BADOWNER; out: + NFSD_CURVNET_RESTORE(); NFSEXITCODE(error); return (error); } @@ -3642,12 +3671,12 @@ nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p) int error; NFSLOCKNAMEID(); - if (nfsrv_nfsuserd != NOTRUNNING) { + if (NFSD_VNET(nfsrv_nfsuserd) != NOTRUNNING) { NFSUNLOCKNAMEID(); error = EPERM; goto out; } - nfsrv_nfsuserd = STARTSTOP; + NFSD_VNET(nfsrv_nfsuserd) = STARTSTOP; /* * Set up the socket record and connect. * Set nr_client NULL before unlocking, just to ensure that no other @@ -3655,7 +3684,7 @@ nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p) * occur if the use of the nameid lock to protect nfsrv_nfsuserd is * broken. */ - rp = &nfsrv_nfsuserdsock; + rp = &NFSD_VNET(nfsrv_nfsuserdsock); rp->nr_client = NULL; NFSUNLOCKNAMEID(); rp->nr_sotype = SOCK_DGRAM; @@ -3696,12 +3725,12 @@ nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p) &rp->nr_client); if (error == 0) { NFSLOCKNAMEID(); - nfsrv_nfsuserd = RUNNING; + NFSD_VNET(nfsrv_nfsuserd) = RUNNING; NFSUNLOCKNAMEID(); } else { free(rp->nr_nam, M_SONAME); NFSLOCKNAMEID(); - nfsrv_nfsuserd = NOTRUNNING; + NFSD_VNET(nfsrv_nfsuserd) = NOTRUNNING; NFSUNLOCKNAMEID(); } out: @@ -3717,20 +3746,20 @@ nfsrv_nfsuserddelport(void) { NFSLOCKNAMEID(); - if (nfsrv_nfsuserd != RUNNING) { + if (NFSD_VNET(nfsrv_nfsuserd) != RUNNING) { NFSUNLOCKNAMEID(); return; } - nfsrv_nfsuserd = STARTSTOP; + NFSD_VNET(nfsrv_nfsuserd) = STARTSTOP; /* Wait for all upcalls to complete. */ - while (nfsrv_userdupcalls > 0) - msleep(&nfsrv_userdupcalls, NFSNAMEIDMUTEXPTR, PVFS, + while (NFSD_VNET(nfsrv_userdupcalls) > 0) + msleep(&NFSD_VNET(nfsrv_userdupcalls), NFSNAMEIDMUTEXPTR, PVFS, "nfsupcalls", 0); NFSUNLOCKNAMEID(); - newnfs_disconnect(NULL, &nfsrv_nfsuserdsock); - free(nfsrv_nfsuserdsock.nr_nam, M_SONAME); + newnfs_disconnect(NULL, &NFSD_VNET(nfsrv_nfsuserdsock)); + free(NFSD_VNET(nfsrv_nfsuserdsock).nr_nam, M_SONAME); NFSLOCKNAMEID(); - nfsrv_nfsuserd = NOTRUNNING; + NFSD_VNET(nfsrv_nfsuserd) = NOTRUNNING; NFSUNLOCKNAMEID(); } @@ -3750,7 +3779,7 @@ nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name) int error; NFSLOCKNAMEID(); - if (nfsrv_nfsuserd != RUNNING) { + if (NFSD_VNET(nfsrv_nfsuserd) != RUNNING) { NFSUNLOCKNAMEID(); error = EPERM; goto out; @@ -3759,9 +3788,9 @@ nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name) * Maintain a count of upcalls in progress, so that nfsrv_X() * can wait until no upcalls are in progress. */ - nfsrv_userdupcalls++; + NFSD_VNET(nfsrv_userdupcalls)++; NFSUNLOCKNAMEID(); - KASSERT(nfsrv_userdupcalls > 0, + KASSERT(NFSD_VNET(nfsrv_userdupcalls) > 0, ("nfsrv_getuser: non-positive upcalls")); nd = &nfsd; cred = newnfs_getcred(); @@ -3779,11 +3808,13 @@ nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name) len = strlen(name); (void) nfsm_strtom(nd, name, len); } - error = newnfs_request(nd, NULL, NULL, &nfsrv_nfsuserdsock, NULL, NULL, - cred, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, NULL, 0, NULL, NULL); + error = newnfs_request(nd, NULL, NULL, &NFSD_VNET(nfsrv_nfsuserdsock), + NULL, NULL, cred, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, NULL, 0, + NULL, NULL); NFSLOCKNAMEID(); - if (--nfsrv_userdupcalls == 0 && nfsrv_nfsuserd == STARTSTOP) - wakeup(&nfsrv_userdupcalls); + if (--NFSD_VNET(nfsrv_userdupcalls) == 0 && + NFSD_VNET(nfsrv_nfsuserd) == STARTSTOP) + wakeup(&NFSD_VNET(nfsrv_userdupcalls)); NFSUNLOCKNAMEID(); NFSFREECRED(cred); if (!error) { @@ -3823,7 +3854,8 @@ nfssvc_idname(struct nfsd_idargs *nidp) free(cp, M_NFSSTRING); goto out; } - if (atomic_cmpset_acq_int(&nfsrv_dnsnamelen, 0, 0) == 0) { + if (atomic_cmpset_acq_int(&NFSD_VNET(nfsrv_dnsnamelen), 0, 0) == + 0) { /* * Free up all the old stuff and reinitialize hash * lists. All mutexes for both lists must be locked, @@ -3831,80 +3863,81 @@ nfssvc_idname(struct nfsd_idargs *nidp) * ones, to avoid a LOR. */ for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsusernamehash[i].mtx); + mtx_lock(&NFSD_VNET(nfsusernamehash)[i].mtx); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsuserhash[i].mtx); + mtx_lock(&NFSD_VNET(nfsuserhash)[i].mtx); for (i = 0; i < nfsrv_lughashsize; i++) TAILQ_FOREACH_SAFE(usrp, - &nfsuserhash[i].lughead, lug_numhash, nusrp) + &NFSD_VNET(nfsuserhash)[i].lughead, lug_numhash, nusrp) nfsrv_removeuser(usrp, 1); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsuserhash[i].mtx); + mtx_unlock(&NFSD_VNET(nfsuserhash)[i].mtx); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsusernamehash[i].mtx); + mtx_unlock(&NFSD_VNET(nfsusernamehash)[i].mtx); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsgroupnamehash[i].mtx); + mtx_lock(&NFSD_VNET(nfsgroupnamehash)[i].mtx); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsgrouphash[i].mtx); + mtx_lock(&NFSD_VNET(nfsgrouphash)[i].mtx); for (i = 0; i < nfsrv_lughashsize; i++) TAILQ_FOREACH_SAFE(usrp, - &nfsgrouphash[i].lughead, lug_numhash, + &NFSD_VNET(nfsgrouphash)[i].lughead, lug_numhash, nusrp) nfsrv_removeuser(usrp, 0); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsgrouphash[i].mtx); + mtx_unlock(&NFSD_VNET(nfsgrouphash)[i].mtx); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsgroupnamehash[i].mtx); - free(nfsrv_dnsname, M_NFSSTRING); - nfsrv_dnsname = NULL; + mtx_unlock(&NFSD_VNET(nfsgroupnamehash)[i].mtx); + free(NFSD_VNET(nfsrv_dnsname), M_NFSSTRING); + NFSD_VNET(nfsrv_dnsname) = NULL; } - if (nfsuserhash == NULL) { + if (NFSD_VNET(nfsuserhash) == NULL) { /* Allocate the hash tables. */ - nfsuserhash = malloc(sizeof(struct nfsrv_lughash) * + NFSD_VNET(nfsuserhash) = malloc(sizeof(struct nfsrv_lughash) * nfsrv_lughashsize, M_NFSUSERGROUP, M_WAITOK | M_ZERO); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_init(&nfsuserhash[i].mtx, "nfsuidhash", + mtx_init(&NFSD_VNET(nfsuserhash)[i].mtx, "nfsuidhash", NULL, MTX_DEF | MTX_DUPOK); - nfsusernamehash = malloc(sizeof(struct nfsrv_lughash) * + NFSD_VNET(nfsusernamehash) = malloc(sizeof(struct nfsrv_lughash) * nfsrv_lughashsize, M_NFSUSERGROUP, M_WAITOK | M_ZERO); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_init(&nfsusernamehash[i].mtx, + mtx_init(&NFSD_VNET(nfsusernamehash)[i].mtx, "nfsusrhash", NULL, MTX_DEF | MTX_DUPOK); - nfsgrouphash = malloc(sizeof(struct nfsrv_lughash) * + NFSD_VNET(nfsgrouphash) = malloc(sizeof(struct nfsrv_lughash) * nfsrv_lughashsize, M_NFSUSERGROUP, M_WAITOK | M_ZERO); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_init(&nfsgrouphash[i].mtx, "nfsgidhash", + mtx_init(&NFSD_VNET(nfsgrouphash)[i].mtx, "nfsgidhash", NULL, MTX_DEF | MTX_DUPOK); - nfsgroupnamehash = malloc(sizeof(struct nfsrv_lughash) * + NFSD_VNET(nfsgroupnamehash) = malloc(sizeof(struct nfsrv_lughash) * nfsrv_lughashsize, M_NFSUSERGROUP, M_WAITOK | M_ZERO); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_init(&nfsgroupnamehash[i].mtx, + mtx_init(&NFSD_VNET(nfsgroupnamehash)[i].mtx, "nfsgrphash", NULL, MTX_DEF | MTX_DUPOK); } /* (Re)initialize the list heads. */ for (i = 0; i < nfsrv_lughashsize; i++) - TAILQ_INIT(&nfsuserhash[i].lughead); + TAILQ_INIT(&NFSD_VNET(nfsuserhash)[i].lughead); for (i = 0; i < nfsrv_lughashsize; i++) - TAILQ_INIT(&nfsusernamehash[i].lughead); + TAILQ_INIT(&NFSD_VNET(nfsusernamehash)[i].lughead); for (i = 0; i < nfsrv_lughashsize; i++) - TAILQ_INIT(&nfsgrouphash[i].lughead); + TAILQ_INIT(&NFSD_VNET(nfsgrouphash)[i].lughead); for (i = 0; i < nfsrv_lughashsize; i++) - TAILQ_INIT(&nfsgroupnamehash[i].lughead); + TAILQ_INIT(&NFSD_VNET(nfsgroupnamehash)[i].lughead); /* * Put name in "DNS" string. */ - nfsrv_dnsname = cp; - nfsrv_defaultuid = nidp->nid_uid; - nfsrv_defaultgid = nidp->nid_gid; - nfsrv_usercnt = 0; - nfsrv_usermax = nidp->nid_usermax; - atomic_store_rel_int(&nfsrv_dnsnamelen, nidp->nid_namelen); + NFSD_VNET(nfsrv_dnsname) = cp; + NFSD_VNET(nfsrv_defaultuid) = nidp->nid_uid; + NFSD_VNET(nfsrv_defaultgid) = nidp->nid_gid; + NFSD_VNET(nfsrv_usercnt) = 0; + NFSD_VNET(nfsrv_usermax) = nidp->nid_usermax; + atomic_store_rel_int(&NFSD_VNET(nfsrv_dnsnamelen), + nidp->nid_namelen); goto out; } @@ -3931,7 +3964,7 @@ nfssvc_idname(struct nfsd_idargs *nidp) cr->cr_uid = cr->cr_ruid = cr->cr_svuid = nidp->nid_uid; crsetgroups(cr, nidp->nid_ngroup, grps); cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0]; - cr->cr_prison = &prison0; + cr->cr_prison = curthread->td_ucred->cr_prison; prison_hold(cr->cr_prison); #ifdef MAC mac_cred_associate_nfsd(cr); @@ -3963,7 +3996,7 @@ nfssvc_idname(struct nfsd_idargs *nidp) if (nidp->nid_flag & (NFSID_DELUID | NFSID_ADDUID)) { /* Must lock all username hash lists first, to avoid a LOR. */ for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsusernamehash[i].mtx); + mtx_lock(&NFSD_VNET(nfsusernamehash)[i].mtx); username_locked = 1; hp_idnum = NFSUSERHASH(nidp->nid_uid); mtx_lock(&hp_idnum->mtx); @@ -3992,7 +4025,7 @@ nfssvc_idname(struct nfsd_idargs *nidp) } else if (nidp->nid_flag & (NFSID_DELGID | NFSID_ADDGID)) { /* Must lock all groupname hash lists first, to avoid a LOR. */ for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsgroupnamehash[i].mtx); + mtx_lock(&NFSD_VNET(nfsgroupnamehash)[i].mtx); groupname_locked = 1; hp_idnum = NFSGROUPHASH(nidp->nid_gid); mtx_lock(&hp_idnum->mtx); @@ -4035,7 +4068,7 @@ nfssvc_idname(struct nfsd_idargs *nidp) thp = NFSUSERNAMEHASH(newusrp->lug_name, newusrp->lug_namelen); mtx_assert(&thp->mtx, MA_OWNED); TAILQ_INSERT_TAIL(&thp->lughead, newusrp, lug_namehash); - atomic_add_int(&nfsrv_usercnt, 1); + atomic_add_int(&NFSD_VNET(nfsrv_usercnt), 1); } else if (nidp->nid_flag & (NFSID_ADDGID | NFSID_ADDGROUPNAME)) { newusrp->lug_gid = nidp->nid_gid; thp = NFSGROUPHASH(newusrp->lug_gid); @@ -4044,7 +4077,7 @@ nfssvc_idname(struct nfsd_idargs *nidp) thp = NFSGROUPNAMEHASH(newusrp->lug_name, newusrp->lug_namelen); mtx_assert(&thp->mtx, MA_OWNED); TAILQ_INSERT_TAIL(&thp->lughead, newusrp, lug_namehash); - atomic_add_int(&nfsrv_usercnt, 1); + atomic_add_int(&NFSD_VNET(nfsrv_usercnt), 1); } else { if (newusrp->lug_cred != NULL) crfree(newusrp->lug_cred); @@ -4073,17 +4106,17 @@ nfssvc_idname(struct nfsd_idargs *nidp) NFSID_DELUSERNAME | NFSID_ADDUSERNAME)) != 0) { if (username_locked == 0) { for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsusernamehash[i].mtx); + mtx_lock(&NFSD_VNET(nfsusernamehash)[i].mtx); username_locked = 1; } KASSERT(user_locked == 0, ("nfssvc_idname: user_locked")); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsuserhash[i].mtx); + mtx_lock(&NFSD_VNET(nfsuserhash)[i].mtx); user_locked = 1; for (i = 0; i < nfsrv_lughashsize; i++) { TAILQ_FOREACH_SAFE(usrp, - &nfsuserhash[i].lughead, lug_numhash, + &NFSD_VNET(nfsuserhash)[i].lughead, lug_numhash, nusrp) if (usrp->lug_expiry < NFSD_MONOSEC) nfsrv_removeuser(usrp, 1); @@ -4094,26 +4127,26 @@ nfssvc_idname(struct nfsd_idargs *nidp) * algorithm. This code deletes the least * recently used entry on each hash list. */ - if (nfsrv_usercnt <= nfsrv_usermax) + if (NFSD_VNET(nfsrv_usercnt) <= NFSD_VNET(nfsrv_usermax)) break; - usrp = TAILQ_FIRST(&nfsuserhash[i].lughead); + usrp = TAILQ_FIRST(&NFSD_VNET(nfsuserhash)[i].lughead); if (usrp != NULL) nfsrv_removeuser(usrp, 1); } } else { if (groupname_locked == 0) { for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsgroupnamehash[i].mtx); + mtx_lock(&NFSD_VNET(nfsgroupnamehash)[i].mtx); groupname_locked = 1; } KASSERT(group_locked == 0, ("nfssvc_idname: group_locked")); for (i = 0; i < nfsrv_lughashsize; i++) - mtx_lock(&nfsgrouphash[i].mtx); + mtx_lock(&NFSD_VNET(nfsgrouphash)[i].mtx); group_locked = 1; for (i = 0; i < nfsrv_lughashsize; i++) { TAILQ_FOREACH_SAFE(usrp, - &nfsgrouphash[i].lughead, lug_numhash, + &NFSD_VNET(nfsgrouphash)[i].lughead, lug_numhash, nusrp) if (usrp->lug_expiry < NFSD_MONOSEC) nfsrv_removeuser(usrp, 0); @@ -4124,9 +4157,9 @@ nfssvc_idname(struct nfsd_idargs *nidp) * algorithm. This code deletes the least * recently user entry on each hash list. */ - if (nfsrv_usercnt <= nfsrv_usermax) + if (NFSD_VNET(nfsrv_usercnt) <= NFSD_VNET(nfsrv_usermax)) break; - usrp = TAILQ_FIRST(&nfsgrouphash[i].lughead); + usrp = TAILQ_FIRST(&NFSD_VNET(nfsgrouphash)[i].lughead); if (usrp != NULL) nfsrv_removeuser(usrp, 0); } @@ -4142,16 +4175,16 @@ nfssvc_idname(struct nfsd_idargs *nidp) mtx_unlock(&hp_name->mtx); if (user_locked != 0) for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsuserhash[i].mtx); + mtx_unlock(&NFSD_VNET(nfsuserhash)[i].mtx); if (username_locked != 0) for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsusernamehash[i].mtx); + mtx_unlock(&NFSD_VNET(nfsusernamehash)[i].mtx); if (group_locked != 0) for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsgrouphash[i].mtx); + mtx_unlock(&NFSD_VNET(nfsgrouphash)[i].mtx); if (groupname_locked != 0) for (i = 0; i < nfsrv_lughashsize; i++) - mtx_unlock(&nfsgroupnamehash[i].mtx); + mtx_unlock(&NFSD_VNET(nfsgroupnamehash)[i].mtx); out: NFSEXITCODE(error); return (error); @@ -4180,7 +4213,7 @@ nfsrv_removeuser(struct nfsusrgrp *usrp, int isuser) mtx_assert(&hp->mtx, MA_OWNED); TAILQ_REMOVE(&hp->lughead, usrp, lug_namehash); } - atomic_add_int(&nfsrv_usercnt, -1); + atomic_add_int(&NFSD_VNET(nfsrv_usercnt), -1); if (usrp->lug_cred != NULL) crfree(usrp->lug_cred); free(usrp, M_NFSUSERGROUP); @@ -4190,7 +4223,7 @@ nfsrv_removeuser(struct nfsusrgrp *usrp, int isuser) * Free up all the allocations related to the name<-->id cache. * This function should only be called when the nfsuserd daemon isn't * running, since it doesn't do any locking. - * This function is meant to be used when the nfscommon module is unloaded. + * This function is meant to be called when a vnet jail is destroyed. */ void nfsrv_cleanusergroup(void) @@ -4199,11 +4232,11 @@ nfsrv_cleanusergroup(void) struct nfsusrgrp *nusrp, *usrp; int i; - if (nfsuserhash == NULL) + if (NFSD_VNET(nfsuserhash) == NULL) return; for (i = 0; i < nfsrv_lughashsize; i++) { - hp = &nfsuserhash[i]; + hp = &NFSD_VNET(nfsuserhash)[i]; TAILQ_FOREACH_SAFE(usrp, &hp->lughead, lug_numhash, nusrp) { TAILQ_REMOVE(&hp->lughead, usrp, lug_numhash); hp2 = NFSUSERNAMEHASH(usrp->lug_name, @@ -4213,7 +4246,7 @@ nfsrv_cleanusergroup(void) crfree(usrp->lug_cred); free(usrp, M_NFSUSERGROUP); } - hp = &nfsgrouphash[i]; + hp = &NFSD_VNET(nfsgrouphash)[i]; TAILQ_FOREACH_SAFE(usrp, &hp->lughead, lug_numhash, nusrp) { TAILQ_REMOVE(&hp->lughead, usrp, lug_numhash); hp2 = NFSGROUPNAMEHASH(usrp->lug_name, @@ -4223,16 +4256,16 @@ nfsrv_cleanusergroup(void) crfree(usrp->lug_cred); free(usrp, M_NFSUSERGROUP); } - mtx_destroy(&nfsuserhash[i].mtx); - mtx_destroy(&nfsusernamehash[i].mtx); - mtx_destroy(&nfsgroupnamehash[i].mtx); - mtx_destroy(&nfsgrouphash[i].mtx); + mtx_destroy(&NFSD_VNET(nfsuserhash)[i].mtx); + mtx_destroy(&NFSD_VNET(nfsusernamehash)[i].mtx); + mtx_destroy(&NFSD_VNET(nfsgroupnamehash)[i].mtx); + mtx_destroy(&NFSD_VNET(nfsgrouphash)[i].mtx); } - free(nfsuserhash, M_NFSUSERGROUP); - free(nfsusernamehash, M_NFSUSERGROUP); - free(nfsgrouphash, M_NFSUSERGROUP); - free(nfsgroupnamehash, M_NFSUSERGROUP); - free(nfsrv_dnsname, M_NFSSTRING); + free(NFSD_VNET(nfsuserhash), M_NFSUSERGROUP); + free(NFSD_VNET(nfsusernamehash), M_NFSUSERGROUP); + free(NFSD_VNET(nfsgrouphash), M_NFSUSERGROUP); + free(NFSD_VNET(nfsgroupnamehash), M_NFSUSERGROUP); + free(NFSD_VNET(nfsrv_dnsname), M_NFSSTRING); } /*