]> git.neil.brown.name Git - history.git/commitdiff
[IPV4/IPV6]: IGMP source filter fixes
authorChris Wright <chrisw@osdl.org>
Tue, 14 Dec 2004 03:06:25 +0000 (19:06 -0800)
committerDavid S. Miller <davem@nuts.davemloft.net>
Tue, 14 Dec 2004 03:06:25 +0000 (19:06 -0800)
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>
net/ipv4/igmp.c
net/ipv6/mcast.c

index 312186eb610017d301c1a56c61eaa2f713a7acab..fc0c27f25f6aad7a2d833b92a98a3d32673138eb 100644 (file)
@@ -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 */
index b3243770978f379a6a7cc28eda046c2bbdd3b54f..2cd84b9f96d93d9838dd63df23a46c318d736c06 100644 (file)
@@ -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 */