* Possible leak of multicast source filter sctructure
2006-08-10 10:20 ` Ville Nuorvala
@ 2006-08-10 12:07 ` Michal Ruzicka
2006-08-10 12:12 ` David Miller
2006-08-10 18:07 ` David Stevens
0 siblings, 2 replies; 13+ messages in thread
From: Michal Ruzicka @ 2006-08-10 12:07 UTC (permalink / raw)
To: davem, kuznet; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 1610 bytes --]
Hi all!
It seems to me that there is a leak of struct ip_sf_socklist in the
ip_mc_drop_socket function (in net/ipv4/igmp.c) which is called on socket
close.
This patch corrects it:
diff -Naur linux-2.6.17.8.orig/net/ipv4/igmp.c
linux-2.6.17.8/net/ipv4/igmp.c
--- linux-2.6.17.8.orig/net/ipv4/igmp.c 2006-08-07 06:18:54.000000000 +0200
+++ linux-2.6.17.8/net/ipv4/igmp.c 2006-08-10 10:38:04.000000000 +0200
@@ -2206,9 +2206,10 @@
(void) ip_mc_leave_src(sk, iml, in_dev);
ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
in_dev_put(in_dev);
- }
- sock_kfree_s(sk, iml, sizeof(*iml));
+ } else if (iml->sflist != NULL)
+ sock_kfree_s(sk, iml->sflist, IP_SFLSIZE(iml->sflist->sl_max));
+ sock_kfree_s(sk, iml, sizeof(*iml));
}
rtnl_unlock();
}
The leak only happens if there are some multicast source filters set on a
socket wich are bound to an interface that does not exist any more, as in
the following scenario:
1. create a temporary interface (say GRE tunnel)
3. join a multicast group an set a source filter on the temporary interface
via MCAST_JOIN_SOURCE_GROUP setsockopt call
4. destroy the temporary interface
5. close the socket
This sequence of things eventually leads to a call of ip_mc_drop_socket
function, which fails to free the soucre filter structure ip_sf_socklist
pointed to from members of socket's multicast addresses list. This structure
is normally freed in ip_mc_leave_src function but this function is not
called in this scenario because the interface that the multicast group is
joined on does not exist any more.
Thanks
Michal Ruzicka
[-- Attachment #2: linux-2.6.17.8-mc_sf_leak.patch --]
[-- Type: application/octet-stream, Size: 609 bytes --]
diff -Naur linux-2.6.17.8.orig/net/ipv4/igmp.c linux-2.6.17.8/net/ipv4/igmp.c
--- linux-2.6.17.8.orig/net/ipv4/igmp.c 2006-08-07 06:18:54.000000000 +0200
+++ linux-2.6.17.8/net/ipv4/igmp.c 2006-08-10 10:38:04.000000000 +0200
@@ -2206,9 +2206,10 @@
(void) ip_mc_leave_src(sk, iml, in_dev);
ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
in_dev_put(in_dev);
- }
- sock_kfree_s(sk, iml, sizeof(*iml));
+ } else if (iml->sflist != NULL)
+ sock_kfree_s(sk, iml->sflist, IP_SFLSIZE(iml->sflist->sl_max));
+ sock_kfree_s(sk, iml, sizeof(*iml));
}
rtnl_unlock();
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
2006-08-10 12:07 ` Possible leak of multicast source filter sctructure Michal Ruzicka
@ 2006-08-10 12:12 ` David Miller
2006-08-10 12:13 ` David Miller
2006-08-10 18:07 ` David Stevens
1 sibling, 1 reply; 13+ messages in thread
From: David Miller @ 2006-08-10 12:12 UTC (permalink / raw)
To: michal.ruzicka; +Cc: kuznet, netdev
From: Michal Ruzicka <michal.ruzicka@comstar.cz>
Date: Thu, 10 Aug 2006 14:07:06 +0200
> This patch corrects it:
Correct or not this patch is corrupted by your email client, turning
tabs into spaces among other things. This makes your patch unusable.
Please configure your email client to not mangle the text of the patch
in any way and resubmit with your original surrounding description so
that it can be properly reviewed.
If in doubt, always email the patch to yourself as a test and try to
apply that patch as if you were the person who might be integrating
your work.
Thanks a lot.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
2006-08-10 12:12 ` David Miller
@ 2006-08-10 12:13 ` David Miller
0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2006-08-10 12:13 UTC (permalink / raw)
To: michal.ruzicka; +Cc: kuznet, netdev
From: David Miller <davem@davemloft.net>
Date: Thu, 10 Aug 2006 05:12:41 -0700 (PDT)
> From: Michal Ruzicka <michal.ruzicka@comstar.cz>
> Date: Thu, 10 Aug 2006 14:07:06 +0200
>
> > This patch corrects it:
>
> Correct or not this patch is corrupted by your email client, turning
> tabs into spaces among other things. This makes your patch unusable.
And yes I do realize you created an attachment before you
bark that back. :-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
2006-08-10 12:07 ` Possible leak of multicast source filter sctructure Michal Ruzicka
2006-08-10 12:12 ` David Miller
@ 2006-08-10 18:07 ` David Stevens
1 sibling, 0 replies; 13+ messages in thread
From: David Stevens @ 2006-08-10 18:07 UTC (permalink / raw)
To: Michal Ruzicka; +Cc: davem, kuznet, netdev, netdev-owner
Michal,
This looks correct, but I think a better way to do it is:
in_dev = inetdev_by_index(...)
(void) ip_mc_leave_src()
if (in_dev) {
ip_mc_dec_group()
in_dev_put()
}
That way, sflist internal details aren't visible at this
level, and ip_mc_leave_src() collapses to the sock_kfree_s()
when in_dev is NULL.
Also, ip_mc_leave_group() has the same issue; looks
like it just needs the "if (in_dev)" removed before the call to
ip_mc_leave_src().
+-DLS
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
@ 2006-08-11 11:04 Michal Ruzicka
2006-08-14 3:44 ` David Miller
0 siblings, 1 reply; 13+ messages in thread
From: Michal Ruzicka @ 2006-08-11 11:04 UTC (permalink / raw)
To: David Stevens; +Cc: davem, kuznet, netdev, netdev-owner
> Michal,
> This looks correct, but I think a better way to do it is:
>
> in_dev = inetdev_by_index(...)
> (void) ip_mc_leave_src()
> if (in_dev) {
> ip_mc_dec_group()
> in_dev_put()
> }
>
> That way, sflist internal details aren't visible at this
> level, and ip_mc_leave_src() collapses to the sock_kfree_s()
> when in_dev is NULL.
You are absolutely right, I just failed to notice that -ENODEV return value
from ip_mc_del_src()/ip_mc_leave_src() is ignored.
Here comes the patch:
--- linux-2.6.17.8/net/ipv4/igmp.c.orig 2006-08-11 11:45:56.000000000 +0200
+++ linux-2.6.17.8/net/ipv4/igmp.c 2006-08-11 11:51:56.000000000 +0200
@@ -2202,13 +2202,13 @@
struct in_device *in_dev;
inet->mc_list = iml->next;
- if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) {
- (void) ip_mc_leave_src(sk, iml, in_dev);
+ in_dev = inetdev_by_index(iml->multi.imr_ifindex);
+ (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (in_dev != NULL) {
ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
in_dev_put(in_dev);
}
sock_kfree_s(sk, iml, sizeof(*iml));
-
}
rtnl_unlock();
}
> Also, ip_mc_leave_group() has the same issue; looks
> like it just needs the "if (in_dev)" removed before the call to
> ip_mc_leave_src().
In fact it is a slightly different issue, there is no leak in this
function. Rather the function completely fails to leave a multicast
group joined on an interface that does not exist any more. Actually
this is how I discovered the bug as I was tracking down a problem
with ripd daemon of routing software quagga which failed to join
a multicast group (with -ENOBUFS) on an interface after there were
several (20 to be precise which corresponds to the default value
[IP_MAX_MEMBERSHIPS] of sysctl_igmp_max_memberships) interfaces
added/removed.
Here comes a patch for that:
--- linux-2.6.17.8/net/ipv4/igmp.c.leak 2006-08-11 11:50:46.000000000 +0200
+++ linux-2.6.17.8/net/ipv4/igmp.c 2006-08-11 11:52:33.000000000 +0200
@@ -1799,19 +1799,15 @@
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);
+ (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (in_dev != NULL)
+ ip_mc_dec_group(in_dev, group);
rtnl_unlock();
sock_kfree_s(sk, iml, sizeof(*iml));
return 0;
> +-DLS
>
Michal
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
2006-08-11 11:04 Possible leak of multicast source filter sctructure Michal Ruzicka
@ 2006-08-14 3:44 ` David Miller
2006-08-14 22:07 ` David Stevens
0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2006-08-14 3:44 UTC (permalink / raw)
To: michal.ruzicka; +Cc: dlstevens, kuznet, netdev, netdev-owner
From: "Michal Ruzicka" <michal.ruzicka@comstar.cz>
Date: Fri, 11 Aug 2006 12:04:53 +0100
> You are absolutely right, I just failed to notice that -ENODEV return value
> from ip_mc_del_src()/ip_mc_leave_src() is ignored.
> Here comes the patch:
...
> > Also, ip_mc_leave_group() has the same issue; looks
> > like it just needs the "if (in_dev)" removed before the call to
> > ip_mc_leave_src().
>
> In fact it is a slightly different issue, there is no leak in this
> function. Rather the function completely fails to leave a multicast
> group joined on an interface that does not exist any more.
...
> Here comes a patch for that:
Both of these fixes look fine to me. David?
(Meanwhile, Michal, can I get a Signed-off-by: line from you for these
patches? Thanks a lot.)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
@ 2006-08-14 10:56 Michal Ruzicka
0 siblings, 0 replies; 13+ messages in thread
From: Michal Ruzicka @ 2006-08-14 10:56 UTC (permalink / raw)
To: David Miller; +Cc: dlstevens, kuznet, netdev, netdev-owner
Hi,
...
> (Meanwhile, Michal, can I get a Signed-off-by: line from you for these
> patches? Thanks a lot.)
no problem :-)
There is a leak of a socket's multicast source filter list structure
on closing a socket with a multicast source filter set on an interface
that does not exist any more.
This patch fixes it:
Signed-off-by: Michal Ruzicka <michal.ruzicka@comstar.cz>
--- linux-2.6.17.8/net/ipv4/igmp.c.orig 2006-08-11 11:45:56.000000000 +0200
+++ linux-2.6.17.8/net/ipv4/igmp.c 2006-08-11 11:51:56.000000000 +0200
@@ -2202,13 +2202,13 @@
struct in_device *in_dev;
inet->mc_list = iml->next;
- if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) {
- (void) ip_mc_leave_src(sk, iml, in_dev);
+ in_dev = inetdev_by_index(iml->multi.imr_ifindex);
+ (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (in_dev != NULL) {
ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
in_dev_put(in_dev);
}
sock_kfree_s(sk, iml, sizeof(*iml));
-
}
rtnl_unlock();
}
Due to a bug in IP_DROP_MEMBERSHIP setsockopt handling code it is not
possible to leave a multicast group joined on an interface that
does not exist any more.
This patch makes leaving a multicast group possible even in that case:
Signed-off-by: Michal Ruzicka <michal.ruzicka@comstar.cz>
--- linux-2.6.17.8/net/ipv4/igmp.c.leak 2006-08-11 11:50:46.000000000 +0200
+++ linux-2.6.17.8/net/ipv4/igmp.c 2006-08-11 11:52:33.000000000 +0200
@@ -1799,19 +1799,15 @@
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);
+ (void) ip_mc_leave_src(sk, iml, in_dev);
+ if (in_dev != NULL)
+ ip_mc_dec_group(in_dev, group);
rtnl_unlock();
sock_kfree_s(sk, iml, sizeof(*iml));
return 0;
Michal
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
2006-08-14 3:44 ` David Miller
@ 2006-08-14 22:07 ` David Stevens
2006-08-15 7:21 ` David Miller
0 siblings, 1 reply; 13+ messages in thread
From: David Stevens @ 2006-08-14 22:07 UTC (permalink / raw)
To: David Miller; +Cc: kuznet, michal.ruzicka, netdev, netdev-owner
netdev-owner@vger.kernel.org wrote on 08/13/2006 08:44:05 PM:
> From: "Michal Ruzicka" <michal.ruzicka@comstar.cz>
> Date: Fri, 11 Aug 2006 12:04:53 +0100
>
> > You are absolutely right, I just failed to notice that -ENODEV return
value
> > from ip_mc_del_src()/ip_mc_leave_src() is ignored.
> > Here comes the patch:
> ...
> > > Also, ip_mc_leave_group() has the same issue; looks
> > > like it just needs the "if (in_dev)" removed before the call to
> > > ip_mc_leave_src().
> >
> > In fact it is a slightly different issue, there is no leak in this
> > function. Rather the function completely fails to leave a multicast
> > group joined on an interface that does not exist any more.
> ...
> > Here comes a patch for that:
>
> Both of these fixes look fine to me. David?
The first patch in that, yes.
Acked-by: David L Stevens <dlstevens@us.ibm.com>
I'm not sure the second one is quite right. The case of concern
is where an interface is deleted. If you joined (or left) the group by
address and then deleted the interface, then you wouldn't match the
index (which wouldn't be set) so the leave wouldn't work, still.
Also, if you passed a completely bogus ifindex, it should return
ENODEV, but with the patch it would return EADDRNOTAVAIL it appears.
So, I think the second patch needs some more work. I'll look at
it some more and see if I can suggest something better.
+-DLS
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
2006-08-14 22:07 ` David Stevens
@ 2006-08-15 7:21 ` David Miller
2006-08-15 23:57 ` [PATCH] " David Stevens
0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2006-08-15 7:21 UTC (permalink / raw)
To: dlstevens; +Cc: kuznet, michal.ruzicka, netdev, netdev-owner
From: David Stevens <dlstevens@us.ibm.com>
Date: Mon, 14 Aug 2006 15:07:08 -0700
> The first patch in that, yes.
>
> Acked-by: David L Stevens <dlstevens@us.ibm.com>
I've applied it and will push to net-2.6.18
> I'm not sure the second one is quite right. The case of concern
> is where an interface is deleted. If you joined (or left) the group by
> address and then deleted the interface, then you wouldn't match the
> index (which wouldn't be set) so the leave wouldn't work, still.
> Also, if you passed a completely bogus ifindex, it should return
> ENODEV, but with the patch it would return EADDRNOTAVAIL it appears.
> So, I think the second patch needs some more work. I'll look at
> it some more and see if I can suggest something better.
Ok, this second patch does need to be refined a little bit.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] Re: Possible leak of multicast source filter sctructure
2006-08-15 7:21 ` David Miller
@ 2006-08-15 23:57 ` David Stevens
2006-08-17 23:29 ` David Miller
0 siblings, 1 reply; 13+ messages in thread
From: David Stevens @ 2006-08-15 23:57 UTC (permalink / raw)
To: David Miller; +Cc: kuznet, michal.ruzicka, netdev
[-- Attachment #1: Type: text/plain, Size: 4265 bytes --]
Here's a patch to fix source filter leakage when a device is removed
and a process leaves the group thereafter. (2nd part of prior discussion)
This patch also includes corresponding fixes for IPv6 multicast source
filters on device removal (1st & 2nd parts of prior discussion, for IPv6).
+-DLS
[in-line for viewing, attached for applying]
Signed-off-by: David L Stevens <dlstevens@us.ibm.com>
diff -ruNp linux-2.6.17.8/net/ipv4/igmp.c
linux-2.6.17.8-dls/net/ipv4/igmp.c
--- linux-2.6.17.8/net/ipv4/igmp.c 2006-08-06 21:18:54.000000000
-0700
+++ linux-2.6.17.8-dls/net/ipv4/igmp.c 2006-08-15 16:30:18.000000000
-0700
@@ -1796,29 +1796,35 @@ int ip_mc_leave_group(struct sock *sk, s
struct in_device *in_dev;
u32 group = imr->imr_multiaddr.s_addr;
u32 ifindex;
+ int ret = -EADDRNOTAVAIL;
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);
+ if (iml->multi.imr_multiaddr.s_addr != group)
+ continue;
+ if (ifindex) {
+ if (iml->multi.imr_ifindex != ifindex)
+ continue;
+ } else if (imr->imr_address.s_addr &&
imr->imr_address.s_addr !=
+ iml->multi.imr_address.s_addr)
+ continue;
+
+ (void) ip_mc_leave_src(sk, iml, in_dev);
- *imlp = iml->next;
+ *imlp = iml->next;
+ if (in_dev)
ip_mc_dec_group(in_dev, group);
- rtnl_unlock();
- sock_kfree_s(sk, iml, sizeof(*iml));
- return 0;
- }
+ rtnl_unlock();
+ sock_kfree_s(sk, iml, sizeof(*iml));
+ return 0;
}
+ if (!in_dev)
+ ret = -ENODEV;
rtnl_unlock();
- return -EADDRNOTAVAIL;
+ return ret;
}
int ip_mc_source(int add, int omode, struct sock *sk, struct
diff -ruNp linux-2.6.17.8/net/ipv6/mcast.c
linux-2.6.17.8-dls/net/ipv6/mcast.c
--- linux-2.6.17.8/net/ipv6/mcast.c 2006-08-06 21:18:54.000000000
-0700
+++ linux-2.6.17.8-dls/net/ipv6/mcast.c 2006-08-15 15:51:53.000000000
-0700
@@ -269,13 +269,14 @@ int ipv6_sock_mc_drop(struct sock *sk, i
if ((dev = dev_get_by_index(mc_lst->ifindex)) !=
NULL) {
struct inet6_dev *idev = in6_dev_get(dev);
+ (void) ip6_mc_leave_src(sk, mc_lst, idev);
if (idev) {
- (void)
ip6_mc_leave_src(sk,mc_lst,idev);
__ipv6_dev_mc_dec(idev,
&mc_lst->addr);
in6_dev_put(idev);
}
dev_put(dev);
- }
+ } else
+ (void) ip6_mc_leave_src(sk, mc_lst, NULL);
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
return 0;
}
@@ -335,13 +336,14 @@ void ipv6_sock_mc_close(struct sock *sk)
if (dev) {
struct inet6_dev *idev = in6_dev_get(dev);
+ (void) ip6_mc_leave_src(sk, mc_lst, idev);
if (idev) {
- (void) ip6_mc_leave_src(sk, mc_lst, idev);
__ipv6_dev_mc_dec(idev, &mc_lst->addr);
in6_dev_put(idev);
}
dev_put(dev);
- }
+ } else
+ (void) ip6_mc_leave_src(sk, mc_lst, NULL);
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
[-- Attachment #2: mcd.patch --]
[-- Type: application/octet-stream, Size: 2647 bytes --]
diff -ruNp linux-2.6.17.8/net/ipv4/igmp.c linux-2.6.17.8-dls/net/ipv4/igmp.c
--- linux-2.6.17.8/net/ipv4/igmp.c 2006-08-06 21:18:54.000000000 -0700
+++ linux-2.6.17.8-dls/net/ipv4/igmp.c 2006-08-15 16:30:18.000000000 -0700
@@ -1796,29 +1796,35 @@ int ip_mc_leave_group(struct sock *sk, s
struct in_device *in_dev;
u32 group = imr->imr_multiaddr.s_addr;
u32 ifindex;
+ int ret = -EADDRNOTAVAIL;
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);
+ if (iml->multi.imr_multiaddr.s_addr != group)
+ continue;
+ if (ifindex) {
+ if (iml->multi.imr_ifindex != ifindex)
+ continue;
+ } else if (imr->imr_address.s_addr && imr->imr_address.s_addr !=
+ iml->multi.imr_address.s_addr)
+ continue;
+
+ (void) ip_mc_leave_src(sk, iml, in_dev);
- *imlp = iml->next;
+ *imlp = iml->next;
+ if (in_dev)
ip_mc_dec_group(in_dev, group);
- rtnl_unlock();
- sock_kfree_s(sk, iml, sizeof(*iml));
- return 0;
- }
+ rtnl_unlock();
+ sock_kfree_s(sk, iml, sizeof(*iml));
+ return 0;
}
+ if (!in_dev)
+ ret = -ENODEV;
rtnl_unlock();
- return -EADDRNOTAVAIL;
+ return ret;
}
int ip_mc_source(int add, int omode, struct sock *sk, struct
diff -ruNp linux-2.6.17.8/net/ipv6/mcast.c linux-2.6.17.8-dls/net/ipv6/mcast.c
--- linux-2.6.17.8/net/ipv6/mcast.c 2006-08-06 21:18:54.000000000 -0700
+++ linux-2.6.17.8-dls/net/ipv6/mcast.c 2006-08-15 15:51:53.000000000 -0700
@@ -269,13 +269,14 @@ int ipv6_sock_mc_drop(struct sock *sk, i
if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) {
struct inet6_dev *idev = in6_dev_get(dev);
+ (void) ip6_mc_leave_src(sk, mc_lst, idev);
if (idev) {
- (void) ip6_mc_leave_src(sk,mc_lst,idev);
__ipv6_dev_mc_dec(idev, &mc_lst->addr);
in6_dev_put(idev);
}
dev_put(dev);
- }
+ } else
+ (void) ip6_mc_leave_src(sk, mc_lst, NULL);
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
return 0;
}
@@ -335,13 +336,14 @@ void ipv6_sock_mc_close(struct sock *sk)
if (dev) {
struct inet6_dev *idev = in6_dev_get(dev);
+ (void) ip6_mc_leave_src(sk, mc_lst, idev);
if (idev) {
- (void) ip6_mc_leave_src(sk, mc_lst, idev);
__ipv6_dev_mc_dec(idev, &mc_lst->addr);
in6_dev_put(idev);
}
dev_put(dev);
- }
+ } else
+ (void) ip6_mc_leave_src(sk, mc_lst, NULL);
sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
@ 2006-08-17 12:26 Michal Ruzicka
2006-08-17 15:26 ` David Stevens
0 siblings, 1 reply; 13+ messages in thread
From: Michal Ruzicka @ 2006-08-17 12:26 UTC (permalink / raw)
To: David Stevens; +Cc: davem, kuznet, netdev, netdev-owner
Hello David,
> Michal,
> I believe the patch I submitted yesterday fixes this
> problem, and in a simpler way.
Somehow I've missed that e-mail (It did not appear on the thread's list at MARC
archives). Sorry for that.
>
> +-DLS
I've reviewed your patch (the IPv4 part of it) and I think I can say that
our soulutions are actually quite similar.
But I can come up with one difference that I'd like know your opinion on.
Suppose the following situatuion:
1) create pppX interface:
IP: A.B.C.D
2) join a multicast group by address: A.B.C.D
ASSUMPTION: no other interface with the same IP address exists;
the result should be that the group is joined on the pppX interface
3) create pppY interface
IP: A.B.C.D (Yes the same IP, not unusual on ppp links.)
4) delete the pppX interace
5) attempt to leave the multicast group by address: A.B.C.D
6) * if your algorthim is used -EADDRNOTAVAIL is returned
* if mine is used the multicast group is left on the pppX interface
Surely this won't be a common problem but I think it's worth pointing out
here.
Michal
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Possible leak of multicast source filter sctructure
2006-08-17 12:26 Michal Ruzicka
@ 2006-08-17 15:26 ` David Stevens
0 siblings, 0 replies; 13+ messages in thread
From: David Stevens @ 2006-08-17 15:26 UTC (permalink / raw)
To: Michal Ruzicka; +Cc: davem, kuznet, netdev, netdev-owner
"Michal Ruzicka" <michal.ruzicka@comstar.cz> wrote on 08/17/2006 05:26:35
AM:
> I've reviewed your patch (the IPv4 part of it) and I think I can say
that
> our soulutions are actually quite similar.
> But I can come up with one difference that I'd like know your opinion
on.
If you have a duplicated address and the application is not using
interface index to identify the interface, then which one you join or
leave
on is not unique, and which one you'll get is not defined. It is, in fact,
an error to leave the group on an interface with a different index, and
the duplicate scenario has effectively changed the meaning of that
address's
interface.
In the same scenario, if you have not deleted any interfaces and
attempt to leave the group, your code may get the "pppY" interface from
ip_mc_find_dev(), not have a matching index for the group you actually
joined, and will return EADDRNOTAVAIL rather than leaving the group you
joined on.
In both cases, it'd simply be an error for an application to be
using address to identify the interface when that is not unique. If the
addresses are used (or reused) on multiple interfaces, the application
has to use interface index to work properly.
+-DLS
> Suppose the following situatuion:
>
> 1) create pppX interface:
> IP: A.B.C.D
>
> 2) join a multicast group by address: A.B.C.D
> ASSUMPTION: no other interface with the same IP address exists;
> the result should be that the group is joined on the pppX interface
>
> 3) create pppY interface
> IP: A.B.C.D (Yes the same IP, not unusual on ppp links.)
>
> 4) delete the pppX interace
>
> 5) attempt to leave the multicast group by address: A.B.C.D
>
> 6) * if your algorthim is used -EADDRNOTAVAIL is returned
> * if mine is used the multicast group is left on the pppX interface
>
> Surely this won't be a common problem but I think it's worth pointing
out
> here.
>
> Michal
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Re: Possible leak of multicast source filter sctructure
2006-08-15 23:57 ` [PATCH] " David Stevens
@ 2006-08-17 23:29 ` David Miller
0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2006-08-17 23:29 UTC (permalink / raw)
To: dlstevens; +Cc: kuznet, michal.ruzicka, netdev
From: David Stevens <dlstevens@us.ibm.com>
Date: Tue, 15 Aug 2006 17:57:58 -0600
> Here's a patch to fix source filter leakage when a device is removed
> and a process leaves the group thereafter. (2nd part of prior discussion)
>
> This patch also includes corresponding fixes for IPv6 multicast source
> filters on device removal (1st & 2nd parts of prior discussion, for IPv6).
>
> Signed-off-by: David L Stevens <dlstevens@us.ibm.com>
Patch applied, thanks David.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2006-08-17 23:29 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-11 11:04 Possible leak of multicast source filter sctructure Michal Ruzicka
2006-08-14 3:44 ` David Miller
2006-08-14 22:07 ` David Stevens
2006-08-15 7:21 ` David Miller
2006-08-15 23:57 ` [PATCH] " David Stevens
2006-08-17 23:29 ` David Miller
-- strict thread matches above, loose matches on Subject: below --
2006-08-17 12:26 Michal Ruzicka
2006-08-17 15:26 ` David Stevens
2006-08-14 10:56 Michal Ruzicka
2006-08-09 10:56 [RFC] [GIT PATCH] IPv6 Routing / Ndisc Fixes YOSHIFUJI Hideaki / 吉藤英明
[not found] ` <44D9D431.10101@tcs.hut.fi>
2006-08-09 21:37 ` Ville Nuorvala
2006-08-10 8:46 ` YOSHIFUJI Hideaki / 吉藤英明
2006-08-10 10:20 ` Ville Nuorvala
2006-08-10 12:07 ` Possible leak of multicast source filter sctructure Michal Ruzicka
2006-08-10 12:12 ` David Miller
2006-08-10 12:13 ` David Miller
2006-08-10 18:07 ` David Stevens
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).