From nobody@FreeBSD.org  Tue Oct  2 17:26:15 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 6719716A41A
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  2 Oct 2007 17:26:15 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 2BE5313C45D
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  2 Oct 2007 17:26:15 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.1/8.14.1) with ESMTP id l92HQEFF091116
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 2 Oct 2007 17:26:14 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.1/8.14.1/Submit) id l92HQE2H091109;
	Tue, 2 Oct 2007 17:26:14 GMT
	(envelope-from nobody)
Message-Id: <200710021726.l92HQE2H091109@www.freebsd.org>
Date: Tue, 2 Oct 2007 17:26:14 GMT
From: Jonathan Pascal <jkpyvxmzsa@mailinator.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: ifconfig tunX destroy: panic
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         116837
>Category:       kern
>Synopsis:       [tun] [panic] [patch] ifconfig tunX destroy: panic
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    bz
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 02 17:30:06 GMT 2007
>Closed-Date:    Fri Oct 15 15:11:35 UTC 2010
>Last-Modified:  Fri Oct 15 15:11:35 UTC 2010
>Originator:     Jonathan Pascal
>Release:        -CURRENT as of 2007-09-29
>Organization:
>Environment:
FreeBSD box 7.0-CURRENT FreeBSD 7.0-CURRENT #4: Sat Sep 29 19:41:37 CEST 2007     root@box:/usr/obj/usr/src/sys/CURRENT_STARLIGHT  i386
>Description:
Destroying a tun device while a process is using it via /dev/tunX leads
to a kernel panic.
>How-To-Repeat:
# cat < /dev/tun0 > /dev/tun0 &
# ifconfig tun0 destroy

panic: tununits is out of sync - unit 0
>Fix:


>Release-Note:
>Audit-Trail:

From: "Remko Lodder" <remko@elvandar.org>
To: "Jonathan Pascal" <jkpyvxmzsa@mailinator.com>
Cc: freebsd-gnats-submit@freebsd.org,
 freebsd-bugs@FreeBSD.org
Subject: Re: kern/116837: ifconfig tunX destroy: panic
Date: Tue, 2 Oct 2007 19:48:58 +0200 (CEST)

 So are you running with the debugging symbols etc? Do you get a core dump?
 if so please go to the
 http://www.freebsd.org/doc/en/books/developers-handbook/kerneldebug.html
 page and see how you can get more information there. This PR ticket is
 rather difficult to fix without detailed information.
 
 Thanks & Regards
 remko
 
 -- 
 Kind regards,
 
      Remko Lodder               ** remko@elvandar.org
      FreeBSD                    ** remko@FreeBSD.org
 
      /* Quis custodiet ipsos custodes */
 
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: thompsa 
Responsible-Changed-When: Tue Oct 2 18:15:43 UTC 2007 
Responsible-Changed-Why:  
A core dump isnt needed for this PR, the problem is quite 
obvious (not not necessarily the solution). 


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

From: Bob Van Zant <bob@veznat.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116837: ifconfig tunX destroy: panic
Date: Sun, 6 Jan 2008 22:46:09 +0530

 My FreeBSD 7.0-PRERELEASE box has been running into this problem a lot  
 recently when I reset my ppp connection to counteract the effects of  
 having a very poor ISP. I would like to fix this bug. Is there anyone  
 that can help me identify what the proper behavior is?
 
 In my case the repro is something along the lines of:
 
 - Create ppp connection (tun0)
 - Create six-to-four connection (stf0)
 - The ppp connection gets wedged
 - /etc/rc.d/ppp stop
 - ifconfig tun0 destroy
 -     kernel panic
 
 My hunch is that the stf0 interface being "on top" of tun0 is causing  
 the problem. I've changed the script, maybe the panic will stop  
 happening.
 
 But what should the behavior be? Should the if_tun code make an  
 attempt to clean up whatever it can and then just destroy the  
 interface like requested? Or should it return some sort of error and  
 the ifconfig request to destroy the interface fails?
 
 The if_tap code appears to have the same assert in its destroy  
 function and we may want to fix that as well.
 
 I tend to get a few spare hours during any given week to play with  
 these sorts of things and I'd like to be able to help out with this  
 one. Any sort of direction folks can give in working towards a  
 solution will be appreciated.
 
 -Bob
 

From: KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
To: bug-followup@FreeBSD.org, jkpyvxmzsa@mailinator.com
Cc:  
Subject: Re: kern/116837: ifconfig tunX destroy: panic
Date: Sat, 12 Jan 2008 15:48:39 +0900

 The KASSERT() check in tun_destroy() seems incorrect
 since the function can actually be called while
 a user thread is opening /dev/tunX.  If we needed to
 ensure that no threads have fd for /dev/tunX in
 tun_destroy(), we should implement it in if_tun.
 
 Instead, we can rely on destroy_dev() to ensure that
 no threads access /dev/tunX anymore (the function
 blocks when there are threads accessing the device).
 But just deleting KASSERT() is insufficient because
 there is a race condition: tun_destroy() calls
 if_free() before destroy_dev(), so user threads might
 access the destroyed ifnet structure by read()/write()/...
 on /dev/tunX.
 
 I guess the following change is needed for if_tun.c:
 
 --- sys/net/if_tun.c	2008/01/11 04:14:11	1.1
 +++ sys/net/if_tun.c	2008/01/12 04:04:39
 @@ -249,15 +249,12 @@ tun_destroy(struct tun_softc *tp)
  {
  	struct cdev *dev;
  
 -	/* Unlocked read. */
 -	KASSERT((tp->tun_flags & TUN_OPEN) == 0,
 -	    ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
 -
  	dev = tp->tun_dev;
 +	/* destroy_dev() ensures no threads access /dev/tunX anymore. */
 +	destroy_dev(dev);
  	bpfdetach(TUN2IFP(tp));
  	if_detach(TUN2IFP(tp));
  	if_free(TUN2IFP(tp));
 -	destroy_dev(dev);
  	knlist_destroy(&tp->tun_rsel.si_note);
  	mtx_destroy(&tp->tun_mtx);
  	free(tp, M_TUN);

From: Bob Van Zant <bvanzant@ironport.com>
To: <bug-followup@FreeBSD.org>
Cc:  
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Thu, 24 Jan 2008 12:40:19 +0530

 I applied the patch in the prior comment and now I get this, different,
 kernel panic (yanked from dmesg):
 
 Fatal trap 12: page fault while in kernel mode
 cpuid = 0; apic id = 00
 fault virtual address    = 0xdeadc0e6
 fault code        = supervisor write, page not present
 instruction pointer    = 0x20:0xc07903b5
 stack pointer            = 0x28:0xd62a2ab4
 frame pointer            = 0x28:0xd62a2ac8
 code segment        = base 0x0, limit 0xfffff, type 0x1b
             = DPL 0, pres 1, def32 1, gran 1
 processor eflags    = interrupt enabled, resume, IOPL = 0
 current process        = 3091 (ppp)
 trap number        = 12
 panic: page fault
 cpuid = 0
 Uptime: 1h58m15s
 Physical memory: 499 MB
 Dumping 154 MB: 139 123 107 91 75 59 43 27 11
 Dump complete
 
 
 Plopping into kgdb:
 
 (kgdb) list *0xc07903b5
 0xc07903b5 is in clear_selinfo_list (/usr/src/sys/kern/sys_generic.c:1066).
 1061    {
 1062        struct selinfo *si;
 1063    
 1064        mtx_assert(&sellock, MA_OWNED);
 1065        TAILQ_FOREACH(si, &td->td_selq, si_thrlist)
 1066            si->si_thread = NULL;
 1067        TAILQ_INIT(&td->td_selq);
 1068    }
 1069    
 1070    /*
 
 
 (kgdb) bt
 #0  doadump () at pcpu.h:195
 #1  0xc075957f in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:409
 #2  0xc075984b in panic (fmt=Variable "fmt" is not available.
 ) at /usr/src/sys/kern/kern_shutdown.c:563
 #3  0xc0a41913 in trap_fatal (frame=0xd62a2a74, eva=3735929062)
     at /usr/src/sys/i386/i386/trap.c:899
 #4  0xc0a41af0 in trap_pfault (frame=0xd62a2a74, usermode=0, eva=3735929062)
     at /usr/src/sys/i386/i386/trap.c:812
 #5  0xc0a42432 in trap (frame=0xd62a2a74) at
 /usr/src/sys/i386/i386/trap.c:490
 #6  0xc0a289bb in calltrap () at /usr/src/sys/i386/i386/exception.s:139
 #7  0xc07903b5 in clear_selinfo_list (td=0xc321d220)
     at /usr/src/sys/kern/sys_generic.c:1065
 #8  0xc0791168 in kern_select (td=0xc321d220, nd=11, fd_in=0x28413c00,
     fd_ou=0x28414000, fd_ex=0x28414400, tvp=0x0)
     at /usr/src/sys/kern/sys_generic.c:794
 #9  0xc079131e in select (td=0xc321d220, uap=0xd62a2cfc)
     at /usr/src/sys/kern/sys_generic.c:663
 #10 0xc0a41dc3 in syscall (frame=0xd62a2d38)
     at /usr/src/sys/i386/i386/trap.c:1035
 #11 0xc0a28a20 in Xint0x80_syscall () at
 /usr/src/sys/i386/i386/exception.s:196
 #12 0x00000033 in ?? ()
 

From: KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
To: bug-followup@FreeBSD.org, bvanzant@ironport.com, jkpyvxmzsa@mailinator.com
Cc:  
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Tue, 5 Feb 2008 12:58:31 +0900

 It seems that lackness of waking up a process sleeping on select(2)
 caused the panic.  The following patch (instead of the previous one)
 might fix the problem.
 
 --- sys/net/if_tun.c	2008/01/11 04:14:11	1.1
 +++ sys/net/if_tun.c	2008/01/29 02:22:43
 @@ -249,15 +249,16 @@ tun_destroy(struct tun_softc *tp)
  {
  	struct cdev *dev;
  
 -	/* Unlocked read. */
 -	KASSERT((tp->tun_flags & TUN_OPEN) == 0,
 -	    ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
 -
  	dev = tp->tun_dev;
 +	/* destroy_dev() ensures no threads access /dev/tunX anymore. */
 +	destroy_dev(dev);
  	bpfdetach(TUN2IFP(tp));
  	if_detach(TUN2IFP(tp));
  	if_free(TUN2IFP(tp));
 -	destroy_dev(dev);
 +
 +	funsetown(&tp->tun_sigio);
 +	selwakeuppri(&tp->tun_rsel, PZERO + 1);
 +	KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
  	knlist_destroy(&tp->tun_rsel.si_note);
  	mtx_destroy(&tp->tun_mtx);
  	free(tp, M_TUN);

From: Bob Van Zant <bob@veznat.com>
To: <bug-followup@FreeBSD.org>
Cc:  
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Tue, 05 Feb 2008 10:04:08 +0530

 I've been running this patch for the past ~6 days and haven't seen a panic
 yet. Prior to this I was panicing 2-3 times a day so I think this patch
 fixes the problem.
 
 I believe that this same problem exists with the tap interface. Should we
 fix it at the same time?
 
 -Bob
 
 

From: KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
To: bug-followup@FreeBSD.org, jkpyvxmzsa@mailinator.com
Cc:  
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Tue, 17 Feb 2009 11:42:00 +0900

 This is fixed on recent 8-CURRENT, but probably not yet on 7.x.

From: Lucius Windschuh <lwindschuh@googlemail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Sat, 21 Feb 2009 14:27:45 +0100

 This is a follow-up to PR kern/116837. The described issue is solved,
 but now we have this issue.
 The following simple steps lead to a kernel panic on my system (i386,
 SMP, 8-CURRENT from Feb. 18th):
 
 -->8--
 cat < /dev/tun0 > /dev/tun0 &
 ifconfig tun0 up
 ifconfig tun0 destroy & ifconfig tun0 destroy
 --8<--
 
 Panic string: Bad link elm 0xc6437c00 prev->next != elm
 
 Responsible backtraces:
 
 Tracing pid 1610 tid 100114 td 0xc686f240
 kdb_enter(c090abd7,c090abd7,c08e2418,eaefeb6c,0,...) at kdb_enter+0x3a
 panic(c08e2418,c6437c00,c091867f,d3,2d,...) at panic+0x136
 if_clone_destroyif(c0976300,c6437c00,c091867f,bf,0,...) at
 if_clone_destroyif+0x8a
 if_clone_destroy(c724f320,19c,eaefebd4,c0604976,c1494788,...) at
 if_clone_destroy+0xa2
 ifioctl(c7077dc8,80206979,c724f320,c686f240,80206979,...) at ifioctl+0x116
 soo_ioctl(c71deaf0,80206979,c724f320,c722a000,c686f240,...) at soo_ioctl+0x397
 kern_ioctl(c686f240,3,80206979,c724f320,64c3c0,...) at kern_ioctl+0x1dd
 ioctl(c686f240,eaefecf8,c,c,c09644b0,...) at ioctl+0x134
 syscall(eaefed38) at syscall+0x2a3
 Xint0x80_syscall() at Xint0x80_syscall+0x20
 
 Tracing command ifconfig pid 1611 tid 100194 td 0xc6c9b000
 sched_switch(c6c9b000,0,104,18d,5796c911,...) at sched_switch+0x437
 mi_switch(104,0,c090edc3,1d2,0,...) at mi_switch+0x200
 sleepq_switch(c6c9b000,0,c090edc3,247,c6c9b000,...) at sleepq_switch+0x15f
 sleepq_wait(c69aa850,0,c0918d9f,1,0,...) at sleepq_wait+0x63
 _cv_wait_unlock(c69aa850,c69aa83c,c0918d76,102,c69aa800,...) at
 _cv_wait_unlock+0x1d4
 tun_destroy(c09ca0d8,0,c0918d76,11c) at tun_destroy+0x49
 tun_clone_destroy(c6437c00,c6437c00,c6437c00,c0976300,eb04eb88,...) at
 tun_clone_destroy+0xb8
 ifc_simple_destroy(c0976300,c6437c00,c091867f,d5,2d,...) at
 ifc_simple_destroy+0x27
 if_clone_destroyif(c0976300,c6437c00,c091867f,bf,0,...) at
 if_clone_destroyif+0xe1
 if_clone_destroy(c677cb20,19c,eb04ebd4,c0604976,c1494788,...) at
 if_clone_destroy+0xa2
 ifioctl(c7257620,80206979,c677cb20,c6c9b000,80206979,...) at ifioctl+0x116
 soo_ioctl(c7285bd0,80206979,c677cb20,c722a000,c6c9b000,...) at soo_ioctl+0x397
 kern_ioctl(c6c9b000,3,80206979,c677cb20,64c3c0,...) at kern_ioctl+0x1dd
 ioctl(c6c9b000,eb04ecf8,c,c,c09644b0,...) at ioctl+0x134
 syscall(eb04ed38) at syscall+0x2a3
 Xint0x80_syscall() at Xint0x80_syscall+0x20
 --- syscall (54, FreeBSD ELF32, ioctl), eip = 0x281b4b83, esp =
 0xbfbfe47c, ebp = 0xbfbfe498 ---
 
 OK, it's odd to destroy an interface two times in parallel. But it
 shouldn't crash the kernel. ;-)
 
 This panic is triggered reliably.
 To rule out side effects of my kernel config, I ran the same test with
 the GENERIC config and got the same result: panic.
 
 The textdump is available here:
 http://sites.google.com/site/lwfreebsd/Home/files/tun0-double-destroy.zip?attredirects=0
 
 I can supply more information if needed.
 
 
 Kind regards,
 
 Lucius

From: Takahiro Kurosawa <takahiro.kurosawa@gmail.com>
To: Lucius Windschuh <lwindschuh@googlemail.com>
Cc: bug-followup@freebsd.org
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Sun, 1 Mar 2009 14:46:44 +0900

 2009/2/21 Lucius Windschuh <lwindschuh@googlemail.com>:
 
 > =A0This is a follow-up to PR kern/116837. The described issue is solved,
 > =A0but now we have this issue.
 > =A0The following simple steps lead to a kernel panic on my system (i386,
 > =A0SMP, 8-CURRENT from Feb. 18th):
 >
 > =A0-->8--
 > =A0cat < /dev/tun0 > /dev/tun0 &
 > =A0ifconfig tun0 up
 > =A0ifconfig tun0 destroy & ifconfig tun0 destroy
 > =A0--8<--
 >
 > =A0Panic string: Bad link elm 0xc6437c00 prev->next !=3D elm
 >
 > =A0Responsible backtraces:
 >
 > =A0Tracing pid 1610 tid 100114 td 0xc686f240
 > =A0kdb_enter(c090abd7,c090abd7,c08e2418,eaefeb6c,0,...) at kdb_enter+0x3a
 > =A0panic(c08e2418,c6437c00,c091867f,d3,2d,...) at panic+0x136
 > =A0if_clone_destroyif(c0976300,c6437c00,c091867f,bf,0,...) at
 > =A0if_clone_destroyif+0x8a
 > =A0if_clone_destroy(c724f320,19c,eaefebd4,c0604976,c1494788,...) at
 > =A0if_clone_destroy+0xa2
 
 if_clone_destroyif() should check that ifp is on ifc->ifc_iflist
 but it doesn't.
 
 Probably the following patch may fix this problem, but I fear that
 there might be another race between a thread accessing the ifp members
 and a thread calling if_clone_destroy().
 
 # This is a shell archive.  Save it in a file, remove anything before
 # this line, and then unpack it by entering "sh file".  Note, it may
 # create directories; files and directories will be owned by you and
 # have default permissions.
 #
 # This archive contains:
 #
 #	if_clone.c.diff
 #
 echo x - if_clone.c.diff
 sed 's/^X//' >if_clone.c.diff << 'fa5d2f08d96bc39865fb972ff194104f'
 X=3D=3D=3D sys/net/if_clone.c
 X=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 X--- sys/net/if_clone.c	(revision 189132)
 X+++ sys/net/if_clone.c	(local)
 X@@ -201,6 +201,7 @@
 X int
 X if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
 X {
 X+	struct ifnet *tmp;
 X 	int err;
 X
 X 	if (ifc->ifc_destroy =3D=3D NULL) {
 X@@ -209,8 +210,15 @@
 X 	}
 X
 X 	IF_CLONE_LOCK(ifc);
 X-	IFC_IFLIST_REMOVE(ifc, ifp);
 X+	LIST_FOREACH(tmp, &ifc->ifc_iflist, if_clones) {
 X+		if (tmp =3D=3D ifp) {
 X+			IFC_IFLIST_REMOVE(ifc, ifp);
 X+			break;
 X+		}
 X+	}
 X 	IF_CLONE_UNLOCK(ifc);
 X+	if (tmp =3D=3D NULL)
 X+		return (ENXIO);		/* ifp is not on the list. */
 X
 X 	if_delgroup(ifp, ifc->ifc_name);
 X
 fa5d2f08d96bc39865fb972ff194104f
 exit
Responsible-Changed-From-To: freebsd-net->bz 
Responsible-Changed-By: bz 
Responsible-Changed-When: Sun Apr 11 18:49:46 UTC 2010 
Responsible-Changed-Why:  
Take at least temporary. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116837: commit references a PR
Date: Sun, 11 Apr 2010 18:41:59 +0000 (UTC)

 Author: bz
 Date: Sun Apr 11 18:41:31 2010
 New Revision: 206486
 URL: http://svn.freebsd.org/changeset/base/206486
 
 Log:
   Check that the interface is on the list of cloned interfaces before trying
   to remove it to avoid panics in case of two threads trying to remove it in
   parallel.
   
   PR:		kern/116837
   Submitted by:	Takahiro Kurosawa (takahiro.kurosawa gmail.com) (orig version)
   MFC after:	10 days
 
 Modified:
   head/sys/net/if_clone.c
 
 Modified: head/sys/net/if_clone.c
 ==============================================================================
 --- head/sys/net/if_clone.c	Sun Apr 11 16:28:10 2010	(r206485)
 +++ head/sys/net/if_clone.c	Sun Apr 11 18:41:31 2010	(r206486)
 @@ -234,6 +234,7 @@ int
  if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
  {
  	int err;
 +	struct ifnet *ifcifp;
  
  	if (ifc->ifc_destroy == NULL)
  		return(EOPNOTSUPP);
 @@ -246,8 +247,17 @@ if_clone_destroyif(struct if_clone *ifc,
  	CURVNET_SET_QUIET(ifp->if_vnet);
  
  	IF_CLONE_LOCK(ifc);
 -	IFC_IFLIST_REMOVE(ifc, ifp);
 +	LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
 +		if (ifcifp == ifp) {
 +			IFC_IFLIST_REMOVE(ifc, ifp);
 +			break;
 +		}
 +	}
  	IF_CLONE_UNLOCK(ifc);
 +	if (ifcifp == NULL) {
 +		CURVNET_RESTORE();
 +		return (ENXIO);		/* ifp is not on the list. */
 +	}
  
  	if_delgroup(ifp, ifc->ifc_name);
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116837: commit references a PR
Date: Sun, 11 Apr 2010 18:48:02 +0000 (UTC)

 Author: bz
 Date: Sun Apr 11 18:47:38 2010
 New Revision: 206488
 URL: http://svn.freebsd.org/changeset/base/206488
 
 Log:
   Take a reference to make sure that the interface cannot go away during
   if_clone_destroy() in case parallel threads try to.
   
   PR:		kern/116837
   Submitted by:	Mikolaj Golub (to.my.trociny gmail.com)
   MFC after:	10 days
 
 Modified:
   head/sys/net/if_clone.c
 
 Modified: head/sys/net/if_clone.c
 ==============================================================================
 --- head/sys/net/if_clone.c	Sun Apr 11 18:44:42 2010	(r206487)
 +++ head/sys/net/if_clone.c	Sun Apr 11 18:47:38 2010	(r206488)
 @@ -196,10 +196,11 @@ if_clone_createif(struct if_clone *ifc, 
  int
  if_clone_destroy(const char *name)
  {
 +	int err;
  	struct if_clone *ifc;
  	struct ifnet *ifp;
  
 -	ifp = ifunit(name);
 +	ifp = ifunit_ref(name);
  	if (ifp == NULL)
  		return (ENXIO);
  
 @@ -221,10 +222,14 @@ if_clone_destroy(const char *name)
  	}
  #endif
  	IF_CLONERS_UNLOCK();
 -	if (ifc == NULL)
 +	if (ifc == NULL) {
 +		if_rele(ifp);
  		return (EINVAL);
 +	}
  
 -	return (if_clone_destroyif(ifc, ifp));
 +	err = if_clone_destroyif(ifc, ifp);
 +	if_rele(ifp);
 +	return err;
  }
  
  /*
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: "Bjoern A. Zeeb" <bz@FreeBSD.org>
To: bug-followup@FreeBSD.org, jkpyvxmzsa@mailinator.com
Cc: Bob Van Zant <bob@veznat.com>, 
    KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Sun, 11 Apr 2010 18:53:05 +0000 (UTC)

 Hi,
 
 can someone please summarize what the state of the changes to if_tun.c
 are in various branches?  Does it still need to be fixed in 7.x and
 earlier?  Do you know when it was fixed in 8.x/9.x?
 
 Thanks,
 Bjoern
 
 -- 
 Bjoern A. Zeeb         It will not break if you know what you are doing.

From: KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
To: "Bjoern A. Zeeb" <bz@FreeBSD.org>
Cc: bug-followup@FreeBSD.org, jkpyvxmzsa@mailinator.com,
        Bob Van Zant <bob@veznat.com>,
        KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Wed, 14 Apr 2010 12:35:19 +0900

 Hi,
 
 At Sun, 11 Apr 2010 18:53:05 +0000 (UTC),
 Bjoern A. Zeeb wrote:
 
 > can someone please summarize what the state of the changes to if_tun.c
 > are in various branches?  Does it still need to be fixed in 7.x and
 > earlier?  Do you know when it was fixed in 8.x/9.x?
 
 7-STABLE (r206532) still has the problem.
 8.0-RELEASE does not have the problem.  The first fix was done
 in r186391, but r186391 seems to introduce another problem.
 The problem seems to be fixed completely in r186497.
 
 Thanks,
 ----
 KUROSAWA Takahiro
 fwkg7679@mb.infoweb.ne.jp
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116837: commit references a PR
Date: Wed, 21 Apr 2010 20:01:28 +0000 (UTC)

 Author: bz
 Date: Wed Apr 21 19:55:43 2010
 New Revision: 207014
 URL: http://svn.freebsd.org/changeset/base/207014
 
 Log:
   MFC r206486:
   
     Check that the interface is on the list of cloned interfaces before trying
     to remove it to avoid panics in case of two threads trying to remove it in
     parallel.
   
   PR:	      kern/116837
   Submitted by: Takahiro Kurosawa (takahiro.kurosawa gmail.com) (orig version)
 
 Modified:
   stable/8/sys/net/if_clone.c
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
   stable/8/sys/dev/xen/xenpci/   (props changed)
   stable/8/sys/geom/sched/   (props changed)
 
 Modified: stable/8/sys/net/if_clone.c
 ==============================================================================
 --- stable/8/sys/net/if_clone.c	Wed Apr 21 19:51:22 2010	(r207013)
 +++ stable/8/sys/net/if_clone.c	Wed Apr 21 19:55:43 2010	(r207014)
 @@ -234,6 +234,7 @@ int
  if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
  {
  	int err;
 +	struct ifnet *ifcifp;
  
  	if (ifc->ifc_destroy == NULL)
  		return(EOPNOTSUPP);
 @@ -246,8 +247,17 @@ if_clone_destroyif(struct if_clone *ifc,
  	CURVNET_SET_QUIET(ifp->if_vnet);
  
  	IF_CLONE_LOCK(ifc);
 -	IFC_IFLIST_REMOVE(ifc, ifp);
 +	LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
 +		if (ifcifp == ifp) {
 +			IFC_IFLIST_REMOVE(ifc, ifp);
 +			break;
 +		}
 +	}
  	IF_CLONE_UNLOCK(ifc);
 +	if (ifcifp == NULL) {
 +		CURVNET_RESTORE();
 +		return (ENXIO);		/* ifp is not on the list. */
 +	}
  
  	if_delgroup(ifp, ifc->ifc_name);
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116837: commit references a PR
Date: Wed, 21 Apr 2010 20:02:16 +0000 (UTC)

 Author: bz
 Date: Wed Apr 21 20:00:13 2010
 New Revision: 207015
 URL: http://svn.freebsd.org/changeset/base/207015
 
 Log:
   MFC r206488:
   
     Take a reference to make sure that the interface cannot go away during
     if_clone_destroy() in case parallel threads try to.
   
   PR:		kern/116837
   Submitted by:	Mikolaj Golub (to.my.trociny gmail.com)
 
 Modified:
   stable/8/sys/net/if_clone.c
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
   stable/8/sys/dev/xen/xenpci/   (props changed)
   stable/8/sys/geom/sched/   (props changed)
 
 Modified: stable/8/sys/net/if_clone.c
 ==============================================================================
 --- stable/8/sys/net/if_clone.c	Wed Apr 21 19:55:43 2010	(r207014)
 +++ stable/8/sys/net/if_clone.c	Wed Apr 21 20:00:13 2010	(r207015)
 @@ -196,10 +196,11 @@ if_clone_createif(struct if_clone *ifc, 
  int
  if_clone_destroy(const char *name)
  {
 +	int err;
  	struct if_clone *ifc;
  	struct ifnet *ifp;
  
 -	ifp = ifunit(name);
 +	ifp = ifunit_ref(name);
  	if (ifp == NULL)
  		return (ENXIO);
  
 @@ -221,10 +222,14 @@ if_clone_destroy(const char *name)
  	}
  #endif
  	IF_CLONERS_UNLOCK();
 -	if (ifc == NULL)
 +	if (ifc == NULL) {
 +		if_rele(ifp);
  		return (EINVAL);
 +	}
  
 -	return (if_clone_destroyif(ifc, ifp));
 +	err = if_clone_destroyif(ifc, ifp);
 +	if_rele(ifp);
 +	return err;
  }
  
  /*
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: Mikolaj Golub <to.my.trociny@gmail.com>
To: bug-followup@FreeBSD.org
Cc: Jonathan Pascal <jkpyvxmzsa@mailinator.com>, "Bjoern A. Zeeb" <bz@FreeBSD.org>, KUROSAWA Takahiro <fwkg7679@mb.infoweb.ne.jp>
Subject: Re: kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic
Date: Mon, 03 May 2010 10:35:45 +0300

 --=-=-=
 
 I am attaching the patch for 7-STABLE, which is r186391 + a part of r186483
 (drop the tun_mtx after the flag check). This fixes initial problem described
 in this pr (panic when destroying a tun device while /dev/tunX is still open)
 for 7-STABLE too.
 
 Note, we have kern/133902 which is duplicate of this pr (the panic was obtain
 there by destroing tun used by ssh for tunneling; I have reproduced it on
 7-STABLE and checked that panic does not observe with the patch).
 
 -- 
 Mikolaj Golub
 
 
 --=-=-=
 Content-Type: text/x-diff
 Content-Disposition: attachment; filename=if_tun.c.destroy.patch
 
 --- sys/net/if_tun.c.orig	2010-03-07 22:06:06.000000000 +0200
 +++ sys/net/if_tun.c	2010-05-03 00:25:50.000000000 +0300
 @@ -56,6 +56,7 @@
  #include <net/if_tun.h>
  
  #include <sys/queue.h>
 +#include <sys/condvar.h>
  
  #include <security/mac/mac_framework.h>
  
 @@ -92,6 +93,7 @@ struct tun_softc {
  	struct  sigio *tun_sigio;	/* information for async I/O */
  	struct	selinfo	tun_rsel;	/* read select */
  	struct mtx	tun_mtx;	/* protect mutable softc fields */
 +	struct cv	tun_cv;		/* protect against ref'd dev destroy */
  };
  #define TUN2IFP(sc)	((sc)->tun_ifp)
  
 @@ -242,8 +244,11 @@ tun_destroy(struct tun_softc *tp)
  	struct cdev *dev;
  
  	/* Unlocked read. */
 -	KASSERT((tp->tun_flags & TUN_OPEN) == 0,
 -	    ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
 +	mtx_lock(&tp->tun_mtx);
 +	if ((tp->tun_flags & TUN_OPEN) != 0)
 +		cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
 +	else
 +		mtx_unlock(&tp->tun_mtx);
  
  	dev = tp->tun_dev;
  	bpfdetach(TUN2IFP(tp));
 @@ -252,6 +257,7 @@ tun_destroy(struct tun_softc *tp)
  	destroy_dev(dev);
  	knlist_destroy(&tp->tun_rsel.si_note);
  	mtx_destroy(&tp->tun_mtx);
 +	cv_destroy(&tp->tun_cv);
  	free(tp, M_TUN);
  }
  
 @@ -353,6 +359,7 @@ tuncreate(const char *name, struct cdev 
  
  	MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
  	mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
 +	cv_init(&sc->tun_cv, "tun_condvar");
  	sc->tun_flags = TUN_INITED;
  	sc->tun_dev = dev;
  	mtx_lock(&tunmtx);
 @@ -436,6 +443,7 @@ tunclose(struct cdev *dev, int foo, int 
  	mtx_lock(&tp->tun_mtx);
  	tp->tun_flags &= ~TUN_OPEN;
  	tp->tun_pid = 0;
 +	mtx_unlock(&tp->tun_mtx);
  
  	/*
  	 * junk all pending output
 @@ -443,7 +451,6 @@ tunclose(struct cdev *dev, int foo, int 
  	s = splimp();
  	IFQ_PURGE(&ifp->if_snd);
  	splx(s);
 -	mtx_unlock(&tp->tun_mtx);
  
  	if (ifp->if_flags & IFF_UP) {
  		s = splimp();
 @@ -470,10 +477,14 @@ tunclose(struct cdev *dev, int foo, int 
  		splx(s);
  	}
  
 +	mtx_lock(&tp->tun_mtx);
  	funsetown(&tp->tun_sigio);
  	selwakeuppri(&tp->tun_rsel, PZERO + 1);
  	KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
  	TUNDEBUG (ifp, "closed\n");
 +
 +	cv_broadcast(&tp->tun_cv);
 +	mtx_unlock(&tp->tun_mtx);
  	return (0);
  }
  
 
 --=-=-=--

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/116837: commit references a PR
Date: Fri, 15 Oct 2010 15:06:39 +0000 (UTC)

 Author: bz
 Date: Fri Oct 15 15:06:32 2010
 New Revision: 213895
 URL: http://svn.freebsd.org/changeset/base/213895
 
 Log:
   MFC r186391,186483,186497 (qingli, kmacy 21 months ago):
   
   r186391:
     Provide a condition variable to delay the cloned interface
     destroy operation until the referenced clone device has
     been closed by the process properly. The behavior is now
     consistently with the previous release.
   
   r186483:
     - Close a race during which the open flag could be cleared but the
       tun_softc would still be referenced by adding a separate TUN_CLOSED
       flag that is set after tunclose is done referencing it.
     - drop the tun_mtx after the flag check to avoid holding it across
       if_detach which can recurse in to if_tun.c
   
   r186497:
     The "tun?" dev need not be opened at all. One is allowed to perform
     the following operations, e.g.:
     1) ifconfig tun0 create
     2) ifconfig tun0 10.1.1.1 10.1.1.2
     3) route add -net 192.103.54.0/24 -iface tun0
     4) ifconfig tun0 destroy
     If cv wait on the TUN_CLOSED flag, then the last operation (4) will
     block forever.
   
     Revert the previous changes and fix the mtx_unlock() leak.
   
   PR:		kern/116837
   Submitted by:	Mikolaj Golub (to.my.trociny gmail.com)
   		(Not used the patch, just did the MFC)
 
 Modified:
   stable/7/sys/net/if_tun.c
 Directory Properties:
   stable/7/sys/   (props changed)
   stable/7/sys/cddl/contrib/opensolaris/   (props changed)
   stable/7/sys/contrib/dev/acpica/   (props changed)
   stable/7/sys/contrib/pf/   (props changed)
 
 Modified: stable/7/sys/net/if_tun.c
 ==============================================================================
 --- stable/7/sys/net/if_tun.c	Fri Oct 15 15:00:30 2010	(r213894)
 +++ stable/7/sys/net/if_tun.c	Fri Oct 15 15:06:32 2010	(r213895)
 @@ -56,6 +56,7 @@
  #include <net/if_tun.h>
  
  #include <sys/queue.h>
 +#include <sys/condvar.h>
  
  #include <security/mac/mac_framework.h>
  
 @@ -92,6 +93,7 @@ struct tun_softc {
  	struct  sigio *tun_sigio;	/* information for async I/O */
  	struct	selinfo	tun_rsel;	/* read select */
  	struct mtx	tun_mtx;	/* protect mutable softc fields */
 +	struct cv	tun_cv;		/* protect against ref'd dev destroy */
  };
  #define TUN2IFP(sc)	((sc)->tun_ifp)
  
 @@ -242,8 +244,11 @@ tun_destroy(struct tun_softc *tp)
  	struct cdev *dev;
  
  	/* Unlocked read. */
 -	KASSERT((tp->tun_flags & TUN_OPEN) == 0,
 -	    ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
 +	mtx_lock(&tp->tun_mtx);
 +	if ((tp->tun_flags & TUN_OPEN) != 0)
 +		cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
 +	else
 +		mtx_unlock(&tp->tun_mtx);
  
  	dev = tp->tun_dev;
  	bpfdetach(TUN2IFP(tp));
 @@ -252,6 +257,7 @@ tun_destroy(struct tun_softc *tp)
  	destroy_dev(dev);
  	knlist_destroy(&tp->tun_rsel.si_note);
  	mtx_destroy(&tp->tun_mtx);
 +	cv_destroy(&tp->tun_cv);
  	free(tp, M_TUN);
  }
  
 @@ -353,6 +359,7 @@ tuncreate(const char *name, struct cdev 
  
  	MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
  	mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
 +	cv_init(&sc->tun_cv, "tun_condvar");
  	sc->tun_flags = TUN_INITED;
  	sc->tun_dev = dev;
  	mtx_lock(&tunmtx);
 @@ -472,6 +479,8 @@ tunclose(struct cdev *dev, int foo, int 
  	selwakeuppri(&tp->tun_rsel, PZERO + 1);
  	KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
  	TUNDEBUG (ifp, "closed\n");
 +
 +	cv_broadcast(&tp->tun_cv);
  	mtx_unlock(&tp->tun_mtx);
  	return (0);
  }
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: bz 
State-Changed-When: Fri Oct 15 15:10:58 UTC 2010 
State-Changed-Why:  
Remaining missing changes merged to stable/7 as well. 
Thanks a lot to everyone involved for reporting, testing and 
sending patches. 

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