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>