From 1f6a95ec037b22b0b2744fce3dbc191c13bf839e Mon Sep 17 00:00:00 2001 From: hannken Date: Fri, 30 Aug 2013 12:58:22 +0000 Subject: [PATCH] Dounmount() violates the locking protocol for member v_mountedhere. A vnode lock is required to access or modify this field. Lock/unlock the vnode when clearing v_mountedhere. Reviewed by: David Holland Should fix PR #48135 (Bad locking for umount) --- sys/kern/vfs_mount.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index c9b2ec3e05df..90c715199a87 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_mount.c,v 1.19 2013/04/28 21:34:31 mlelstv Exp $ */ +/* $NetBSD: vfs_mount.c,v 1.20 2013/08/30 12:58:22 hannken Exp $ */ /*- * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.19 2013/04/28 21:34:31 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.20 2013/08/30 12:58:22 hannken Exp $"); #include #include @@ -878,9 +878,12 @@ dounmount(struct mount *mp, int flags, struct lwp *l) mp->mnt_iflag |= IMNT_GONE; mutex_exit(&mp->mnt_unmounting); - mutex_enter(&mountlist_lock); - if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) + if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) { + vn_lock(coveredvp, LK_EXCLUSIVE | LK_RETRY); coveredvp->v_mountedhere = NULL; + VOP_UNLOCK(coveredvp); + } + mutex_enter(&mountlist_lock); CIRCLEQ_REMOVE(&mountlist, mp, mnt_list); mutex_exit(&mountlist_lock); if (TAILQ_FIRST(&mp->mnt_vnodelist) != NULL)