Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Mar 2005 15:20:05 GMT
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/78227: Destroying a network interface leaks kernel memory
Message-ID:  <200503091520.j29FK5EF041922@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/78227; it has been noted by GNATS.

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Yar Tikhiy <yar@comp.chem.msu.su>, oleg@rinet.ru
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: kern/78227: Destroying a network interface leaks kernel memory
Date: Wed, 9 Mar 2005 18:13:15 +0300

 --vtzGhvizbBRQ85DL
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: inline
 
   This is already fixed in NetBSD a long time ago, and recently in OpenBSD.
 
 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netinet/in.c#rev1.64
 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/netinet/in.c#rev1.65
 
 http://www.openbsd.org/cgi-bin/cvsweb/src/sys/netinet/in.c#rev1.39
 
 I like OpenBSD's solution. Please look at the attached patch; it
 adds in_multi pointer into in_ifaddr, assigns it return value of
 in_addmulti() and calls in_delmulti() when removing address.
 
 P.S. I suspect we also have a memory leak when interface is joined a
 multicast group and then destroyed.
 
 -- 
 Totus tuus, Glebius.
 GLEBIUS-RIPN GLEB-RIPE
 
 --vtzGhvizbBRQ85DL
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: attachment; filename="kern.78227.diff"
 
 Index: in.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/in.c,v
 retrieving revision 1.81
 diff -u -r1.81 in.c
 --- in.c	7 Jan 2005 01:45:44 -0000	1.81
 +++ in.c	9 Mar 2005 15:05:32 -0000
 @@ -433,6 +433,14 @@
  		 */
  		in_ifscrub(ifp, ia);
  		/*
 +		 * Leave all hosts multicast group,
 +		 * freeing memory.
 +		 */
 +		if (ia->ia_allhosts != NULL) {
 +			in_delmulti(ia->ia_allhosts);
 +			ia->ia_allhosts = NULL;
 +		}
 +		/*
  		 * in_ifadown gets rid of all the rest of
  		 * the routes.  This is not quite the right
  		 * thing to do, but at least if we are running
 @@ -746,11 +760,11 @@
  	 * If the interface supports multicast, join the "all hosts"
  	 * multicast group on that interface.
  	 */
 -	if (ifp->if_flags & IFF_MULTICAST) {
 +	if ((ifp->if_flags & IFF_MULTICAST) && ia->ia_allhosts == NULL) {
  		struct in_addr addr;
  
  		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
 -		in_addmulti(&addr, ifp);
 +		ia->ia_allhosts =  in_addmulti(&addr, ifp);
  	}
  	return (error);
  }
 Index: in_var.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/in_var.h,v
 retrieving revision 1.53
 diff -u -r1.53 in_var.h
 --- in_var.h	7 Jan 2005 01:45:44 -0000	1.53
 +++ in_var.h	9 Mar 2005 15:00:40 -0000
 @@ -58,6 +58,8 @@
  	struct	sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
  #define	ia_broadaddr	ia_dstaddr
  	struct	sockaddr_in ia_sockmask; /* reserve space for general netmask */
 +	struct	in_multi *ia_allhosts;	 /* multicast address record for
 +					    the allhosts multicast group */
  };
  
  struct	in_aliasreq {
 
 --vtzGhvizbBRQ85DL--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200503091520.j29FK5EF041922>