| From foo@baz Wed Sep 30 05:25:07 CEST 2015 |
| From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue> |
| Date: Fri, 11 Sep 2015 18:39:48 +0200 |
| Subject: bridge: fix igmpv3 / mldv2 report parsing |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@c0d3.blue> |
| |
| [ Upstream commit c2d4fbd2163e607915cc05798ce7fb7f31117cc1 ] |
| |
| With the newly introduced helper functions the skb pulling is hidden in |
| the checksumming function - and undone before returning to the caller. |
| |
| The IGMPv3 and MLDv2 report parsing functions in the bridge still |
| assumed that the skb is pointing to the beginning of the IGMP/MLD |
| message while it is now kept at the beginning of the IPv4/6 header, |
| breaking the message parsing and creating packet loss. |
| |
| Fixing this by taking the offset between IP and IGMP/MLD header into |
| account, too. |
| |
| Fixes: 9afd85c9e455 ("net: Export IGMP/MLD message validation code") |
| Reported-by: Tobias Powalowski <tobias.powalowski@googlemail.com> |
| Tested-by: Tobias Powalowski <tobias.powalowski@googlemail.com> |
| Signed-off-by: Linus LΓΌssing <linus.luessing@c0d3.blue> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/bridge/br_multicast.c | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/net/bridge/br_multicast.c |
| +++ b/net/bridge/br_multicast.c |
| @@ -991,7 +991,7 @@ static int br_ip4_multicast_igmp3_report |
| |
| ih = igmpv3_report_hdr(skb); |
| num = ntohs(ih->ngrec); |
| - len = sizeof(*ih); |
| + len = skb_transport_offset(skb) + sizeof(*ih); |
| |
| for (i = 0; i < num; i++) { |
| len += sizeof(*grec); |
| @@ -1052,7 +1052,7 @@ static int br_ip6_multicast_mld2_report( |
| |
| icmp6h = icmp6_hdr(skb); |
| num = ntohs(icmp6h->icmp6_dataun.un_data16[1]); |
| - len = sizeof(*icmp6h); |
| + len = skb_transport_offset(skb) + sizeof(*icmp6h); |
| |
| for (i = 0; i < num; i++) { |
| __be16 *nsrcs, _nsrcs; |