From root@blackbox.quis.cx  Mon Jan  7 15:46:07 2008
Return-Path: <root@blackbox.quis.cx>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id DCECB16A421
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 Jan 2008 15:46:07 +0000 (UTC)
	(envelope-from root@blackbox.quis.cx)
Received: from blackbox.quis.cx (ip83-113-174-82.adsl2.versatel.nl [82.174.113.83])
	by mx1.freebsd.org (Postfix) with ESMTP id 7B4BE13C4CC
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  7 Jan 2008 15:46:07 +0000 (UTC)
	(envelope-from root@blackbox.quis.cx)
Received: from blackbox.quis.cx (localhost [127.0.0.1])
	by blackbox.quis.cx (8.14.2/8.14.2) with ESMTP id m07AaXQ8000878;
	Mon, 7 Jan 2008 11:36:33 +0100 (CET)
	(envelope-from root@blackbox.quis.cx)
Received: (from root@localhost)
	by blackbox.quis.cx (8.14.2/8.14.2/Submit) id m07AaXkK000877;
	Mon, 7 Jan 2008 11:36:33 +0100 (CET)
	(envelope-from root)
Message-Id: <200801071036.m07AaXkK000877@blackbox.quis.cx>
Date: Mon, 7 Jan 2008 11:36:33 +0100 (CET)
From: Jille Timmermans <jille@quis.cx>
Reply-To: Jille Timmermans <jille@quis.cx>
To: FreeBSD-gnats-submit@freebsd.org
Cc: Ed Schouten <ed@fxq.nl>
Subject: Kernel panic (page fault) with devfs rules
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         119422
>Category:       kern
>Synopsis:       [devfs] Kernel panic (page fault) with devfs rules
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kib
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 07 15:50:00 UTC 2008
>Closed-Date:    Mon Jun 30 12:35:21 UTC 2008
>Last-Modified:  Mon Jun 30 12:35:21 UTC 2008
>Originator:     Jille Timmermans
>Release:        FreeBSD 6.3-PRERELEASE i386
>Organization:
None
>Environment:
System: FreeBSD blackbox.quis.cx 6.3-PRERELEASE FreeBSD 6.3-PRERELEASE #1: Sun Jan 6 23:24:15 CET 2008 root@blackbox.quis.cx:/usr/obj/usr/src/sys/BLACKBOX i386
And: FreeBSD istud.quis.cx 6.2-RELEASE-p4 FreeBSD 6.2-RELEASE-p4 #0: Sat May 12 16:41:58 CEST 2007 root@istud.quis.cx:/usr/obj/usr/src/sys/ISTUD i386


>Description:
	A kernel panic (page fault) occurs when trying to add/apply rules to a devfs mount.
	A value of a null-pointed struct is used in devfs_rule_match().
	(/usr/src/sys/fs/devfs/devfs_rule.c:546)

	I can give you kernel dumps/backtraces if needed.
>How-To-Repeat:
	# mkdir dev
	# mount -t devfs devfs dev
	# devfs -m dev ruleset 50
	# devfs -m dev rule add type disk hide
	# devfs -m dev rule applyset
>Fix:
	In /usr/src/sys/fs/devfs/devfs_rule.c:546
		if (dev == NULL ||
	Change into:
		if (dev == NULL || dev->si_devsw == NULL ||

	I changed this and recompiled, the crash didn't occur anymore.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->kib 
Responsible-Changed-By: kib 
Responsible-Changed-When: Tue Mar 11 09:38:55 UTC 2008 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=119422 

From: Kostik Belousov <kostikbel@gmail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/119422: [devfs] Kernel panic (page fault) with devfs rules
Date: Tue, 18 Mar 2008 19:31:35 +0200

 --GFHRPGHrS2AOMWit
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 Besides the problem with the device aliases that have si_devsw =3D=3D NULL,
 there is a race with the destroy_dev() that may clean the si_devsw
 during the device destruction.
 
 The same problem is presented in the two places in vm/vm_mmap.c, one of
 them seems to be dead.
 
 All the places seems to be a leftover from the earlier days of devfs,
 see devfs_rule.c rev. 1.13 and commit message.
 
 Patch below seems to help.
 
 diff --git a/sys/fs/devfs/devfs_rule.c b/sys/fs/devfs/devfs_rule.c
 index 1255e03..4fdb781 100644
 --- a/sys/fs/devfs/devfs_rule.c
 +++ b/sys/fs/devfs/devfs_rule.c
 @@ -527,6 +527,7 @@ devfs_rule_match(struct devfs_krule *dk, struct devfs_d=
 irent *de)
  {
  	struct devfs_rule *dr =3D &dk->dk_rule;
  	struct cdev *dev;
 +	struct cdevsw *dsw;
 =20
  	dev =3D devfs_rule_getdev(de);
  	/*
 @@ -540,13 +541,19 @@ devfs_rule_match(struct devfs_krule *dk, struct devfs=
 _dirent *de)
  	 * They're actually testing to see whether the condition does
  	 * *not* match, since the default is to assume the rule should
  	 * be run (such as if there are no conditions).
 -	 *
 -	 * XXX: lacks threadref on dev
  	 */
 -	if (dr->dr_icond & DRC_DSWFLAGS)
 -		if (dev =3D=3D NULL ||
 -		    (dev->si_devsw->d_flags & dr->dr_dswflags) =3D=3D 0)
 +	if (dr->dr_icond & DRC_DSWFLAGS) {
 +		if (dev =3D=3D NULL)
 +			return (0);
 +		dsw =3D dev_refthread(dev);
 +		if (dsw =3D=3D NULL)
 +			return (0);
 +		if ((dsw->d_flags & dr->dr_dswflags) =3D=3D 0) {
 +			dev_relthread(dev);
  			return (0);
 +		}
 +		dev_relthread(dev);
 +	}
  	if (dr->dr_icond & DRC_PATHPTRN)
  		if (!devfs_rule_matchpath(dk, de))
  			return (0);
 diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
 index ad9b34e..e7ae233 100644
 --- a/sys/vm/vm_mmap.c
 +++ b/sys/vm/vm_mmap.c
 @@ -1160,6 +1160,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
  	void *handle;
  	vm_object_t obj;
  	struct mount *mp;
 +	struct cdevsw *dsw;
  	int error, flags, type;
  	int vfslocked;
 =20
 @@ -1190,13 +1191,19 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
  		type =3D OBJT_DEVICE;
  		handle =3D vp->v_rdev;
 =20
 -		/* XXX: lack thredref on device */
 -		if(vp->v_rdev->si_devsw->d_flags & D_MMAP_ANON) {
 +		dsw =3D dev_refthread(handle);
 +		if (dsw =3D=3D NULL) {
 +			error =3D ENXIO;
 +			goto done;
 +		}
 +		if (dsw->d_flags & D_MMAP_ANON) {
 +			dev_relthread(handle);
  			*maxprotp =3D VM_PROT_ALL;
  			*flagsp |=3D MAP_ANON;
  			error =3D 0;
  			goto done;
  		}
 +		dev_relthread(handle);
  		/*
  		 * cdevs does not provide private mappings of any kind.
  		 */
 @@ -1273,16 +1280,21 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
      struct cdev *cdev, vm_ooffset_t foff, vm_object_t *objp)
  {
  	vm_object_t obj;
 +	struct cdevsw *dsw;
  	int flags;
 =20
  	flags =3D *flagsp;
 =20
 -	/* XXX: lack thredref on device */
 -	if (cdev->si_devsw->d_flags & D_MMAP_ANON) {
 +	dsw =3D dev_refthread(cdev);
 +	if (dsw =3D=3D NULL)
 +		return (ENXIO);
 +	if (dsw->d_flags & D_MMAP_ANON) {
 +		dev_relthread(cdev);
  		*maxprotp =3D VM_PROT_ALL;
  		*flagsp |=3D MAP_ANON;
  		return (0);
  	}
 +	dev_relthread(cdev);
  	/*
  	 * cdevs does not provide private mappings of any kind.
  	 */
 
 --GFHRPGHrS2AOMWit
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.8 (FreeBSD)
 
 iEYEARECAAYFAkff/HcACgkQC3+MBN1Mb4jxYQCgiQ81Qm5nEbk/DXcpGEC7xXRw
 +yoAn3h4oZxROdU8zV2xjLElfyrE8u2v
 =lRmm
 -----END PGP SIGNATURE-----
 
 --GFHRPGHrS2AOMWit--

From: Kostik Belousov <kostikbel@gmail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/119422: [devfs] Kernel panic (page fault) with devfs rules
Date: Tue, 18 Mar 2008 19:51:11 +0200

 Resend of the patch with proper content-type.
 
 diff --git a/sys/fs/devfs/devfs_rule.c b/sys/fs/devfs/devfs_rule.c
 index 1255e03..4fdb781 100644
 --- a/sys/fs/devfs/devfs_rule.c
 +++ b/sys/fs/devfs/devfs_rule.c
 @@ -527,6 +527,7 @@ devfs_rule_match(struct devfs_krule *dk, struct devfs_dirent *de)
  {
  	struct devfs_rule *dr = &dk->dk_rule;
  	struct cdev *dev;
 +	struct cdevsw *dsw;
  
  	dev = devfs_rule_getdev(de);
  	/*
 @@ -540,13 +541,19 @@ devfs_rule_match(struct devfs_krule *dk, struct devfs_dirent *de)
  	 * They're actually testing to see whether the condition does
  	 * *not* match, since the default is to assume the rule should
  	 * be run (such as if there are no conditions).
 -	 *
 -	 * XXX: lacks threadref on dev
  	 */
 -	if (dr->dr_icond & DRC_DSWFLAGS)
 -		if (dev == NULL ||
 -		    (dev->si_devsw->d_flags & dr->dr_dswflags) == 0)
 +	if (dr->dr_icond & DRC_DSWFLAGS) {
 +		if (dev == NULL)
 +			return (0);
 +		dsw = dev_refthread(dev);
 +		if (dsw == NULL)
 +			return (0);
 +		if ((dsw->d_flags & dr->dr_dswflags) == 0) {
 +			dev_relthread(dev);
  			return (0);
 +		}
 +		dev_relthread(dev);
 +	}
  	if (dr->dr_icond & DRC_PATHPTRN)
  		if (!devfs_rule_matchpath(dk, de))
  			return (0);
 diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
 index ad9b34e..e7ae233 100644
 --- a/sys/vm/vm_mmap.c
 +++ b/sys/vm/vm_mmap.c
 @@ -1160,6 +1160,7 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
  	void *handle;
  	vm_object_t obj;
  	struct mount *mp;
 +	struct cdevsw *dsw;
  	int error, flags, type;
  	int vfslocked;
  
 @@ -1190,13 +1191,19 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
  		type = OBJT_DEVICE;
  		handle = vp->v_rdev;
  
 -		/* XXX: lack thredref on device */
 -		if(vp->v_rdev->si_devsw->d_flags & D_MMAP_ANON) {
 +		dsw = dev_refthread(handle);
 +		if (dsw == NULL) {
 +			error = ENXIO;
 +			goto done;
 +		}
 +		if (dsw->d_flags & D_MMAP_ANON) {
 +			dev_relthread(handle);
  			*maxprotp = VM_PROT_ALL;
  			*flagsp |= MAP_ANON;
  			error = 0;
  			goto done;
  		}
 +		dev_relthread(handle);
  		/*
  		 * cdevs does not provide private mappings of any kind.
  		 */
 @@ -1273,16 +1280,21 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
      struct cdev *cdev, vm_ooffset_t foff, vm_object_t *objp)
  {
  	vm_object_t obj;
 +	struct cdevsw *dsw;
  	int flags;
  
  	flags = *flagsp;
  
 -	/* XXX: lack thredref on device */
 -	if (cdev->si_devsw->d_flags & D_MMAP_ANON) {
 +	dsw = dev_refthread(cdev);
 +	if (dsw == NULL)
 +		return (ENXIO);
 +	if (dsw->d_flags & D_MMAP_ANON) {
 +		dev_relthread(cdev);
  		*maxprotp = VM_PROT_ALL;
  		*flagsp |= MAP_ANON;
  		return (0);
  	}
 +	dev_relthread(cdev);
  	/*
  	 * cdevs does not provide private mappings of any kind.
  	 */

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119422: commit references a PR
Date: Thu, 20 Mar 2008 16:08:53 +0000 (UTC)

 kib         2008-03-20 16:08:42 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/vm               vm_mmap.c 
     sys/fs/devfs         devfs_rule.c 
   Log:
   Do not dereference cdev->si_cdevsw, use the dev_refthread() to properly
   obtain the reference. In particular, this fixes the panic reported in
   the PR. Remove the comments stating that this needs to be done.
   
   PR:     kern/119422
   MFC after:      1 week
   
   Revision  Changes    Path
   1.24      +12 -5     src/sys/fs/devfs/devfs_rule.c
   1.218     +16 -4     src/sys/vm/vm_mmap.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: remko 
State-Changed-When: Thu Mar 20 23:39:28 UTC 2008 
State-Changed-Why:  
Konstantin patched this, reflect the status. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=119422 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119422: commit references a PR
Date: Fri, 16 May 2008 10:35:22 +0000 (UTC)

 kib         2008-05-16 10:35:16 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_6)
     sys/fs/devfs         devfs_rule.c 
     sys/vm               vm_mmap.c 
   Log:
   MFC rev. 1.24 of the sys/fs/devfs/devfs_rule.c,
       rev. 1.218 of the sys/vm/vm_mmap.c
   
   Do not dereference cdev->si_cdevsw, use the dev_refthread() to properly
   obtain the reference. In particular, this fixes the panic reported in
   the PR. Remove the comments stating that this needs to be done.
   
   PR:     kern/119422
   
   Revision   Changes    Path
   1.14.2.4   +12 -5     src/sys/fs/devfs/devfs_rule.c
   1.200.2.5  +16 -4     src/sys/vm/vm_mmap.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: gavin 
State-Changed-When: Mon Jun 30 12:33:34 UTC 2008 
State-Changed-Why:  
Close, kib@ has fixed this in HEAD, RELENG_7 and RELENG_6 

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