⬢ DragonFlyBSD Kernel Audit
DF-3242 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/ufs/ufs_vfsops.c
+++ b/sys/vfs/ufs/ufs_vfsops.c
@@ -238,14 +238,22 @@ ufs_check_export(struct mount *mp, struct sockaddr *nam, int *exflagsp,
 	ump = VFSTOUFS(mp);
 	/*
 	 * Get the export permission structure for this <mp, client> tuple.
 	 */
 	np = vfs_export_lookup(mp, &ump->um_export, nam);
 	if (np == NULL)
 		return (EACCES);
 
 	*exflagsp = np->netc_exflags;
-	*credanonp = &np->netc_anon;
+	/*
+	 * The netcred (including the embedded anon credential) can be
+	 * freed by a concurrent export update (mount -u -o -export) as
+	 * soon as NE_LOCK is dropped; hand the caller an owned copy.
+	 * nfsrv_fhtovp() must crfree() it when done.
+	 */
+	*credanonp = crdup(&np->netc_anon);
 	return (0);
 }
--- a/sys/vfs/nfs/nfs_subs.c
+++ b/sys/vfs/nfs/nfs_subs.c
@@ -1274,6 +1274,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int dorestrict, struct mount **mpp,
 		for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++)
 			cred->cr_groups[i] = credanon->cr_groups[i];
 		cred->cr_ngroups = i;
 	}
+	crfree(credanon);