Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Aug 2012 18:33:12 -0400
From:      Randall Stewart <rrs@lakerest.net>
To:        John Baldwin <jhb@freebsd.org>
Cc:        svn-src-head@freebsd.org, Randall Stewart <rrs@freebsd.org>, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r239334 - head/sys/netinet
Message-ID:  <896011BA-5F0C-4371-A9D2-6E96283380E0@lakerest.net>
In-Reply-To: <201208161534.42012.jhb@freebsd.org>
References:  <201208161755.q7GHtHHZ048693@svn.freebsd.org> <201208161534.42012.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On Aug 16, 2012, at 3:34 PM, John Baldwin wrote:

> On Thursday, August 16, 2012 1:55:17 pm Randall Stewart wrote:
>> Author: rrs
>> Date: Thu Aug 16 17:55:16 2012
>> New Revision: 239334
>> URL: http://svn.freebsd.org/changeset/base/239334
>>=20
>> Log:
>>  Its never a good idea to double free the same
>>  address.
>>=20
>>  MFC after:	1 week (after the other commits ahead of this gets =
MFC'd)
>>=20
>> Modified:
>>  head/sys/netinet/in.c
>>=20
>> Modified: head/sys/netinet/in.c
>>=20
> =
=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=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
>> --- head/sys/netinet/in.c	Thu Aug 16 17:27:11 2012	=
(r239333)
>> +++ head/sys/netinet/in.c	Thu Aug 16 17:55:16 2012	=
(r239334)
>> @@ -573,7 +573,7 @@ in_control(struct socket *so, u_long cmd
>> 	}
>> 	TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
>> 	IF_ADDR_WUNLOCK(ifp);
>> -	ifa_free(&ia->ia_ifa);				/* if_addrhead =
*/
>> +/*	ifa_free(&ia->ia_ifa);	- Double free?? */	/* if_addrhead =
*/
>=20
> This isn't a double free.  This is dropping a reference count.  In =
this case=20
> as the comment suggests, it is removing the reference held by the per-
> interface if_addrhead list that it was just removed from two lines =
above. =20
> Later in the function when ifa_free() is invoked:
>=20
> 	LIST_REMOVE(ia, ia_hash);
> 	IN_IFADDR_WUNLOCK();
> 	...
> 	ifa_free(&ia->ia_ifa);				/* in_ifaddrhead =
*/
>=20
> It is dropping the reference held by the in_ifaddrhead list which the =
ifa
> was removed from by the above LIST_REMOVE().  Are you seeing a panic =
or
> refcount underflow or some such?
>=20

No panic, I wish I were so lucky, I had a lockup/fault at:

in_gif.c line 410 (this is 9 stable)
-----------------------
        IN_IFADDR_RLOCK();
        TAILQ_FOREACH(ia4, &V_in_ifaddrhead, ia_link) {
                if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) =3D=3D=
 0) <------fault in kernel HERE
                        continue;
                if (ip->ip_src.s_addr =3D=3D =
ia4->ia_broadaddr.sin_addr.s_addr) {
                        IN_IFADDR_RUNLOCK();
                        return 0;
                }
        }
        IN_IFADDR_RUNLOCK();
------------------------

I went through and made sure first that every reference using =
V_in_ifaddrhead
was properly locking, and they were. The only thing I could find is =
this. From
the instructions I could see in the assembly the ia4->ia_ifa.ifa_ifp was =
NULL. And
thus caused a deref of a NULL pointer.

Hmm, it takes two days of pounding to get this by the way. We are using =
a Shenick with
our proxy that is adding and deleting addresses on a somewhat regular =
basis while
traffic is flowing ;-0

Something that not a lot of folks do obviously=85 not sure why I did not
get into DDB, two CPU's faulted at the same time though.. also the HP's =
that
this thing was running on are not known for being kind on getting into =
even
DDB ;-(

Be glad when we get them all replaced with iX systems ;-)


R

> --=20
> John Baldwin
>=20

------------------------------
Randall Stewart
803-317-4952 (cell)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?896011BA-5F0C-4371-A9D2-6E96283380E0>