Manage the ucred for the NFS server using the crget/crfree API defined in
kern_prot.c. This API handles reference counting among many other things. Notably, if MAC is compiled into the kernel, it will properly initialize the MAC labels when the ucred is allocated. This work is in preparation for a new MAC entry point which will be responsible for properly initializing policy specific labels for the NFS server credential. Utilization of the crfree/crget APIs reduce the complexity associated with this label's management. Submitted by: green (with changes) [1] Obtained from: TrustedBSD Project Discussed with: rwatson, alfred [1] I moved the ucred allocation outside the scope of the NFS server lock to prevent M_WAIKOK allocations from occurring with non-sleep-able locks held. Additionally, to reduce complexity, the ucred persist as long as the NFS server descriptor.
This commit is contained in:
parent
05157fa0a1
commit
7a3e891951
@ -258,7 +258,7 @@ struct nfsrv_descript {
|
||||
u_int32_t nd_retxid; /* Reply xid */
|
||||
struct timeval nd_starttime; /* Time RPC initiated */
|
||||
fhandle_t nd_fh; /* File handle */
|
||||
struct ucred nd_cr; /* Credentials */
|
||||
struct ucred *nd_cr; /* Credentials */
|
||||
};
|
||||
|
||||
/* Bits for "nd_flag" */
|
||||
|
@ -170,7 +170,7 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct vnode *vp = NULL;
|
||||
nfsfh_t nfh;
|
||||
fhandle_t *fhp;
|
||||
@ -249,7 +249,7 @@ nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct nfs_fattr *fp;
|
||||
struct vattr va;
|
||||
struct vattr *vap = &va;
|
||||
@ -310,7 +310,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct vattr va, preat;
|
||||
struct vattr *vap = &va;
|
||||
struct nfsv2_sattr *sp;
|
||||
@ -488,7 +488,7 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct nfs_fattr *fp;
|
||||
struct nameidata nd, ind, *ndp = &nd;
|
||||
struct vnode *vp, *dirp = NULL;
|
||||
@ -686,7 +686,7 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN];
|
||||
struct iovec *ivp = iv;
|
||||
struct mbuf *mp;
|
||||
@ -803,7 +803,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct iovec *iv;
|
||||
struct iovec *iv2;
|
||||
struct mbuf *m;
|
||||
@ -1073,7 +1073,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct iovec *ivp;
|
||||
int i, cnt;
|
||||
struct mbuf *mp;
|
||||
@ -1366,7 +1366,7 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp,
|
||||
mrep = nfsd->nd_mrep;
|
||||
md = nfsd->nd_md;
|
||||
dpos = nfsd->nd_dpos;
|
||||
cred = &nfsd->nd_cr;
|
||||
cred = nfsd->nd_cr;
|
||||
v3 = (nfsd->nd_flag & ND_NFSV3);
|
||||
LIST_INIT(&nfsd->nd_coalesce);
|
||||
nfsd->nd_mreq = NULL;
|
||||
@ -1473,7 +1473,7 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp,
|
||||
*/
|
||||
for(; nfsd && NFSW_CONTIG(owp, nfsd); nfsd = wp) {
|
||||
wp = LIST_NEXT(nfsd, nd_hash);
|
||||
if (nfsrv_samecred(&owp->nd_cr, &nfsd->nd_cr))
|
||||
if (nfsrv_samecred(owp->nd_cr, nfsd->nd_cr))
|
||||
nfsrvw_coalesce(owp, nfsd);
|
||||
}
|
||||
} else {
|
||||
@ -1502,7 +1502,7 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp,
|
||||
splx(s);
|
||||
mrep = nfsd->nd_mrep;
|
||||
nfsd->nd_mrep = NULL;
|
||||
cred = &nfsd->nd_cr;
|
||||
cred = nfsd->nd_cr;
|
||||
v3 = (nfsd->nd_flag & ND_NFSV3);
|
||||
forat_ret = aftat_ret = 1;
|
||||
error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, cred, slp,
|
||||
@ -1727,7 +1727,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct nfs_fattr *fp;
|
||||
struct vattr va, dirfor, diraft;
|
||||
struct vattr *vap = &va;
|
||||
@ -2035,7 +2035,7 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct vattr va, dirfor, diraft;
|
||||
struct vattr *vap = &va;
|
||||
u_int32_t *tl;
|
||||
@ -2243,7 +2243,7 @@ nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct nameidata nd;
|
||||
caddr_t bpos;
|
||||
int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
|
||||
@ -2364,7 +2364,7 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
caddr_t bpos;
|
||||
int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
|
||||
int tdirfor_ret = 1, tdiraft_ret = 1;
|
||||
@ -2620,7 +2620,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct nameidata nd;
|
||||
caddr_t bpos;
|
||||
int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
|
||||
@ -2779,7 +2779,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct vattr va, dirfor, diraft;
|
||||
struct nameidata nd;
|
||||
struct vattr *vap = &va;
|
||||
@ -2969,7 +2969,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct vattr va, dirfor, diraft;
|
||||
struct vattr *vap = &va;
|
||||
struct nfs_fattr *fp;
|
||||
@ -3148,7 +3148,7 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
caddr_t bpos;
|
||||
int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
|
||||
int v3 = (nfsd->nd_flag & ND_NFSV3);
|
||||
@ -3321,7 +3321,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
char *bp, *be;
|
||||
struct mbuf *mp;
|
||||
struct dirent *dp;
|
||||
@ -3639,7 +3639,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
char *bp, *be;
|
||||
struct mbuf *mp;
|
||||
struct dirent *dp;
|
||||
@ -4007,7 +4007,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct vattr bfor, aft;
|
||||
struct vnode *vp = NULL;
|
||||
nfsfh_t nfh;
|
||||
@ -4179,7 +4179,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct statfs *sf;
|
||||
struct nfs_statfs *sfp;
|
||||
caddr_t bpos;
|
||||
@ -4281,7 +4281,7 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct nfsv3_fsinfo *sip;
|
||||
caddr_t bpos;
|
||||
int error = 0, rdonly, getret = 1, pref;
|
||||
@ -4368,7 +4368,7 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
|
||||
struct sockaddr *nam = nfsd->nd_nam;
|
||||
caddr_t dpos = nfsd->nd_dpos;
|
||||
struct ucred *cred = &nfsd->nd_cr;
|
||||
struct ucred *cred = nfsd->nd_cr;
|
||||
struct nfsv3_pathconf *pc;
|
||||
caddr_t bpos;
|
||||
int error = 0, rdonly, getret = 1;
|
||||
|
@ -39,10 +39,13 @@ __FBSDID("$FreeBSD$");
|
||||
* Socket operations for use by nfs
|
||||
*/
|
||||
|
||||
#include "opt_mac.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mac.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mount.h>
|
||||
@ -362,16 +365,10 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
|
||||
}
|
||||
nfsm_adv(nfsm_rndup(len));
|
||||
tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED);
|
||||
/*
|
||||
* XXX: This credential should be managed using crget(9)
|
||||
* and related calls. Right now, this tramples on any
|
||||
* extensible data in the ucred, and worse. This wasn't
|
||||
* fixed before FreeBSD 5.3-RELEASE.
|
||||
*/
|
||||
bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
|
||||
refcount_init(&nd->nd_cr.cr_ref, 1);
|
||||
nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
|
||||
nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
|
||||
nd->nd_cr->cr_uid = nd->nd_cr->cr_ruid =
|
||||
nd->nd_cr->cr_svuid = fxdr_unsigned(uid_t, *tl++);
|
||||
nd->nd_cr->cr_groups[0] = nd->nd_cr->cr_rgid =
|
||||
nd->nd_cr->cr_svgid = fxdr_unsigned(gid_t, *tl++);
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
if (len < 0 || len > RPCAUTH_UNIXGIDS) {
|
||||
m_freem(mrep);
|
||||
@ -380,12 +377,12 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
|
||||
tl = nfsm_dissect_nonblock(u_int32_t *, (len + 2) * NFSX_UNSIGNED);
|
||||
for (i = 1; i <= len; i++)
|
||||
if (i < NGROUPS)
|
||||
nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
|
||||
nd->nd_cr->cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
|
||||
else
|
||||
tl++;
|
||||
nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
|
||||
if (nd->nd_cr.cr_ngroups > 1)
|
||||
nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
|
||||
nd->nd_cr->cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
|
||||
if (nd->nd_cr->cr_ngroups > 1)
|
||||
nfsrvw_sort(nd->nd_cr->cr_groups, nd->nd_cr->cr_ngroups);
|
||||
len = fxdr_unsigned(int, *++tl);
|
||||
if (len < 0 || len > RPCAUTH_MAXSIZ) {
|
||||
m_freem(mrep);
|
||||
@ -709,6 +706,7 @@ nfsrv_dorec(struct nfssvc_sock *slp, struct nfsd *nfsd,
|
||||
NFSD_UNLOCK();
|
||||
MALLOC(nd, struct nfsrv_descript *, sizeof (struct nfsrv_descript),
|
||||
M_NFSRVDESC, M_WAITOK);
|
||||
nd->nd_cr = crget();
|
||||
NFSD_LOCK();
|
||||
nd->nd_md = nd->nd_mrep = m;
|
||||
nd->nd_nam2 = nam;
|
||||
@ -718,6 +716,8 @@ nfsrv_dorec(struct nfssvc_sock *slp, struct nfsd *nfsd,
|
||||
if (nam) {
|
||||
FREE(nam, M_SONAME);
|
||||
}
|
||||
if (nd->nd_cr != NULL)
|
||||
crfree(nd->nd_cr);
|
||||
free((caddr_t)nd, M_NFSRVDESC);
|
||||
return (error);
|
||||
}
|
||||
|
@ -390,6 +390,8 @@ nfssvc_nfsd(struct thread *td)
|
||||
}
|
||||
if (error || (slp->ns_flag & SLP_VALID) == 0) {
|
||||
if (nd) {
|
||||
if (nd->nd_cr != NULL)
|
||||
crfree(nd->nd_cr);
|
||||
free((caddr_t)nd, M_NFSRVDESC);
|
||||
nd = NULL;
|
||||
}
|
||||
@ -522,6 +524,8 @@ nfssvc_nfsd(struct thread *td)
|
||||
if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED)
|
||||
nfs_slpunlock(slp);
|
||||
if (error == EINTR || error == ERESTART) {
|
||||
if (nd->nd_cr != NULL)
|
||||
crfree(nd->nd_cr);
|
||||
free((caddr_t)nd, M_NFSRVDESC);
|
||||
nfsrv_slpderef(slp);
|
||||
s = splnet();
|
||||
@ -535,6 +539,8 @@ nfssvc_nfsd(struct thread *td)
|
||||
break;
|
||||
};
|
||||
if (nd) {
|
||||
if (nd->nd_cr != NULL)
|
||||
crfree(nd->nd_cr);
|
||||
FREE((caddr_t)nd, M_NFSRVDESC);
|
||||
nd = NULL;
|
||||
}
|
||||
@ -630,6 +636,8 @@ nfsrv_zapsock(struct nfssvc_sock *slp)
|
||||
for (nwp = LIST_FIRST(&slp->ns_tq); nwp; nwp = nnwp) {
|
||||
nnwp = LIST_NEXT(nwp, nd_tq);
|
||||
LIST_REMOVE(nwp, nd_tq);
|
||||
if (nwp->nd_cr != NULL)
|
||||
crfree(nwp->nd_cr);
|
||||
free((caddr_t)nwp, M_NFSRVDESC);
|
||||
}
|
||||
LIST_INIT(&slp->ns_tq);
|
||||
|
Loading…
Reference in New Issue
Block a user