[IGMP]: workaround for IGMP v1/v2 bug

From: David Stevens <dlstevens@us.ibm.com>

As explained at:

http://www.cs.ucsb.edu/~krishna/igmp_dos/

With IGMP version 1 and 2 it is possible to inject a unicast
report to a client which will make it ignore multicast
reports sent later by the router.

The fix is to only accept the report if is was sent to a
multicast or unicast address.

Signed-off-by: David S. Miller <davem@davemloft.net>

authored by David Stevens and committed by David S. Miller 24c69275 bf031fff

+9 -1
+4 -1
net/ipv4/igmp.c
··· 897 /* Is it our report looped back? */ 898 if (((struct rtable*)skb->dst)->fl.iif == 0) 899 break; 900 - igmp_heard_report(in_dev, ih->group); 901 break; 902 case IGMP_PIM: 903 #ifdef CONFIG_IP_PIMSM_V1
··· 897 /* Is it our report looped back? */ 898 if (((struct rtable*)skb->dst)->fl.iif == 0) 899 break; 900 + /* don't rely on MC router hearing unicast reports */ 901 + if (skb->pkt_type == PACKET_MULTICAST || 902 + skb->pkt_type == PACKET_BROADCAST) 903 + igmp_heard_report(in_dev, ih->group); 904 break; 905 case IGMP_PIM: 906 #ifdef CONFIG_IP_PIMSM_V1
+5
net/ipv6/mcast.c
··· 1231 if (skb->pkt_type == PACKET_LOOPBACK) 1232 return 0; 1233 1234 if (!pskb_may_pull(skb, sizeof(struct in6_addr))) 1235 return -EINVAL; 1236
··· 1231 if (skb->pkt_type == PACKET_LOOPBACK) 1232 return 0; 1233 1234 + /* send our report if the MC router may not have heard this report */ 1235 + if (skb->pkt_type != PACKET_MULTICAST && 1236 + skb->pkt_type != PACKET_BROADCAST) 1237 + return 0; 1238 + 1239 if (!pskb_may_pull(skb, sizeof(struct in6_addr))) 1240 return -EINVAL; 1241