kern/78227: Destroying a network interface leaks kernel memory
Gleb Smirnoff
glebius at FreeBSD.org
Wed Mar 9 15:20:06 GMT 2005
The following reply was made to PR kern/78227; it has been noted by GNATS.
From: Gleb Smirnoff <glebius at FreeBSD.org>
To: Yar Tikhiy <yar at comp.chem.msu.su>, oleg at rinet.ru
Cc: freebsd-gnats-submit at 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--
More information about the freebsd-bugs
mailing list