Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3-0]: src/sys/miscfs/specfs Pull up following revision(s) (reques...



details:   https://anonhg.NetBSD.org/src/rev/5ee69616121d
branches:  netbsd-3-0
changeset: 579338:5ee69616121d
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sat Nov 11 21:01:52 2006 +0000

description:
Pull up following revision(s) (requested by jld in ticket #1557):
        sys/miscfs/specfs/spec_vnops.c: revision 1.91 via patch
Protect spec_poll from racing against revocation and thus dereferencing a
NULL v_specinfo.  Mostly copied (with understanding) from rev 1.83's fix
to spec_ioctl, and needed for the same reason (kern/vfs_subr.c r1.231).

diffstat:

 sys/miscfs/specfs/spec_vnops.c |  24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

diffs (49 lines):

diff -r 26f525b3b2e6 -r 5ee69616121d sys/miscfs/specfs/spec_vnops.c
--- a/sys/miscfs/specfs/spec_vnops.c    Sat Nov 11 20:49:55 2006 +0000
+++ b/sys/miscfs/specfs/spec_vnops.c    Sat Nov 11 21:01:52 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spec_vnops.c,v 1.80.2.1 2005/09/26 20:22:55 tron Exp $ */
+/*     $NetBSD: spec_vnops.c,v 1.80.2.1.2.1 2006/11/11 21:01:52 bouyer Exp $   */
 
 /*
  * Copyright (c) 1989, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.80.2.1 2005/09/26 20:22:55 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.80.2.1.2.1 2006/11/11 21:01:52 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -518,12 +518,28 @@
                struct proc *a_p;
        } */ *ap = v;
        const struct cdevsw *cdev;
+       struct vnode *vp;
        dev_t dev;
 
-       switch (ap->a_vp->v_type) {
+       /*
+        * Extract all the info we need from the vnode, taking care to
+        * avoid a race with VOP_REVOKE().
+        */
+
+       vp = ap->a_vp;
+       dev = NODEV;
+       simple_lock(&vp->v_interlock);
+       if ((vp->v_flag & VXLOCK) == 0 && vp->v_specinfo) {
+               dev = vp->v_rdev;
+       }
+       simple_unlock(&vp->v_interlock);
+       if (dev == NODEV) {
+               return ENXIO;
+       }
+
+       switch (vp->v_type) {
 
        case VCHR:
-               dev = ap->a_vp->v_rdev;
                cdev = cdevsw_lookup(dev);
                if (cdev == NULL)
                        return (ENXIO);



Home | Main Index | Thread Index | Old Index