svn commit: r348052 - head/sys/kern

Konstantin Belousov kib at FreeBSD.org
Tue May 21 15:12:14 UTC 2019


Author: kib
Date: Tue May 21 15:12:13 2019
New Revision: 348052
URL: https://svnweb.freebsd.org/changeset/base/348052

Log:
  NDFREE(): Fix unlocking for LOCKPARENT|LOCKLEAF and ndp->ni_dvp == ndp->ni_vp.
  
  NDFREE() calculates unlock_dvp after ndp->ni_vp is unlocked and zeroed
  out. This makes the comparision of ni_dvp with ni_vp always fail.
  Move the calculation of unlock_dvp right after unlock_vp, so that the
  code sees correct ni_vp value.
  
  Reproduced by
  	   chdir("/usr");
  	   open("/..", O_BENEATH | O_RDONLY);
  
  Reported by:	syzkaller
  Reviewed by:	markj, mckusick
  Tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D20304

Modified:
  head/sys/kern/vfs_lookup.c

Modified: head/sys/kern/vfs_lookup.c
==============================================================================
--- head/sys/kern/vfs_lookup.c	Tue May 21 13:29:53 2019	(r348051)
+++ head/sys/kern/vfs_lookup.c	Tue May 21 15:12:13 2019	(r348052)
@@ -1332,6 +1332,10 @@ NDFREE(struct nameidata *ndp, const u_int flags)
 	if (!(flags & NDF_NO_VP_UNLOCK) &&
 	    (ndp->ni_cnd.cn_flags & LOCKLEAF) && ndp->ni_vp)
 		unlock_vp = 1;
+	if (!(flags & NDF_NO_DVP_UNLOCK) &&
+	    (ndp->ni_cnd.cn_flags & LOCKPARENT) &&
+	    ndp->ni_dvp != ndp->ni_vp)
+		unlock_dvp = 1;
 	if (!(flags & NDF_NO_VP_RELE) && ndp->ni_vp) {
 		if (unlock_vp) {
 			vput(ndp->ni_vp);
@@ -1342,10 +1346,6 @@ NDFREE(struct nameidata *ndp, const u_int flags)
 	}
 	if (unlock_vp)
 		VOP_UNLOCK(ndp->ni_vp, 0);
-	if (!(flags & NDF_NO_DVP_UNLOCK) &&
-	    (ndp->ni_cnd.cn_flags & LOCKPARENT) &&
-	    ndp->ni_dvp != ndp->ni_vp)
-		unlock_dvp = 1;
 	if (!(flags & NDF_NO_DVP_RELE) &&
 	    (ndp->ni_cnd.cn_flags & (LOCKPARENT|WANTPARENT))) {
 		if (unlock_dvp) {


More information about the svn-src-all mailing list