Module Name: src
Committed By: hannken
Date: Wed Jul 21 09:06:39 UTC 2010
Modified Files:
src/share/man/man9: vnode.9
src/sys/external/bsd/drm/dist/bsd-core: drm_bufs.c
src/sys/kern: vfs_subr.c
src/sys/miscfs/kernfs: kernfs_subr.c kernfs_vnops.c
src/sys/sys: param.h
Log Message:
Using vfinddev() leads to vnode races as it returns an unreferenced
vnode that may disappear before the caller has a chance to reference it.
Reference the vnode while the specfs cache is locked.
Welcome to 5.99.37.
No objections on tech-kern.
To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/share/man/man9/vnode.9
cvs rdiff -u -r1.7 -r1.8 src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c
cvs rdiff -u -r1.408 -r1.409 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.21 -r1.22 src/sys/miscfs/kernfs/kernfs_subr.c
cvs rdiff -u -r1.142 -r1.143 src/sys/miscfs/kernfs/kernfs_vnops.c
cvs rdiff -u -r1.371 -r1.372 src/sys/sys/param.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man9/vnode.9
diff -u src/share/man/man9/vnode.9:1.49 src/share/man/man9/vnode.9:1.50
--- src/share/man/man9/vnode.9:1.49 Sun Jun 6 08:01:31 2010
+++ src/share/man/man9/vnode.9 Wed Jul 21 09:06:37 2010
@@ -1,4 +1,4 @@
-.\" $NetBSD: vnode.9,v 1.49 2010/06/06 08:01:31 hannken Exp $
+.\" $NetBSD: vnode.9,v 1.50 2010/07/21 09:06:37 hannken Exp $
.\"
.\" Copyright (c) 2001, 2005, 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 6, 2010
+.Dd July 21, 2010
.Dt VNODE 9
.Os
.Sh NAME
@@ -654,7 +654,7 @@
is used for the console and kernfs special devices.
.It Fn vfinddev "dev" "vtype" "vpp"
Lookup a vnode by device number.
-The vnode is returned in the address specified by
+The vnode is referenced and returned in the address specified by
.Fa vpp .
.It Fn vdevgone "int maj" "int min" "int minh" "enum vtype type"
Reclaim all vnodes that correspond to the specified minor number range
Index: src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c
diff -u src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c:1.7 src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c:1.8
--- src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c:1.7 Tue Jan 26 08:01:26 2010
+++ src/sys/external/bsd/drm/dist/bsd-core/drm_bufs.c Wed Jul 21 09:06:38 2010
@@ -1146,6 +1146,9 @@
done:
request->count = dma->buf_count;
+#if defined(__NetBSD__)
+ vrele(vn);
+#endif
DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode);
Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.408 src/sys/kern/vfs_subr.c:1.409
--- src/sys/kern/vfs_subr.c:1.408 Thu Jul 1 13:00:56 2010
+++ src/sys/kern/vfs_subr.c Wed Jul 21 09:06:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_subr.c,v 1.408 2010/07/01 13:00:56 hannken Exp $ */
+/* $NetBSD: vfs_subr.c,v 1.409 2010/07/21 09:06:38 hannken Exp $ */
/*-
* Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.408 2010/07/01 13:00:56 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.409 2010/07/21 09:06:38 hannken Exp $");
#include "opt_ddb.h"
#include "opt_compat_netbsd.h"
@@ -1993,24 +1993,28 @@
}
/*
- * Lookup a vnode by device number.
+ * Lookup a vnode by device number and return it referenced.
*/
int
vfinddev(dev_t dev, enum vtype type, vnode_t **vpp)
{
vnode_t *vp;
- int rc = 0;
mutex_enter(&device_lock);
for (vp = specfs_hash[SPECHASH(dev)]; vp; vp = vp->v_specnext) {
- if (dev != vp->v_rdev || type != vp->v_type)
- continue;
- *vpp = vp;
- rc = 1;
- break;
+ if (dev == vp->v_rdev && type == vp->v_type)
+ break;
}
+ if (vp == NULL) {
+ mutex_exit(&device_lock);
+ return 0;
+ }
+ mutex_enter(&vp->v_interlock);
mutex_exit(&device_lock);
- return (rc);
+ if (vget(vp, LK_INTERLOCK) != 0)
+ return 0;
+ *vpp = vp;
+ return 1;
}
/*
@@ -3366,9 +3370,11 @@
blkdev = devsw_chr2blk(dev);
if (blkdev != NODEV) {
- vfinddev(blkdev, VBLK, &bvp);
- if (bvp != NULL)
+ if (vfinddev(blkdev, VBLK, &bvp) != 0) {
d_type = (cdev->d_flag & D_TYPEMASK);
+ /* XXX: what if bvp disappears? */
+ vrele(bvp);
+ }
}
}
Index: src/sys/miscfs/kernfs/kernfs_subr.c
diff -u src/sys/miscfs/kernfs/kernfs_subr.c:1.21 src/sys/miscfs/kernfs/kernfs_subr.c:1.22
--- src/sys/miscfs/kernfs/kernfs_subr.c:1.21 Thu Jul 1 13:00:56 2010
+++ src/sys/miscfs/kernfs/kernfs_subr.c Wed Jul 21 09:06:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: kernfs_subr.c,v 1.21 2010/07/01 13:00:56 hannken Exp $ */
+/* $NetBSD: kernfs_subr.c,v 1.22 2010/07/21 09:06:38 hannken Exp $ */
/*
* Copyright (c) 1993
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_subr.c,v 1.21 2010/07/01 13:00:56 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kernfs_subr.c,v 1.22 2010/07/21 09:06:38 hannken Exp $");
#ifdef _KERNEL_OPT
#include "opt_ipsec.h"
@@ -176,8 +176,10 @@
return (ENOENT);
}
vp = fvp;
- if (vget(fvp, LK_EXCLUSIVE))
+ if (vn_lock(fvp, LK_EXCLUSIVE)) {
+ vrele(fvp);
goto loop;
+ }
*vpp = vp;
mutex_exit(&kfs_hashlock);
return (0);
Index: src/sys/miscfs/kernfs/kernfs_vnops.c
diff -u src/sys/miscfs/kernfs/kernfs_vnops.c:1.142 src/sys/miscfs/kernfs/kernfs_vnops.c:1.143
--- src/sys/miscfs/kernfs/kernfs_vnops.c:1.142 Thu Jun 24 13:03:16 2010
+++ src/sys/miscfs/kernfs/kernfs_vnops.c Wed Jul 21 09:06:38 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: kernfs_vnops.c,v 1.142 2010/06/24 13:03:16 hannken Exp $ */
+/* $NetBSD: kernfs_vnops.c,v 1.143 2010/07/21 09:06:38 hannken Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.142 2010/06/24 13:03:16 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.143 2010/07/21 09:06:38 hannken Exp $");
#ifdef _KERNEL_OPT
#include "opt_ipsec.h"
@@ -1168,6 +1168,7 @@
if (*dp == NODEV ||
!vfinddev(*dp, kt->kt_vtype, &fvp))
continue;
+ vrele(fvp);
}
if (kt->kt_tag == KFSmsgbuf) {
if (!msgbufenabled
@@ -1250,6 +1251,7 @@
if (*dp == NODEV ||
!vfinddev(*dp, kt->kt_vtype, &fvp))
continue;
+ vrele(fvp);
}
d.d_namlen = kt->kt_namlen;
if ((error = kernfs_setdirentfileno(&d, i, kfs,
Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.371 src/sys/sys/param.h:1.372
--- src/sys/sys/param.h:1.371 Thu Jul 8 12:23:31 2010
+++ src/sys/sys/param.h Wed Jul 21 09:06:37 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.371 2010/07/08 12:23:31 rmind Exp $ */
+/* $NetBSD: param.h,v 1.372 2010/07/21 09:06:37 hannken Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@@ -63,7 +63,7 @@
* 2.99.9 (299000900)
*/
-#define __NetBSD_Version__ 599003600 /* NetBSD 5.99.36 */
+#define __NetBSD_Version__ 599003700 /* NetBSD 5.99.37 */
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)