Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Nov 2018 00:49:08 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r340590 - stable/12/sys/fs/nfsclient
Message-ID:  <201811190049.wAJ0n8TG045259@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Mon Nov 19 00:49:08 2018
New Revision: 340590
URL: https://svnweb.freebsd.org/changeset/base/340590

Log:
  MFC: r339999
  Fix NFS client vnode locking to avoid a crash during forced dismount.
  
  A crash was reported where the crash occurred in nfs_advlock() when the
  NFS_ISV4(vp) macro was being executed. This was caused by the vnode
  being VI_DOOMED due to a forced dismount in progress.
  This patch fixes the problem by locking the vnode before executing the
  NFS_ISV4() macro.
  
  PR:		232673

Modified:
  stable/12/sys/fs/nfsclient/nfs_clvnops.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- stable/12/sys/fs/nfsclient/nfs_clvnops.c	Sun Nov 18 23:48:15 2018	(r340589)
+++ stable/12/sys/fs/nfsclient/nfs_clvnops.c	Mon Nov 19 00:49:08 2018	(r340590)
@@ -3008,14 +3008,19 @@ nfs_advlock(struct vop_advlock_args *ap)
 	int ret, error = EOPNOTSUPP;
 	u_quad_t size;
 	
+	ret = NFSVOPLOCK(vp, LK_SHARED);
+	if (ret != 0)
+		return (EBADF);
 	if (NFS_ISV4(vp) && (ap->a_flags & (F_POSIX | F_FLOCK)) != 0) {
-		if (vp->v_type != VREG)
+		if (vp->v_type != VREG) {
+			NFSVOPUNLOCK(vp, 0);
 			return (EINVAL);
+		}
 		if ((ap->a_flags & F_POSIX) != 0)
 			cred = p->p_ucred;
 		else
 			cred = td->td_ucred;
-		NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
+		NFSVOPLOCK(vp, LK_UPGRADE | LK_RETRY);
 		if (vp->v_iflag & VI_DOOMED) {
 			NFSVOPUNLOCK(vp, 0);
 			return (EBADF);
@@ -3094,9 +3099,6 @@ nfs_advlock(struct vop_advlock_args *ap)
 		NFSVOPUNLOCK(vp, 0);
 		return (0);
 	} else if (!NFS_ISV4(vp)) {
-		error = NFSVOPLOCK(vp, LK_SHARED);
-		if (error)
-			return (error);
 		if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) {
 			size = VTONFS(vp)->n_size;
 			NFSVOPUNLOCK(vp, 0);
@@ -3119,7 +3121,8 @@ nfs_advlock(struct vop_advlock_args *ap)
 				NFSVOPUNLOCK(vp, 0);
 			}
 		}
-	}
+	} else
+		NFSVOPUNLOCK(vp, 0);
 	return (error);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811190049.wAJ0n8TG045259>