Re: Possible leak of multicast source filter sctructure #3a

2006-08-16 Thread Michal Ruzicka
The same patch as in previous e-mail with a few typos in comments corrected:

Signed-off-by: Michal Ruzicka [EMAIL PROTECTED]

--- linux-2.6.17.8/net/ipv4/igmp.c.orig 2006-08-11 11:50:46.0 +0200
+++ linux-2.6.17.8/net/ipv4/igmp.c  2006-08-16 16:53:08.0 +0200
@@ -1369,13 +1369,15 @@
struct flowi fl = { .nl_u = { .ip4_u =
  { .daddr = imr-imr_multiaddr.s_addr } } 
};
struct rtable *rt;
-   struct net_device *dev = NULL;
-   struct in_device *idev = NULL;
+   struct net_device *dev;
 
if (imr-imr_ifindex) {
-   idev = inetdev_by_index(imr-imr_ifindex);
-   if (idev)
+   struct in_device *idev = inetdev_by_index(imr-imr_ifindex);
+
+   if (idev) {
+   imr-imr_address.s_addr = 0;
__in_dev_put(idev);
+   }
return idev;
}
if (imr-imr_address.s_addr) {
@@ -1383,17 +1385,16 @@
if (!dev)
return NULL;
dev_put(dev);
-   }
-
-   if (!dev  !ip_route_output_key(rt, fl)) {
+   } else if (!ip_route_output_key(rt, fl)) {
dev = rt-u.dst.dev;
ip_rt_put(rt);
-   }
-   if (dev) {
-   imr-imr_ifindex = dev-ifindex;
-   idev = __in_dev_get_rtnl(dev);
-   }
-   return idev;
+   if (!dev)
+   return NULL;
+   } else
+   return NULL;
+
+   imr-imr_ifindex = dev-ifindex;
+   return __in_dev_get_rtnl(dev);
 }
 
 /*
@@ -1798,27 +1799,79 @@
u32 ifindex;
 
rtnl_lock();
-   in_dev = ip_mc_find_dev(imr);
-   if (!in_dev) {
-   rtnl_unlock();
-   return -ENODEV;
-   }
ifindex = imr-imr_ifindex;
-   for (imlp = inet-mc_list; (iml = *imlp) != NULL; imlp = iml-next) {
-   if (iml-multi.imr_multiaddr.s_addr == group 
-   iml-multi.imr_ifindex == ifindex) {
-   (void) ip_mc_leave_src(sk, iml, in_dev);
-
-   *imlp = iml-next;
-
-   ip_mc_dec_group(in_dev, group);
-   rtnl_unlock();
-   sock_kfree_s(sk, iml, sizeof(*iml));
-   return 0;
+   in_dev = ip_mc_find_dev(imr);
+   if (ifindex != 0) {
+   /* leave by interface index */
+   for (imlp = inet-mc_list; (iml = *imlp) != NULL; imlp = 
iml-next) {
+   if (iml-multi.imr_multiaddr.s_addr != group)
+   continue;
+
+   if (iml-multi.imr_ifindex == ifindex)
+   goto leave;
+   }
+   } else {
+   /* leave by address / multicast group route */
+   struct ip_mc_socklist **cimlp = NULL;
+   u32 address = imr-imr_address.s_addr;
+
+   ifindex = imr-imr_ifindex;
+   for (imlp = inet-mc_list; (iml = *imlp) != NULL; imlp = 
iml-next) {
+   if (iml-multi.imr_multiaddr.s_addr != group)
+   continue;
+
+   if (iml-multi.imr_ifindex == ifindex)
+   /* direct match
+* NOTE: We do not have to test for in_dev != 
NULL
+* since we know that ifindex was zero before 
call
+* to ip_mc_find_dev() but is non-zero now (as
+* it equals to an interface index which is 
never
+* zero). The ip_mc_find_dev() function modifies
+* the ifindex only if it finds an interface
+* (in wich case it returns non-NULL). Thus the
+* in_dev must be non-NULL.
+*/
+   goto leave;
+
+   if (cimlp == NULL  iml-multi.imr_address.s_addr == 
address)
+   cimlp = imlp;
+   }
+
+   if (cimlp != NULL) {
+   /* We have found at least one candidate interface
+* for leaving by address but not a direct match.
+* Since there is no way to tell what interface the user
+* wnated to leave the multicast group on we are going
+* to leave it on the first candidate interface found.
+*/
+   iml = *(imlp = cimlp);
+
+   if (in_dev != NULL) {
+   /* If we have found an interface matching the 
leave
+* request chances are that the interface which 
we
+* are about to leave the multicast group on 
still

Re: Possible leak of multicast source filter sctructure #3a

2006-08-16 Thread David Stevens
Michal,
I believe the patch I submitted yesterday fixes this
problem, and in a simpler way.

+-DLS

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html