aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChris Wright <chrisw@osdl.org>2004-12-13 19:06:25 -0800
committerDavid S. Miller <davem@nuts.davemloft.net>2004-12-13 19:06:25 -0800
commitc1e98f7df57332a0669d44d82292c064a99b995d (patch)
tree5bf077ba57fbb34467db4d9f033d08143ff45d1a /net
parent66e57dd8c12bffb295dde24b38a108cb19d01041 (diff)
downloadhistory-c1e98f7df57332a0669d44d82292c064a99b995d.tar.gz
[IPV4/IPV6]: IGMP source filter fixes
When adding or deleting from the source list make sure to find matches by comparing against the new source address, not the group address. Also, check each addr in the list rather than just the first one. And, finally, only delete from list when there's a match rather than vice-versa. Drop the effort to keep list sorted, since it's not done on full-state api and can create an sl_addr entry that the delta api won't be able to delete. Without these fixes sl_count can be corrupted which can allow for kernel memory corruption. Signed-off-by: Chris Wright <chrisw@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/igmp.c10
-rw-r--r--net/ipv6/mcast.c10
2 files changed, 10 insertions, 10 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 312186eb610017..fc0c27f25f6aad 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1778,12 +1778,12 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
goto done;
rv = !0;
for (i=0; i<psl->sl_count; i++) {
- rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr,
+ rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
sizeof(__u32));
- if (rv >= 0)
+ if (rv == 0)
break;
}
- if (!rv) /* source not found */
+ if (rv) /* source not found */
goto done;
/* update the interface filter */
@@ -1825,9 +1825,9 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
}
rv = 1; /* > 0 for insert logic below if sl_count is 0 */
for (i=0; i<psl->sl_count; i++) {
- rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr,
+ rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
sizeof(__u32));
- if (rv >= 0)
+ if (rv == 0)
break;
}
if (rv == 0) /* address already there is an error */
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index b3243770978f37..2cd84b9f96d93d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -391,12 +391,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
goto done;
rv = !0;
for (i=0; i<psl->sl_count; i++) {
- rv = memcmp(&psl->sl_addr, group,
+ rv = memcmp(&psl->sl_addr[i], source,
sizeof(struct in6_addr));
- if (rv >= 0)
+ if (rv == 0)
break;
}
- if (!rv) /* source not found */
+ if (rv) /* source not found */
goto done;
/* update the interface filter */
@@ -437,8 +437,8 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
}
rv = 1; /* > 0 for insert logic below if sl_count is 0 */
for (i=0; i<psl->sl_count; i++) {
- rv = memcmp(&psl->sl_addr, group, sizeof(struct in6_addr));
- if (rv >= 0)
+ rv = memcmp(&psl->sl_addr[i], source, sizeof(struct in6_addr));
+ if (rv == 0)
break;
}
if (rv == 0) /* address already there is an error */