ifaddr refcount problem

Gleb Smirnoff glebius at FreeBSD.org
Mon Jun 23 08:52:36 UTC 2014


  Navdeep,

On Fri, Jun 20, 2014 at 12:15:21PM -0700, Navdeep Parhar wrote:
N> Revision 264905 and 266860 that followed it seem to leak ifaddr
N> references.  ifa_ifwithdstaddr and ifa_ifwithnet both install a
N> reference on the ifaddr returned to the caller but ip_output does not
N> release it, eventually leading to a panic when the refcount wraps over
N> to 0 and the ifaddr is freed while it is still on various lists.
N> 
N> I'm using this patch for now.  Thoughts?
N> 
N> Regards,
N> Navdeep
N> 
N> 
N> diff -r 6dfcecd314af sys/netinet/ip_output.c
N> --- a/sys/netinet/ip_output.c	Fri Jun 20 10:33:22 2014 -0700
N> +++ b/sys/netinet/ip_output.c	Fri Jun 20 12:07:12 2014 -0700
N> @@ -243,6 +243,7 @@ again:
N>  		ifp = ia->ia_ifp;
N>  		ip->ip_ttl = 1;
N>  		isbroadcast = 1;
N> +		ifa_free((void *)ia);
N>  	} else if (flags & IP_ROUTETOIF) {
N>  		if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL &&
N>  		    (ia = ifatoia(ifa_ifwithnet(sintosa(dst), 0))) == NULL) {
N> @@ -253,6 +254,7 @@ again:
N>  		ifp = ia->ia_ifp;
N>  		ip->ip_ttl = 1;
N>  		isbroadcast = in_broadcast(dst->sin_addr, ifp);
N> +		ifa_free((void *)ia);
N>  	} else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
N>  	    imo != NULL && imo->imo_multicast_ifp != NULL) {
N>  		/*

The patch shouldn't use void * casts, but instead specify explicit member:

	ifa_free(&ia->ia_ifa);

Apart from that it, the patch looks entirely correct and plugging a leak.
Thanks!

-- 
Totus tuus, Glebius.


More information about the freebsd-net mailing list