From suiram@port294.megapop.eunet.no  Fri Oct  6 21:34:29 2000
Return-Path: <suiram@port294.megapop.eunet.no>
Received: from port294.megapop.eunet.no (port294.megapop.eunet.no [193.91.253.44])
	by hub.freebsd.org (Postfix) with ESMTP id 7427537B502
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  6 Oct 2000 21:34:27 -0700 (PDT)
Received: (from suiram@localhost)
	by suiram.freebsd.org (8.9.3/8.9.3) id EAA23676;
	Sat, 7 Oct 2000 04:16:33 +0200 (CEST)
	(envelope-from suiram)
Message-Id: <200010070216.EAA23676@suiram.freebsd.org>
Date: Sat, 7 Oct 2000 04:16:33 +0200 (CEST)
From: mbendiks@eunet.no
Sender: suiram@port294.megapop.eunet.no
Reply-To: mbendiks@eunet.no
To: FreeBSD-gnats-submit@freebsd.org
Subject: [patches] OpenBSD errata 008 still applies to FreeBSD
X-Send-Pr-Version: 3.2

>Number:         21808
>Category:       kern
>Synopsis:       [msdosfs] [patch] msdosfs incorrectly handles vnode locking
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bde
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Oct 06 21:40:01 PDT 2000
>Closed-Date:    Sat Mar 08 18:23:37 UTC 2008
>Last-Modified:  Sat Mar 08 18:23:37 UTC 2008
>Originator:     Marius Bendiksen
>Release:        FreeBSD 4.1-RELEASE i386
>Organization:
n/a
>Environment:

	not relevant.

>Description:

	In a number of functions, msdosfs incorrectly attempts to use vnodes
	that have previously been released. This could cause problems, given
	MP systems, for example. This is a straight import of errata 008 for
	OpenBSD 2.7.

>How-To-Repeat:

	not known.

>Fix:

	In /sys/msdosfs; diff -u4 patches follow:

--- msdosfs_vnops.c.orig	Tue Aug 29 16:45:48 2000
+++ msdosfs_vnops.c	Sun Sep 24 14:02:42 2000
@@ -1056,9 +1056,9 @@
 	if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster)
 		newparent = 1;
 	if (doingdirectory && newparent) {
 		if (error)	/* write access check above */
-			goto bad;
+			goto bad1;
 		if (xp != NULL)
 			vput(tvp);
 		/*
 		 * doscheckpath() vput()'s dp,
@@ -1084,22 +1084,22 @@
 		 */
 		if (xp->de_Attributes & ATTR_DIRECTORY) {
 			if (!dosdirempty(xp)) {
 				error = ENOTEMPTY;
-				goto bad;
+				goto bad1;
 			}
 			if (!doingdirectory) {
 				error = ENOTDIR;
-				goto bad;
+				goto bad1;
 			}
 			cache_purge(tdvp);
 		} else if (doingdirectory) {
 			error = EISDIR;
-			goto bad;
+			goto bad1;
 		}
 		error = removede(dp, xp);
 		if (error)
-			goto bad;
+			goto bad1;
 		vput(tvp);
 		xp = NULL;
 	}
 
@@ -1109,9 +1109,9 @@
 	 * file/directory.
 	 */
 	error = uniqdosname(VTODE(tdvp), tcnp, toname);
 	if (error)
-		goto abortit;
+		goto bad1;
 
 	/*
 	 * Since from wasn't locked at various places above,
 	 * have to do a relookup here.
@@ -1151,9 +1151,8 @@
 	if (xp != ip) {
 		if (doingdirectory)
 			panic("rename: lost dir entry");
 		vrele(ap->a_fvp);
-		VOP_UNLOCK(fvp, 0, p);
 		if (newparent)
 			VOP_UNLOCK(fdvp, 0, p);
 		xp = NULL;
 	} else {
@@ -1176,9 +1175,8 @@
 		if (error) {
 			bcopy(oldname, ip->de_Name, 11);
 			if (newparent)
 				VOP_UNLOCK(fdvp, 0, p);
-			VOP_UNLOCK(fvp, 0, p);
 			goto bad;
 		}
 		ip->de_refcnt++;
 		zp->de_fndoffset = from_diroffset;
@@ -1186,9 +1184,8 @@
 		if (error) {
 			/* XXX should really panic here, fs is corrupt */
 			if (newparent)
 				VOP_UNLOCK(fdvp, 0, p);
-			VOP_UNLOCK(fvp, 0, p);
 			goto bad;
 		}
 		if (!doingdirectory) {
 			error = pcbmap(dp, de_cluster(pmp, to_diroffset), 0,
@@ -1196,9 +1193,8 @@
 			if (error) {
 				/* XXX should really panic here, fs is corrupt */
 				if (newparent)
 					VOP_UNLOCK(fdvp, 0, p);
-				VOP_UNLOCK(fvp, 0, p);
 				goto bad;
 			}
 			if (ip->de_dirclust == MSDOSFSROOT)
 				ip->de_diroffset = to_diroffset;
@@ -1225,9 +1221,8 @@
 			      NOCRED, &bp);
 		if (error) {
 			/* XXX should really panic here, fs is corrupt */
 			brelse(bp);
-			VOP_UNLOCK(fvp, 0, p);
 			goto bad;
 		}
 		dotdotp = (struct direntry *)bp->b_data + 1;
 		putushort(dotdotp->deStartCluster, dp->de_StartCluster);
@@ -1235,21 +1230,21 @@
 			putushort(dotdotp->deHighClust, dp->de_StartCluster >> 16);
 		error = bwrite(bp);
 		if (error) {
 			/* XXX should really panic here, fs is corrupt */
-			VOP_UNLOCK(fvp, 0, p);
 			goto bad;
 		}
 	}
 
-	VOP_UNLOCK(fvp, 0, p);
 bad:
+	VOP_UNLOCK(fvp, 0, p);
+	vrele(fdvp);
+bad1:
 	if (xp)
 		vput(tvp);
 	vput(tdvp);
 out:
 	ip->de_flag &= ~DE_RENAME;
-	vrele(fdvp);
 	vrele(fvp);
 	return (error);
 
 }

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->analyzed 
State-Changed-By: bp 
State-Changed-When: Sun Oct 22 07:37:48 PDT 2000 
State-Changed-Why:  
I'm unsure if this patch is correct: 

it just gathers VOP_UNLOCK(fvp) invocations into one. 
it introduces a bug by not releasing fdvp vnode when it is necessary. 
de_flags field still not protected by the lock (should it be ?). 


http://www.freebsd.org/cgi/query-pr.cgi?pr=21808 
Responsible-Changed-From-To: freebsd-bugs->trhodes 
Responsible-Changed-By: remko 
Responsible-Changed-When: Fri Dec 29 20:39:45 UTC 2006 
Responsible-Changed-Why:  
assign to tom, he cares about msdosfs 

http://www.freebsd.org/cgi/query-pr.cgi?pr=21808 
Responsible-Changed-From-To: trhodes->bde 
Responsible-Changed-By: kmacy 
Responsible-Changed-When: Fri Nov 16 02:40:33 UTC 2007 
Responsible-Changed-Why:  

bde is the current msdosfs stuckee. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=21808 
State-Changed-From-To: analyzed->closed 
State-Changed-By: rwatson 
State-Changed-When: Sat Mar 8 18:21:42 UTC 2008 
State-Changed-Why:  
A casual inspection of a recent FreeBSD msdosfs_vnops.c suggests 
that these changes generally don't (no longer?) apply to the 
FreeBSD code.  Thanks for the submission, however, and apologies 
for the very long time it's taken to look at it (quite possibly 
these issues were fixed in the intermediate time independently). 


http://www.freebsd.org/cgi/query-pr.cgi?pr=21808 
>Unformatted:
BDE has been most active here. I'm inclined to believe that it has been fixed in the meantime.
