kernel - Fix NULL pointer dereference on forced unmount
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 29 Mar 2010 20:52:11 +0000 (13:52 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 29 Mar 2010 20:52:11 +0000 (13:52 -0700)
* Forced unmounts forcefully remove vnodes from a mount but failed
  to reassociate those vnodes with a dummy mount.  Reassociate the
  vnodes with a dummy mount to avoid a NULL pointer dereference.

Reported-by: Saifi Khan <saifi.khan@datasynergy.org>
sys/kern/vfs_mount.c

index 3e1dd00..ffaf7b5 100644 (file)
@@ -1254,24 +1254,16 @@ vflush_scan(struct mount *mp, struct vnode *vp, void *data)
        }
 
        /*
-        * If FORCECLOSE is set, forcibly close the vnode. For block
-        * or character devices we just clean and leave the vp
-        * associated with devfs.  For all other files, just kill them.
-        *
-        * XXX we need to do something about devfs here, I'd rather not
-        *     blow away device associations.
+        * If FORCECLOSE is set, forcibly destroy the vnode and then move
+        * it to a dummymount structure so vop_*() functions don't deref
+        * a NULL pointer.
         */
        if (info->flags & FORCECLOSE) {
+               vhold(vp);
                vgone_vxlocked(vp);
-#if 0
-               if (vp->v_type != VBLK && vp->v_type != VCHR) {
-                       vgone_vxlocked(vp);
-               } else {
-                       vclean_vxlocked(vp, 0);
-                       /*vp->v_ops = &devfs_vnode_dev_vops_p;*/
-                       insmntque(vp, NULL);
-               }
-#endif
+               if (vp->v_mount == NULL)
+                       insmntque(vp, &dummymount);
+               vdrop(vp);
                return(0);
        }
 #ifdef DIAGNOSTIC