From nobody@FreeBSD.org  Wed Jul 19 20:53:41 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id D390E16A4DA
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 19 Jul 2006 20:53:41 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 6F87C43D66
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 19 Jul 2006 20:53:41 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k6JKrf5x092253
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 19 Jul 2006 20:53:41 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k6JKrfNc092252;
	Wed, 19 Jul 2006 20:53:41 GMT
	(envelope-from nobody)
Message-Id: <200607192053.k6JKrfNc092252@www.freebsd.org>
Date: Wed, 19 Jul 2006 20:53:41 GMT
From: Tom Parker <freebsd@wiresncode.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Multicast data structure corruption in ipv6 stack
X-Send-Pr-Version: www-2.3

>Number:         100579
>Category:       kern
>Synopsis:       [ipv6] Multicast data structure corruption in ipv6 stack
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    bms
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jul 19 21:00:30 GMT 2006
>Closed-Date:    Thu Jan 03 12:46:27 UTC 2008
>Last-Modified:  Thu Jan 03 12:46:27 UTC 2008
>Originator:     Tom Parker
>Release:        N/A
>Organization:
>Environment:
Using ported version of 4.4 code.  Code inspection reveals problem seems to be present in current releases.
>Description:
When an interface is removed in6_ifdetach calls in6_pcbpurgeif0 which calls
in6_delmulti.  This call path frees, but does not remove the in6_multi
structure from sockets that have listened to it.  Upon IPV6_LEAVE_GROUP
freed memory is accessed in ip6_setmoptions because the in6_multi is still
present in the im6o_memberships list in the pcb.

Here is my posting to freebsd-net.

Hi,

New to the list here, but fairly familiar with the innards of (at
least an older) version of the fbsd networking code. I'm fortunate in
my ability to run purify on a simulated instance of our ported version
of the networking code.  Purify has picked up a problem that I'm a bit
mystified as how it can be fixed.  It is present in current versions
also, I'm interested in any comments people have (I think ours is 4.4
vintage, but it is hard to tell).

As far as I can tell, in most calling paths when in6_delmulti() is
called, it is done after the in6_multi_mship structure has been
removed from the im6o_memberships list in the relevant PCB.  This
applies to in6_ifdetach(), in6_pcbpurgeif0, ip6_setmoptions()  etc.
However in in6_purgeaddr() in6_delmulti is called straight off.  I'm
not sure if we've violated some usage convention, but purify is
telling me this causes access violations when we then leave the same
group using setsockopt().  in6_purgeaddr is called when we remove the
address from the interface.

This should be possible in a real kernel.  Add a multicast address to
an interface, open a socket and listen to the address, then remove the
address from the interface.

Am I missing something here or is this a nasty problem in both the
kernel and our stack port?

Thanks,
Tom
>How-To-Repeat:
I am seeing this in a ported version of the code, I am not sure how to
reproduce in the kernel but I can see no reason why this path might not be
hit with a removable interface.
>Fix:
Reference counting for in6_multi is proxied to ifmultiaddr. in6m_refcount
in in6_multi is unused.  Proper independant reference counting is needed
for in6_multi so that it can persist if referenced by a socket after
ifmultiaddr is destroyed.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->bms 
Responsible-Changed-By: bms 
Responsible-Changed-When: Mon Mar 5 09:49:40 UTC 2007 
Responsible-Changed-Why:  
I'll take this. It sounds very similar to problems we have had in IPv4. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100579 
State-Changed-From-To: open->analyzed 
State-Changed-By: bms 
State-Changed-When: Thu Mar 15 19:27:36 UTC 2007 
State-Changed-Why:  
This problem is there all right. And it's in IPv4 too. 
We are relying on the refcounting in ifma. This is a problem because 
ifma is tied to ifnet, which may go away during the lifetime of 
the system. This causes big problems for both sockets and anything 
which invokes in_addmulti() on behalf of another interface e.g. 
carp and pfsync. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100579 
State-Changed-From-To: analyzed->patched 
State-Changed-By: bms 
State-Changed-When: Tue Mar 20 00:40:03 UTC 2007 
State-Changed-Why:  
Architectural changes in -CURRENT should address this 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100579 
State-Changed-From-To: patched->closed 
State-Changed-By: bms 
State-Changed-When: Thu 3 Jan 2008 12:45:42 UTC 
State-Changed-Why:  
7.0 is now its own release branch. Refcounting is (mostly) implemented, 
and folk are actively looking at the v6 stack. 

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