kern/116837: [tun] [panic] [patch] ifconfig tunX destroy: panic

Takahiro Kurosawa takahiro.kurosawa at gmail.com
Sat Feb 28 21:50:03 PST 2009


The following reply was made to PR kern/116837; it has been noted by GNATS.

From: Takahiro Kurosawa <takahiro.kurosawa at gmail.com>
To: Lucius Windschuh <lwindschuh at googlemail.com>
Cc: bug-followup at 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 at 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


More information about the freebsd-net mailing list