From nobody@FreeBSD.org  Sat Mar 24 03:52:25 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 8798237B718
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 24 Mar 2001 03:52:24 -0800 (PST)
	(envelope-from nobody@FreeBSD.org)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.1/8.11.1) id f2OBqOh33828;
	Sat, 24 Mar 2001 03:52:24 -0800 (PST)
	(envelope-from nobody)
Message-Id: <200103241152.f2OBqOh33828@freefall.freebsd.org>
Date: Sat, 24 Mar 2001 03:52:24 -0800 (PST)
From: chervarium@nove.bg
To: freebsd-gnats-submit@FreeBSD.org
Subject: bug in modular vn code causes a fatal trap 12
X-Send-Pr-Version: www-1.0

>Number:         26049
>Category:       i386
>Synopsis:       bug in modular vn code causes a fatal trap 12
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 24 04:00:02 PST 2001
>Closed-Date:    Mon Mar 26 09:02:20 PST 2001
>Last-Modified:  Mon Mar 26 09:05:07 PST 2001
>Originator:     Atanas Bachvaroff
>Release:        FreeBSD 4.3-BETA
>Organization:
NOVE Holding
>Environment:
none available (sorry, didn't get all information needed on the floppy disk)
>Description:
incorrectly modularised vn driver causes a fatal trap 12 due to when module is unloaded, it's entry in cdevsw[] array is left unchanged. afterward, any lstat-ting /dev/vn0 result in unresolved page fault and crash. last in chain function devsw from /usr/src/sys/kerc/kern_conf.c returns invalid (struct cdevsw *) pointer to vn_isdisk from vfs_subr.c, and that pointer is accessed (i'm not describing the whole functions chain, everyone can see it in the sources):
        if (!devsw(vp->v_rdev)) {
                if (errp != NULL)
                        *errp = ENXIO;
                return (0);
        }
        if (!(devsw(vp->v_rdev)->d_flags & D_DISK)) {
                if (errp != NULL)
                        *errp = ENOTBLK;
                return (0);
        }
(watch the second major if statement)
this problem may be found in other modular disk drivers. patch available (posted in the "Fix to the problem if known" part)...
>How-To-Repeat:
almost any loading of vn, using it and unloading it, followed by lstat syscall to "/dev/vn0" result in activating the bug and fatal trap 12 (page fault exception on x86 in protected mode with paging bit in %cr0 = 1 ;)...
>Fix:
--- /usr/src/sys/dev/vn/vn.c        Mon May 15 19:50:33 2000
+++ /usr/src/sys/dev/vn/vn.c        Sat Mar 24 12:09:07 2001
@@ -776,6 +776,7 @@
                                vnclear(vn);
                        free(vn, M_DEVBUF);
                }
+               cdevsw_remove(&vn_cdevsw);
                break;
        default:
                break;

>Release-Note:
>Audit-Trail:

From: Ian Dowse <iedowse@maths.tcd.ie>
To: chervarium@nove.bg
Cc: freebsd-gnats-submit@FreeBSD.org, iedowse@maths.tcd.ie
Subject: Re: i386/26049: bug in modular vn code causes a fatal trap 12 
Date: Sun, 25 Mar 2001 20:30:38 +0100

 In message <200103241152.f2OBqOh33828@freefall.freebsd.org>, chervarium@nove.bg
  writes:
 
 >@@ -776,6 +776,7 @@
 >                                vnclear(vn);
 >                        free(vn, M_DEVBUF);
 >                }
 >+               cdevsw_remove(&vn_cdevsw);
 >                break;
 
 Thanks for the bug report, though it seems that this patch is not
 quite enough to solve the problems that occur when unloading the
 `vn' module after use.
 
 If you attempt to use vnconfig again after the module has been
 unloaded, it may appear to work, but the system could become unstable
 and crash somewhere else. With 'options INVARIANTS' in the kernel
 config file, this problem is much more obvious and the following
 sequence of operations will cause a crash.
 
 	dd if=/dev/zero bs=1k count=100 of=/tmp/foo
 	vnconfig -e /dev/vn0 /tmp/foo
 	vnconfig -u /dev/vn0
 	kldunload vn
 	vnconfig -e /dev/vn0 /tmp/foo
 
 The following patch, which includes the cdevsw_remove you suggested,
 seems to solve this. The module stores a pointer to the vn_softc in
 the device si_drv1 field, but this pointer will be stale if the
 module is unloaded and then reloaded. This patch avoids the use
 of this saved pointer in vnopen by forcing a full lookup.
 
 Ian
 
 Index: vn.c
 ===================================================================
 RCS file: /dump/FreeBSD-CVS/src/sys/dev/vn/Attic/vn.c,v
 retrieving revision 1.105.2.1
 diff -u -r1.105.2.1 vn.c
 --- vn.c	2000/05/15 16:50:33	1.105.2.1
 +++ vn.c	2001/03/25 19:09:54
 @@ -177,13 +177,10 @@
  	struct vn_softc *vn;
  
  	unit = dkunit(dev);
 -	vn = dev->si_drv1;
 -	if (!vn) {
 -		SLIST_FOREACH(vn, &vn_list, sc_list) {
 -			if (vn->sc_unit == unit) {
 -				dev->si_drv1 = vn;
 -				break;
 -			}
 +	SLIST_FOREACH(vn, &vn_list, sc_list) {
 +		if (vn->sc_unit == unit) {
 +			dev->si_drv1 = vn;
 +			break;
  		}
  	}
  	if (!vn) {
 @@ -208,9 +205,7 @@
  	/*
  	 * Locate preexisting device
  	 */
 -
 -	if ((vn = dev->si_drv1) == NULL)
 -		vn = vnfindvn(dev);
 +	vn = vnfindvn(dev);
  
  	/*
  	 * Update si_bsize fields for device.  This data will be overriden by
 @@ -776,6 +771,7 @@
  				vnclear(vn);
  			free(vn, M_DEVBUF);
  		}
 +		cdevsw_remove(&vn_cdevsw);
  		break;
  	default:
  		break;

From: "Nick Hibma" <n_hibma@qubesoft.com>
To: <freebsd-gnats-submit@FreeBSD.org>, <chervarium@nove.bg>
Cc:  
Subject: Re: i386/26049: bug in modular vn code causes a fatal trap 12
Date: Mon, 26 Mar 2001 09:21:01 +0200

 http://www.freebsd.org/cgi/query-pr.cgi?pr=18270
 
 is a duplicate of this one. I believe that I committd the fix to current
 quite some time ago.
 
 Could you close this one as well, while you are at it?
 
 Thanks.
 
 Nick
 
State-Changed-From-To: open->closed 
State-Changed-By: iedowse 
State-Changed-When: Mon Mar 26 09:02:20 PST 2001 
State-Changed-Why:  
A similar patch, based on kern/18270 has been committed to -stable. 
Thanks for the bug report! 


http://www.freebsd.org/cgi/query-pr.cgi?pr=26049 
>Unformatted:
