1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-29 12:03:03 +00:00

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.

Tested by:	rlibby
PR:		232673
Reviewed by:	kib
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D17757
This commit is contained in:
Rick Macklem 2018-11-01 15:27:22 +00:00
parent caa0408fa8
commit 881a9516a2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=339999

View File

@ -3033,14 +3033,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);
@ -3119,9 +3124,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);
@ -3144,7 +3146,8 @@ nfs_advlock(struct vop_advlock_args *ap)
NFSVOPUNLOCK(vp, 0);
}
}
}
} else
NFSVOPUNLOCK(vp, 0);
return (error);
}