Date: Sat, 9 May 2009 18:09:17 +0000 (UTC) From: Alexander Kabaev <kan@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r191940 - in head/sys: fs/nfs fs/nfsserver kern nfsserver nlm ufs/ufs Message-ID: <200905091809.n49I9HPg030473@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kan Date: Sat May 9 18:09:17 2009 New Revision: 191940 URL: http://svn.freebsd.org/changeset/base/191940 Log: Do not embed struct ucred into larger netcred parent structures. Credential might need to hang around longer than its parent and be used outside of mnt_explock scope controlling netcred lifetime. Use separate reference-counted ucred allocated separately instead. While there, extend mnt_explock coverage in vfs_stdexpcheck and clean-up some unused declarations in new NFS code. Reported by: John Hickey PR: kern/133439 Reviewed by: dfr, kib Modified: head/sys/fs/nfs/nfsport.h head/sys/fs/nfsserver/nfs_nfsdport.c head/sys/fs/nfsserver/nfs_nfsdsocket.c head/sys/kern/vfs_export.c head/sys/nfsserver/nfs_srvsubs.c head/sys/nlm/nlm_prot_impl.c head/sys/ufs/ufs/ufs_extern.h Modified: head/sys/fs/nfs/nfsport.h ============================================================================== --- head/sys/fs/nfs/nfsport.h Sat May 9 17:47:42 2009 (r191939) +++ head/sys/fs/nfs/nfsport.h Sat May 9 18:09:17 2009 (r191940) @@ -446,16 +446,6 @@ int nfsmsleep(void *, void *, int, const #define VT_NFSV4ROOT "nfsv4root" /* - * XXX - not in any system .h file, just vfs_export.c - * Network address lookup element - */ -struct netcred { - struct radix_node netc_rnodes[2]; - int netc_exflags; - struct ucred netc_anon; -}; - -/* * Define whatever it takes to do a vn_rdwr(). */ #define NFSD_RDWR(r, v, b, l, o, s, i, c, a, p) \ Modified: head/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- head/sys/fs/nfsserver/nfs_nfsdport.c Sat May 9 17:47:42 2009 (r191939) +++ head/sys/fs/nfsserver/nfs_nfsdport.c Sat May 9 18:09:17 2009 (r191940) @@ -2565,6 +2565,8 @@ nfsd_fhtovp(struct nfsrv_descript *nd, s if (nd->nd_repstat) vput(*vpp); } + if (credanon != NULL) + crfree(credanon); if (nd->nd_repstat) { if (startwrite) vn_finished_write(mp); @@ -2598,16 +2600,6 @@ fp_getfvp(struct thread *p, int fd, stru } /* - * Network export information - */ -struct netexport { - struct netcred ne_defexported; /* Default export */ - struct radix_node_head *ne_rtable[AF_MAX+1]; /* Individual exports */ -}; - -struct netexport nfsv4root_export; - -/* * Called from newnfssvc() to update the exports list. Just call * vfs_export(). This has to be done, since the v4 root fake fs isn't * in the mount list. @@ -2861,6 +2853,8 @@ nfsvno_v4rootexport(struct nfsrv_descrip return (NFSERR_PROGUNAVAIL); if ((exflags & MNT_EXGSSONLY)) nd->nd_flag |= ND_EXGSSONLY; + if (credanon != NULL) + crfree(credanon); return (0); } Modified: head/sys/fs/nfsserver/nfs_nfsdsocket.c ============================================================================== --- head/sys/fs/nfsserver/nfs_nfsdsocket.c Sat May 9 17:47:42 2009 (r191939) +++ head/sys/fs/nfsserver/nfs_nfsdsocket.c Sat May 9 18:09:17 2009 (r191940) @@ -870,6 +870,8 @@ nfsrvd_compound(struct nfsrv_descript *n if (!nd->nd_repstat) nd->nd_repstat = nfsd_excred(nd, &nes, credanon); + if (credanon != NULL) + crfree(credanon); if (!nd->nd_repstat) { if (vpnes.nes_vfslocked) nfsvno_unlockvfs(mp); Modified: head/sys/kern/vfs_export.c ============================================================================== --- head/sys/kern/vfs_export.c Sat May 9 17:47:42 2009 (r191939) +++ head/sys/kern/vfs_export.c Sat May 9 18:09:17 2009 (r191940) @@ -68,7 +68,7 @@ static struct netcred *vfs_export_lookup struct netcred { struct radix_node netc_rnodes[2]; int netc_exflags; - struct ucred netc_anon; + struct ucred *netc_anon; int netc_numsecflavors; int netc_secflavors[MAXSECFLAVORS]; }; @@ -83,7 +83,7 @@ struct netexport { /* * Build hash lists of net addresses and hang them off the mount point. - * Called by ufs_mount() to set up the lists of export addresses. + * Called by vfs_export() to set up the lists of export addresses. */ static int vfs_hang_addrlist(struct mount *mp, struct netexport *nep, @@ -118,15 +118,14 @@ vfs_hang_addrlist(struct mount *mp, stru } np = &nep->ne_defexported; np->netc_exflags = argp->ex_flags; - bzero(&np->netc_anon, sizeof(np->netc_anon)); - np->netc_anon.cr_uid = argp->ex_anon.cr_uid; - np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups; - bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups, - sizeof(np->netc_anon.cr_groups)); + np->netc_anon = crget(); + np->netc_anon->cr_uid = argp->ex_anon.cr_uid; + np->netc_anon->cr_ngroups = argp->ex_anon.cr_ngroups; + bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups, + sizeof(np->netc_anon->cr_groups)); np->netc_numsecflavors = argp->ex_numsecflavors; bcopy(argp->ex_secflavors, np->netc_secflavors, sizeof(np->netc_secflavors)); - refcount_init(&np->netc_anon.cr_ref, 1); MNT_ILOCK(mp); mp->mnt_flag |= MNT_DEFEXPORTED; MNT_IUNLOCK(mp); @@ -204,15 +203,14 @@ vfs_hang_addrlist(struct mount *mp, stru goto out; } np->netc_exflags = argp->ex_flags; - bzero(&np->netc_anon, sizeof(np->netc_anon)); - np->netc_anon.cr_uid = argp->ex_anon.cr_uid; - np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups; - bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups, - sizeof(np->netc_anon.cr_groups)); + np->netc_anon = crget(); + np->netc_anon->cr_uid = argp->ex_anon.cr_uid; + np->netc_anon->cr_ngroups = argp->ex_anon.cr_ngroups; + bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups, + sizeof(np->netc_anon->cr_groups)); np->netc_numsecflavors = argp->ex_numsecflavors; bcopy(argp->ex_secflavors, np->netc_secflavors, sizeof(np->netc_secflavors)); - refcount_init(&np->netc_anon.cr_ref, 1); return (0); out: free(np, M_NETADDR); @@ -267,9 +265,9 @@ vfs_export(struct mount *mp, struct expo || argp->ex_numsecflavors >= MAXSECFLAVORS) return (EINVAL); - nep = mp->mnt_export; error = 0; lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL); + nep = mp->mnt_export; if (argp->ex_flags & MNT_DELEXPORT) { if (nep == NULL) { error = ENOENT; @@ -375,8 +373,9 @@ vfs_setpublicfs(struct mount *mp, struct * If an indexfile was specified, pull it in. */ if (argp->ex_indexfile != NULL) { - nfs_pub.np_index = malloc(MAXNAMLEN + 1, M_TEMP, - M_WAITOK); + if (nfs_pub.np_index != NULL) + nfs_pub.np_index = malloc(MAXNAMLEN + 1, M_TEMP, + M_WAITOK); error = copyinstr(argp->ex_indexfile, nfs_pub.np_index, MAXNAMLEN, (size_t *)0); if (!error) { @@ -392,6 +391,7 @@ vfs_setpublicfs(struct mount *mp, struct } if (error) { free(nfs_pub.np_index, M_TEMP); + nfs_pub.np_index = NULL; return (error); } } @@ -461,15 +461,19 @@ vfs_stdcheckexp(struct mount *mp, struct lockmgr(&mp->mnt_explock, LK_SHARED, NULL); np = vfs_export_lookup(mp, nam); - lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); - if (np == NULL) + if (np == NULL) { + lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); + *credanonp = NULL; return (EACCES); + } *extflagsp = np->netc_exflags; - *credanonp = &np->netc_anon; + if ((*credanonp = np->netc_anon) != NULL) + crhold(*credanonp); if (numsecflavors) *numsecflavors = np->netc_numsecflavors; if (secflavors) *secflavors = np->netc_secflavors; + lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); return (0); } Modified: head/sys/nfsserver/nfs_srvsubs.c ============================================================================== --- head/sys/nfsserver/nfs_srvsubs.c Sat May 9 17:47:42 2009 (r191939) +++ head/sys/nfsserver/nfs_srvsubs.c Sat May 9 18:09:17 2009 (r191940) @@ -1193,6 +1193,9 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockfla if (!lockflag) VOP_UNLOCK(*vpp, 0); out: + if (credanon != NULL) + crfree(credanon); + if (error) { VFS_UNLOCK_GIANT(vfslocked); } else Modified: head/sys/nlm/nlm_prot_impl.c ============================================================================== --- head/sys/nlm/nlm_prot_impl.c Sat May 9 17:47:42 2009 (r191939) +++ head/sys/nlm/nlm_prot_impl.c Sat May 9 18:09:17 2009 (r191940) @@ -1752,7 +1752,8 @@ nlm_get_vfs_state(struct nlm_host *host, } if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { crfree(cred); - cred = crhold(credanon); + cred = credanon; + credanon = NULL; } /* @@ -1772,6 +1773,8 @@ nlm_get_vfs_state(struct nlm_host *host, out: if (cred) crfree(cred); + if (credanon) + crfree(credanon); return (error); } Modified: head/sys/ufs/ufs/ufs_extern.h ============================================================================== --- head/sys/ufs/ufs/ufs_extern.h Sat May 9 17:47:42 2009 (r191939) +++ head/sys/ufs/ufs/ufs_extern.h Sat May 9 18:09:17 2009 (r191940) @@ -38,7 +38,6 @@ struct direct; struct indir; struct inode; struct mount; -struct netcred; struct thread; struct sockaddr; struct ucred;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905091809.n49I9HPg030473>