svn commit: r191940 - in head/sys: fs/nfs fs/nfsserver kern nfsserver nlm ufs/ufs

Alexander Kabaev kan at FreeBSD.org
Sat May 9 18:09:18 UTC 2009


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;


More information about the svn-src-head mailing list