From nobody Wed Jun 3 20:02:49 2026 X-Original-To: dev-commits-src-branches@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 4gVzBx6ZJfz6gckP for ; Wed, 03 Jun 2026 20:02:49 +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 "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gVzBx3pYZz4PSd for ; Wed, 03 Jun 2026 20:02:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1780516969; 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=pJm7IJCMVpf6mldyi2DQ3xhldIrlGL7q8pmWHjvfBCI=; b=yGxaobn1z96Mre62VybC7a7rI9+MhHrwrFbhdsbA1DTrAKxzTQxRcNygdksx+8RZVXIjHE mFTj0xI2KoDaXNs3gprh9EeMFMdNGwwu1UbBK/FQ5DsGt5IMI9GNPQuH/feUUOYt+JeHoE i++D8yfeJKhC7FSvXLKdgMiiv38ei/PfdEUJvKv9IG9Pq8vaVJLqXB9/q7vWPaApXNdaGM e8mEAz1U3rDDriN+KsD9Zz2mfMsa3M57pHSaR/9ZXATgohOxLCXvgBhxMOhszIMyOZZbnk LsBC1ihCR6aYiNaRyW30Fyx9xj601s/XuP0FOqbKdiq6VzTcJ++NNzfAGwJD7w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1780516969; a=rsa-sha256; cv=none; b=ybQly4p2yKhnav+7+sulLczS+gjDcUr0c7gC28XppjWZxr6PRCSgcUIeo8VpXQPnp8sYCJ QurjgyiiXl/dweVCAsUG0EgeB0xNjtp2htRgwjfjhitGih7xgMy+rwLstc+KH+hVzpjV+F B6IzFzhBgrV8iSfYFYR45svySknl/y1rtwJHD0wEBYY2WMXA3DTDr0d5Kr2lZjDQuJqWIa OgwqzXqdJJxQVvuhzXt7Y5qMWIEWVARTyfSCr+vHbZDY7luvekZ/5Y3ZdfoPXjojdlB7st r+5NO/eopwGrX2i6RjmyBafzAf3DksFtDOVLclHyrKeObI74MhEaWm3+Gdc1MA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1780516969; 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=pJm7IJCMVpf6mldyi2DQ3xhldIrlGL7q8pmWHjvfBCI=; b=a7gAjUJ0c35MZKwovScWdUwEBXibhJtC4uF/3pk2gg1jyh49Npw17/Gyryxrk+oFr/kjUE Sh2RggTlhYpDn2guckFugiisa21ru19sL0V3bnPOOXb2zgekuztC6yp0Ruxh+qr7HWs15S z40juZiG8gJLW7i0yaCLQTCBXXGUVCaDNtIHztHYXKcvVtlA8RUtGOcf6DIccZWzRAS5dM 6BITux2WdRaMRfPeBN2yK+LNySpOvUobCjPJt5OlNULmeZL7zKo8rYS9HFRDNQF+6Bikvj nKwrHqGGOZpBnXZEgLyt0GYdyWA3nAKvBzLUMauaDW8DybeYKpeUG7+KbahOsg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gVzBx3Q6Lz9nm for ; Wed, 03 Jun 2026 20:02:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 335d0 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 03 Jun 2026 20:02:49 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Rick Macklem Subject: git: ce77cd3d9c1a - stable/15 - nfscl: Fix handling of gssd upcalls for the NFS client List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list 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/stable/15 X-Git-Reftype: branch X-Git-Commit: ce77cd3d9c1a2752a1bb5641320f281fb83ec468 Auto-Submitted: auto-generated Date: Wed, 03 Jun 2026 20:02:49 +0000 Message-Id: <6a208869.335d0.65dff694@gitrepo.freebsd.org> The branch stable/15 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=ce77cd3d9c1a2752a1bb5641320f281fb83ec468 commit ce77cd3d9c1a2752a1bb5641320f281fb83ec468 Author: Rick Macklem AuthorDate: 2026-05-02 19:36:00 +0000 Commit: Rick Macklem CommitDate: 2026-06-03 19:59:46 +0000 nfscl: Fix handling of gssd upcalls for the NFS client Without this patch, all upcalls to the gssd daemon are done in vnet0 (outside of any vnet jail). This does not work well, because a user principal's credential cache can be within the jail (/tmp/krb5cc_NNN in the jail's namespace). This patch modifies the client so that RPCs done from within vnet jails does an upcall to a gssd daemon running within the vnet jail. It required that the cache of uid->credential shorthands in the rpcsec_gss be vnet'd. The situation is still less than ideal and sec=krb5[ip] mounts that are visible within vnet jails is still not something I would recommend, but it can work ok with this patch. Vnet'ng the NFS client so that mounts can be done within vnet jails is probably more useful, but that will require additional work. (cherry picked from commit a6e527f893df2cbbd941839a93e50ae39ac0db55) --- sys/fs/nfs/nfs_commonkrpc.c | 23 +++++++- sys/fs/nfs/nfs_commonsubs.c | 3 +- sys/fs/nfsserver/nfs_nfsdserv.c | 8 ++- sys/fs/nfsserver/nfs_nfsdstate.c | 1 + sys/rpc/clnt_bck.c | 7 ++- sys/rpc/clnt_dg.c | 7 ++- sys/rpc/clnt_vc.c | 7 ++- sys/rpc/rpcsec_gss/rpcsec_gss.c | 111 +++++++++++++++++++++------------------ 8 files changed, 107 insertions(+), 60 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 1e4e8506790f..9ea4e5f4c9df 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -561,7 +561,9 @@ newnfs_disconnect(struct nfsmount *nmp, struct nfssockreq *nrp) } } mtx_unlock(&nrp->nr_mtx); + CURVNET_SET_QUIET(CRED_TO_VNET(nrp->nr_cred)); rpc_gss_secpurge_call(client); + CURVNET_RESTORE(); CLNT_CLOSE(client); CLNT_RELEASE(client); if (nmp != NULL && nmp->nm_aconnect > 0) { @@ -685,7 +687,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, struct nfsreq *rep = NULL; char *srv_principal = NULL, *clnt_principal = NULL; sigset_t oldset; - struct ucred *authcred; + struct ucred *authcred, *savcred; struct nfsclsession *sep; uint8_t sessionid[NFSX_V4SESSIONID]; bool nextconn_set; @@ -832,6 +834,11 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, ((nmp->nm_tprintf_delay)-(nmp->nm_tprintf_initial_delay)); } + /* + * For Kerberos, the upcall needs to be done to the gssd daemon + * running in the correct vnet. + */ + CURVNET_SET_QUIET(CRED_TO_VNET(authcred)); if (nd->nd_procnum == NFSPROC_NULL) auth = authnone_create(); else if (usegssname) { @@ -849,8 +856,9 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, } else auth = nfs_getauth(nrp, secflavour, NULL, srv_principal, NULL, authcred); - crfree(authcred); + CURVNET_RESTORE(); if (auth == NULL) { + crfree(authcred); m_freem(nd->nd_mreq); if (set_sigset) newnfs_restore_sigmask(td, &oldset); @@ -967,6 +975,13 @@ tryagain: } } + /* + * In case CLNT_CALL_MBUF()/clnt_bck_call() does an AUTH_REFRESH(), + * the thread's credentials need to be set to authcred, so that the + * correct vnet will be set. + */ + savcred = curthread->td_ucred; + curthread->td_ucred = authcred; nd->nd_mrep = NULL; if (clp != NULL && sep != NULL) stat = clnt_bck_call(nrp->nr_client, &ext, procnum, @@ -988,6 +1003,7 @@ tryagain: stat = CLNT_CALL_MBUF(nrp->nr_client, &ext, procnum, nd->nd_mreq, &nd->nd_mrep, timo); NFSCL_DEBUG(2, "clnt call=%d\n", stat); + curthread->td_ucred = savcred; if (rep != NULL) { /* @@ -1069,6 +1085,7 @@ tryagain: error = EACCES; } if (error) { + crfree(authcred); m_freem(nd->nd_mreq); if (usegssname == 0) AUTH_DESTROY(auth); @@ -1429,6 +1446,7 @@ tryagain: } } out: + crfree(authcred); #ifdef KDTRACE_HOOKS if (nmp != NULL && dtrace_nfscl_nfs234_done_probe != NULL) { @@ -1460,6 +1478,7 @@ out: newnfs_restore_sigmask(td, &oldset); return (0); nfsmout: + crfree(authcred); m_freem(nd->nd_mrep); m_freem(nd->nd_mreq); if (usegssname == 0) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 39d7cb447d6a..95703b4cf94d 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -4168,7 +4168,7 @@ nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p) rp->nr_sotype = SOCK_DGRAM; rp->nr_soproto = IPPROTO_UDP; rp->nr_lock = (NFSR_RESERVEDPORT | NFSR_LOCALHOST); - rp->nr_cred = NULL; + rp->nr_cred = crhold(curthread->td_ucred); rp->nr_prog = RPCPROG_NFSUSERD; error = 0; switch (nargs->nuserd_family) { @@ -4236,6 +4236,7 @@ nfsrv_nfsuserddelport(void) NFSUNLOCKNAMEID(); newnfs_disconnect(NULL, &NFSD_VNET(nfsrv_nfsuserdsock)); free(NFSD_VNET(nfsrv_nfsuserdsock).nr_nam, M_SONAME); + crfree(VNET(nfsrv_nfsuserdsock).nr_cred); NFSLOCKNAMEID(); NFSD_VNET(nfsrv_nfsuserd) = NOTRUNNING; NFSUNLOCKNAMEID(); diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 41f3c6893378..0124de2db93d 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -4270,7 +4270,7 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram, /* Allocated large enough for an AF_INET or AF_INET6 socket. */ clp->lc_req.nr_nam = malloc(sizeof(struct sockaddr_in6), M_SONAME, M_WAITOK | M_ZERO); - clp->lc_req.nr_cred = NULL; + clp->lc_req.nr_cred = crhold(nd->nd_cred); NFSBCOPY(verf, clp->lc_verf, NFSX_VERF); clp->lc_idlen = idlen; error = nfsrv_mtostr(nd, clp->lc_id, idlen); @@ -4360,6 +4360,7 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram, if (clp) { free(clp->lc_req.nr_nam, M_SONAME); NFSFREEMUTEX(&clp->lc_req.nr_mtx); + crfree(clp->lc_req.nr_cred); free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); } @@ -4378,6 +4379,7 @@ nfsmout: if (clp) { free(clp->lc_req.nr_nam, M_SONAME); NFSFREEMUTEX(&clp->lc_req.nr_mtx); + crfree(clp->lc_req.nr_cred); free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); } @@ -4635,7 +4637,7 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram, break; #endif } - clp->lc_req.nr_cred = NULL; + clp->lc_req.nr_cred = crhold(nd->nd_cred); NFSBCOPY(verf, clp->lc_verf, NFSX_VERF); clp->lc_idlen = idlen; error = nfsrv_mtostr(nd, clp->lc_id, idlen); @@ -4708,6 +4710,7 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram, if (clp != NULL) { free(clp->lc_req.nr_nam, M_SONAME); NFSFREEMUTEX(&clp->lc_req.nr_mtx); + crfree(clp->lc_req.nr_cred); free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); } @@ -4751,6 +4754,7 @@ nfsmout: if (clp != NULL) { free(clp->lc_req.nr_nam, M_SONAME); NFSFREEMUTEX(&clp->lc_req.nr_mtx); + crfree(clp->lc_req.nr_cred); free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); } diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index e36a5c7810da..fd27de05b35f 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -1503,6 +1503,7 @@ nfsrv_zapclient(struct nfsclient *clp, NFSPROC_T *p) newnfs_disconnect(NULL, &clp->lc_req); free(clp->lc_req.nr_nam, M_SONAME); NFSFREEMUTEX(&clp->lc_req.nr_mtx); + crfree(clp->lc_req.nr_cred); free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); NFSLOCKSTATE(); diff --git a/sys/rpc/clnt_bck.c b/sys/rpc/clnt_bck.c index c5cbbf045bdc..9ff85b1fa2c0 100644 --- a/sys/rpc/clnt_bck.c +++ b/sys/rpc/clnt_bck.c @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -440,15 +441,19 @@ got_reply: * If unsuccessful AND error is an authentication error * then refresh credentials and try again, else break */ - else if (stat == RPC_AUTHERROR) + else if (stat == RPC_AUTHERROR) { /* maybe our credentials need to be refreshed ... */ + CURVNET_SET_QUIET(TD_TO_VNET(curthread)); if (nrefreshes > 0 && AUTH_REFRESH(auth, &reply_msg)) { + CURVNET_RESTORE(); nrefreshes--; XDR_DESTROY(&xdrs); mtx_lock(&ct->ct_lock); goto call_again; } + CURVNET_RESTORE(); /* end of unsuccessful completion */ + } /* end of valid reply message */ } else errp->re_status = stat = RPC_CANTDECODERES; diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c index b6a8cdce0d76..d7870aef5674 100644 --- a/sys/rpc/clnt_dg.c +++ b/sys/rpc/clnt_dg.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -738,15 +739,19 @@ got_reply: * If unsuccessful AND error is an authentication error * then refresh credentials and try again, else break */ - else if (stat == RPC_AUTHERROR) + else if (stat == RPC_AUTHERROR) { /* maybe our credentials need to be refreshed ... */ + CURVNET_SET_QUIET(TD_TO_VNET(curthread)); if (nrefreshes > 0 && AUTH_REFRESH(auth, &reply_msg)) { + CURVNET_RESTORE(); nrefreshes--; XDR_DESTROY(&xdrs); mtx_lock(&cs->cs_lock); goto call_again; } + CURVNET_RESTORE(); + } /* end of unsuccessful completion */ } /* end of valid reply message */ else { diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c index ecd5fdd04f34..e395cd27ccaa 100644 --- a/sys/rpc/clnt_vc.c +++ b/sys/rpc/clnt_vc.c @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -559,15 +560,19 @@ got_reply: * If unsuccessful AND error is an authentication error * then refresh credentials and try again, else break */ - else if (stat == RPC_AUTHERROR) + else if (stat == RPC_AUTHERROR) { /* maybe our credentials need to be refreshed ... */ + CURVNET_SET_QUIET(TD_TO_VNET(curthread)); if (nrefreshes > 0 && AUTH_REFRESH(auth, &reply_msg)) { + CURVNET_RESTORE(); nrefreshes--; XDR_DESTROY(&xdrs); mtx_lock(&ct->ct_lock); goto call_again; } + CURVNET_RESTORE(); + } /* end of unsuccessful completion */ } /* end of valid reply message */ else { diff --git a/sys/rpc/rpcsec_gss/rpcsec_gss.c b/sys/rpc/rpcsec_gss/rpcsec_gss.c index d99e3a3090df..de690bbbd1d1 100644 --- a/sys/rpc/rpcsec_gss/rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/rpcsec_gss.c @@ -150,26 +150,42 @@ static struct timeval AUTH_TIMEOUT = { 25, 0 }; #define RPC_GSS_HASH_SIZE 11 #define RPC_GSS_MAX 256 -static struct rpc_gss_data_list rpc_gss_cache[RPC_GSS_HASH_SIZE]; -static struct rpc_gss_data_list rpc_gss_all; -static struct sx rpc_gss_lock; -static int rpc_gss_count; + +VNET_DEFINE_STATIC(struct rpc_gss_data_list *, rpc_gss_cache); +VNET_DEFINE_STATIC(struct rpc_gss_data_list, rpc_gss_all); +VNET_DEFINE_STATIC(struct sx, rpc_gss_lock); +VNET_DEFINE_STATIC(int, rpc_gss_count); static AUTH *rpc_gss_seccreate_int(CLIENT *, struct ucred *, const char *, const char *, gss_OID, rpc_gss_service_t, u_int, rpc_gss_options_req_t *, rpc_gss_options_ret_t *); static void -rpc_gss_hashinit(void *dummy) +rpc_gss_hashinit(void *dummy __unused) { int i; + VNET(rpc_gss_cache) = mem_alloc(sizeof(struct rpc_gss_data_list) * + RPC_GSS_HASH_SIZE); for (i = 0; i < RPC_GSS_HASH_SIZE; i++) - TAILQ_INIT(&rpc_gss_cache[i]); - TAILQ_INIT(&rpc_gss_all); - sx_init(&rpc_gss_lock, "rpc_gss_lock"); + TAILQ_INIT(&VNET(rpc_gss_cache)[i]); + TAILQ_INIT(&VNET(rpc_gss_all)); + sx_init(&VNET(rpc_gss_lock), "rpc_gss_lock"); } -SYSINIT(rpc_gss_hashinit, SI_SUB_KMEM, SI_ORDER_ANY, rpc_gss_hashinit, NULL); +VNET_SYSINIT(rpc_gss_hashinit, SI_SUB_VNET_DONE, SI_ORDER_ANY, + rpc_gss_hashinit, NULL); + +static void +rpc_gss_hashinit_cleanup(void *dummy __unused) +{ + + rpc_gss_secpurge(NULL); + mem_free(VNET(rpc_gss_cache), sizeof(struct rpc_gss_data_list) * + RPC_GSS_HASH_SIZE); + sx_destroy(&VNET(rpc_gss_lock)); +} +VNET_SYSUNINIT(rpc_gss_hashinit_cleanup, SI_SUB_VNET_DONE, SI_ORDER_ANY, + rpc_gss_hashinit_cleanup, NULL); static uint32_t rpc_gss_hash(const char *principal, gss_OID mech, @@ -198,15 +214,16 @@ rpc_gss_secfind(CLIENT *clnt, struct ucred *cred, const char *principal, struct rpc_gss_data *gd, *tgd; rpc_gss_options_ret_t options; - if (rpc_gss_count > RPC_GSS_MAX) { - while (rpc_gss_count > RPC_GSS_MAX) { - sx_xlock(&rpc_gss_lock); - tgd = TAILQ_FIRST(&rpc_gss_all); + CURVNET_ASSERT_SET(); + if (VNET(rpc_gss_count) > RPC_GSS_MAX) { + while (VNET(rpc_gss_count) > RPC_GSS_MAX) { + sx_xlock(&VNET(rpc_gss_lock)); + tgd = TAILQ_FIRST(&VNET(rpc_gss_all)); th = tgd->gd_hash; - TAILQ_REMOVE(&rpc_gss_cache[th], tgd, gd_link); - TAILQ_REMOVE(&rpc_gss_all, tgd, gd_alllink); - rpc_gss_count--; - sx_xunlock(&rpc_gss_lock); + TAILQ_REMOVE(&VNET(rpc_gss_cache)[th], tgd, gd_link); + TAILQ_REMOVE(&VNET(rpc_gss_all), tgd, gd_alllink); + VNET(rpc_gss_count)--; + sx_xunlock(&VNET(rpc_gss_lock)); AUTH_DESTROY(tgd->gd_auth); } } @@ -217,23 +234,24 @@ rpc_gss_secfind(CLIENT *clnt, struct ucred *cred, const char *principal, h = rpc_gss_hash(principal, mech_oid, cred, service); again: - sx_slock(&rpc_gss_lock); - TAILQ_FOREACH(gd, &rpc_gss_cache[h], gd_link) { + sx_slock(&VNET(rpc_gss_lock)); + TAILQ_FOREACH(gd, &VNET(rpc_gss_cache)[h], gd_link) { if (gd->gd_ucred->cr_uid == cred->cr_uid && !strcmp(gd->gd_principal, principal) && gd->gd_mech == mech_oid && gd->gd_cred.gc_svc == service) { refcount_acquire(&gd->gd_refs); - if (sx_try_upgrade(&rpc_gss_lock)) { + if (sx_try_upgrade(&VNET(rpc_gss_lock))) { /* * Keep rpc_gss_all LRU sorted. */ - TAILQ_REMOVE(&rpc_gss_all, gd, gd_alllink); - TAILQ_INSERT_TAIL(&rpc_gss_all, gd, + TAILQ_REMOVE(&VNET(rpc_gss_all), gd, + gd_alllink); + TAILQ_INSERT_TAIL(&VNET(rpc_gss_all), gd, gd_alllink); - sx_xunlock(&rpc_gss_lock); + sx_xunlock(&VNET(rpc_gss_lock)); } else { - sx_sunlock(&rpc_gss_lock); + sx_sunlock(&VNET(rpc_gss_lock)); } /* @@ -249,7 +267,7 @@ again: return (gd->gd_auth); } } - sx_sunlock(&rpc_gss_lock); + sx_sunlock(&VNET(rpc_gss_lock)); /* * We missed in the cache - create a new association. @@ -262,8 +280,8 @@ again: gd = AUTH_PRIVATE(auth); gd->gd_hash = h; - sx_xlock(&rpc_gss_lock); - TAILQ_FOREACH(tgd, &rpc_gss_cache[h], gd_link) { + sx_xlock(&VNET(rpc_gss_lock)); + TAILQ_FOREACH(tgd, &VNET(rpc_gss_cache)[h], gd_link) { if (tgd->gd_ucred->cr_uid == cred->cr_uid && !strcmp(tgd->gd_principal, principal) && tgd->gd_mech == mech_oid @@ -272,17 +290,17 @@ again: * We lost a race to create the AUTH that * matches this cred. */ - sx_xunlock(&rpc_gss_lock); + sx_xunlock(&VNET(rpc_gss_lock)); AUTH_DESTROY(auth); goto again; } } - rpc_gss_count++; - TAILQ_INSERT_TAIL(&rpc_gss_cache[h], gd, gd_link); - TAILQ_INSERT_TAIL(&rpc_gss_all, gd, gd_alllink); + VNET(rpc_gss_count)++; + TAILQ_INSERT_TAIL(&VNET(rpc_gss_cache)[h], gd, gd_link); + TAILQ_INSERT_TAIL(&VNET(rpc_gss_all), gd, gd_alllink); refcount_acquire(&gd->gd_refs); /* one for the cache, one for user */ - sx_xunlock(&rpc_gss_lock); + sx_xunlock(&VNET(rpc_gss_lock)); return (auth); } @@ -293,14 +311,15 @@ rpc_gss_secpurge(CLIENT *clnt) uint32_t h; struct rpc_gss_data *gd, *tgd; - TAILQ_FOREACH_SAFE(gd, &rpc_gss_all, gd_alllink, tgd) { - if (gd->gd_clnt == clnt) { - sx_xlock(&rpc_gss_lock); + CURVNET_ASSERT_SET(); + TAILQ_FOREACH_SAFE(gd, &VNET(rpc_gss_all), gd_alllink, tgd) { + if (clnt == NULL || gd->gd_clnt == clnt) { + sx_xlock(&VNET(rpc_gss_lock)); h = gd->gd_hash; - TAILQ_REMOVE(&rpc_gss_cache[h], gd, gd_link); - TAILQ_REMOVE(&rpc_gss_all, gd, gd_alllink); - rpc_gss_count--; - sx_xunlock(&rpc_gss_lock); + TAILQ_REMOVE(&VNET(rpc_gss_cache)[h], gd, gd_link); + TAILQ_REMOVE(&VNET(rpc_gss_all), gd, gd_alllink); + VNET(rpc_gss_count)--; + sx_xunlock(&VNET(rpc_gss_lock)); AUTH_DESTROY(gd->gd_auth); } } @@ -748,6 +767,7 @@ rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret) gss_OID_set mechlist; static enum krb_imp my_krb_imp = KRBIMP_UNKNOWN; + CURVNET_ASSERT_SET(); rpc_gss_log_debug("in rpc_gss_refresh()"); gd = AUTH_PRIVATE(auth); @@ -773,17 +793,6 @@ rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret) gd->gd_cred.gc_proc = RPCSEC_GSS_INIT; gd->gd_cred.gc_seq = 0; - /* - * XXX Threads from inside jails can get here via calls - * to clnt_vc_call()->AUTH_REFRESH()->rpc_gss_refresh() - * but the NFS mount is always done outside of the - * jails in vnet0. Since the thread credentials won't - * necessarily have cr_prison == vnet0 and this function - * has no access to the socket, using vnet0 seems the - * only option. This is broken if NFS mounts are enabled - * within vnet prisons. - */ - CURVNET_SET_QUIET(vnet0); /* * For KerberosV, if there is a client principal name, that implies * that this is a host based initiator credential in the default @@ -1030,14 +1039,12 @@ out: gss_delete_sec_context(&min_stat, &gd->gd_ctx, GSS_C_NO_BUFFER); } - CURVNET_RESTORE(); mtx_lock(&gd->gd_lock); gd->gd_state = RPCSEC_GSS_START; wakeup(gd); mtx_unlock(&gd->gd_lock); return (FALSE); } - CURVNET_RESTORE(); mtx_lock(&gd->gd_lock); gd->gd_state = RPCSEC_GSS_ESTABLISHED;