linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check
@ 2020-07-05 18:22 Linus Lüssing
  2020-07-05 18:33 ` Nikolay Aleksandrov
  0 siblings, 1 reply; 7+ messages in thread
From: Linus Lüssing @ 2020-07-05 18:22 UTC (permalink / raw)
  To: netdev
  Cc: Roopa Prabhu, Nikolay Aleksandrov, Martin Weinelt,
	David S . Miller, bridge, linux-kernel, Linus Lüssing

Commit e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in
igmp3/mld2 report handling") introduced a small bug which would potentially
lead to accepting an MLD2 Report with a broken IPv6 header payload length
field.

The check needs to take into account the 2 bytes for the "Number of
Sources" field in the "Multicast Address Record" before reading it.
And not the size of a pointer to this field.

Fixes: e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling")
Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
---
 net/bridge/br_multicast.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 83490bf73a13..4c4a93abde68 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1000,21 +1000,21 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
 	num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
 	len = skb_transport_offset(skb) + sizeof(*icmp6h);
 
 	for (i = 0; i < num; i++) {
 		__be16 *_nsrcs, __nsrcs;
 		u16 nsrcs;
 
 		nsrcs_offset = len + offsetof(struct mld2_grec, grec_nsrcs);
 
 		if (skb_transport_offset(skb) + ipv6_transport_len(skb) <
-		    nsrcs_offset + sizeof(_nsrcs))
+		    nsrcs_offset + sizeof(__nsrcs))
 			return -EINVAL;
 
 		_nsrcs = skb_header_pointer(skb, nsrcs_offset,
 					    sizeof(__nsrcs), &__nsrcs);
 		if (!_nsrcs)
 			return -EINVAL;
 
 		nsrcs = ntohs(*_nsrcs);
 		grec_len = struct_size(grec, grec_src, nsrcs);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check
  2020-07-05 18:22 [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check Linus Lüssing
@ 2020-07-05 18:33 ` Nikolay Aleksandrov
  2020-07-05 19:08   ` Linus Lüssing
  0 siblings, 1 reply; 7+ messages in thread
From: Nikolay Aleksandrov @ 2020-07-05 18:33 UTC (permalink / raw)
  To: Linus Lüssing, netdev
  Cc: Roopa Prabhu, Martin Weinelt, David S . Miller, bridge, linux-kernel

On 05/07/2020 21:22, Linus Lüssing wrote:
> Commit e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in
> igmp3/mld2 report handling") introduced a small bug which would potentially
> lead to accepting an MLD2 Report with a broken IPv6 header payload length
> field.
> 
> The check needs to take into account the 2 bytes for the "Number of
> Sources" field in the "Multicast Address Record" before reading it.
> And not the size of a pointer to this field.
> 
> Fixes: e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling")
> Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
> ---
>  net/bridge/br_multicast.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

I'd rather be more concerned with it rejecting a valid report due to wrong size. The ptr
size would always be bigger. :)

Thanks!
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>

> diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
> index 83490bf73a13..4c4a93abde68 100644
> --- a/net/bridge/br_multicast.c
> +++ b/net/bridge/br_multicast.c
> @@ -1000,21 +1000,21 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
>  	num = ntohs(icmp6h->icmp6_dataun.un_data16[1]);
>  	len = skb_transport_offset(skb) + sizeof(*icmp6h);
>  
>  	for (i = 0; i < num; i++) {
>  		__be16 *_nsrcs, __nsrcs;
>  		u16 nsrcs;
>  
>  		nsrcs_offset = len + offsetof(struct mld2_grec, grec_nsrcs);
>  
>  		if (skb_transport_offset(skb) + ipv6_transport_len(skb) <
> -		    nsrcs_offset + sizeof(_nsrcs))
> +		    nsrcs_offset + sizeof(__nsrcs))
>  			return -EINVAL;
>  
>  		_nsrcs = skb_header_pointer(skb, nsrcs_offset,
>  					    sizeof(__nsrcs), &__nsrcs);
>  		if (!_nsrcs)
>  			return -EINVAL;
>  
>  		nsrcs = ntohs(*_nsrcs);
>  		grec_len = struct_size(grec, grec_src, nsrcs);
>  
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check
  2020-07-05 18:33 ` Nikolay Aleksandrov
@ 2020-07-05 19:08   ` Linus Lüssing
  2020-07-05 19:11     ` Nikolay Aleksandrov
  0 siblings, 1 reply; 7+ messages in thread
From: Linus Lüssing @ 2020-07-05 19:08 UTC (permalink / raw)
  To: Nikolay Aleksandrov
  Cc: netdev, Roopa Prabhu, Martin Weinelt, David S . Miller, bridge,
	linux-kernel

On Sun, Jul 05, 2020 at 09:33:13PM +0300, Nikolay Aleksandrov wrote:
> On 05/07/2020 21:22, Linus Lüssing wrote:
> > Commit e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in
> > igmp3/mld2 report handling") introduced a small bug which would potentially
> > lead to accepting an MLD2 Report with a broken IPv6 header payload length
> > field.
> > 
> > The check needs to take into account the 2 bytes for the "Number of
> > Sources" field in the "Multicast Address Record" before reading it.
> > And not the size of a pointer to this field.
> > 
> > Fixes: e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling")
> > Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
> > ---
> >  net/bridge/br_multicast.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> 
> I'd rather be more concerned with it rejecting a valid report due to wrong size. The ptr
> size would always be bigger. :)
> 
> Thanks!
> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>

Aiy, you're right, it's the other way round. I'll update the
commit message and send a v2 in a minute, with your Acked-by
included.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check
  2020-07-05 19:08   ` Linus Lüssing
@ 2020-07-05 19:11     ` Nikolay Aleksandrov
  2020-07-05 19:49       ` Linus Lüssing
  0 siblings, 1 reply; 7+ messages in thread
From: Nikolay Aleksandrov @ 2020-07-05 19:11 UTC (permalink / raw)
  To: Linus Lüssing
  Cc: netdev, Roopa Prabhu, Martin Weinelt, David S . Miller, bridge,
	linux-kernel

On 7/5/20 10:08 PM, Linus Lüssing wrote:
> On Sun, Jul 05, 2020 at 09:33:13PM +0300, Nikolay Aleksandrov wrote:
>> On 05/07/2020 21:22, Linus Lüssing wrote:
>>> Commit e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in
>>> igmp3/mld2 report handling") introduced a small bug which would potentially
>>> lead to accepting an MLD2 Report with a broken IPv6 header payload length
>>> field.
>>>
>>> The check needs to take into account the 2 bytes for the "Number of
>>> Sources" field in the "Multicast Address Record" before reading it.
>>> And not the size of a pointer to this field.
>>>
>>> Fixes: e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling")
>>> Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
>>> ---
>>>   net/bridge/br_multicast.c | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>
>> I'd rather be more concerned with it rejecting a valid report due to wrong size. The ptr
>> size would always be bigger. :)
>>
>> Thanks!
>> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> 
> Aiy, you're right, it's the other way round. I'll update the
> commit message and send a v2 in a minute, with your Acked-by
> included.
> 

By the way, I can't verify at the moment, but I think we can drop that whole
hunk altogether since skb_header_pointer() is used and it will simply return
an error if there isn't enough data for nsrcs.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check
  2020-07-05 19:11     ` Nikolay Aleksandrov
@ 2020-07-05 19:49       ` Linus Lüssing
  2020-07-05 20:18         ` Nikolay Aleksandrov
  0 siblings, 1 reply; 7+ messages in thread
From: Linus Lüssing @ 2020-07-05 19:49 UTC (permalink / raw)
  To: Nikolay Aleksandrov
  Cc: netdev, Roopa Prabhu, Martin Weinelt, David S . Miller, bridge,
	linux-kernel

On Sun, Jul 05, 2020 at 10:11:39PM +0300, Nikolay Aleksandrov wrote:
> On 7/5/20 10:08 PM, Linus Lüssing wrote:
> > On Sun, Jul 05, 2020 at 09:33:13PM +0300, Nikolay Aleksandrov wrote:
> > > On 05/07/2020 21:22, Linus Lüssing wrote:
> > > > Commit e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in
> > > > igmp3/mld2 report handling") introduced a small bug which would potentially
> > > > lead to accepting an MLD2 Report with a broken IPv6 header payload length
> > > > field.
> > > > 
> > > > The check needs to take into account the 2 bytes for the "Number of
> > > > Sources" field in the "Multicast Address Record" before reading it.
> > > > And not the size of a pointer to this field.
> > > > 
> > > > Fixes: e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling")
> > > > Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
> > > > ---
> > > >   net/bridge/br_multicast.c | 2 +-
> > > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > 
> > > I'd rather be more concerned with it rejecting a valid report due to wrong size. The ptr
> > > size would always be bigger. :)
> > > 
> > > Thanks!
> > > Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
> > 
> > Aiy, you're right, it's the other way round. I'll update the
> > commit message and send a v2 in a minute, with your Acked-by
> > included.
> > 
> 
> By the way, I can't verify at the moment, but I think we can drop that whole
> hunk altogether since skb_header_pointer() is used and it will simply return
> an error if there isn't enough data for nsrcs.
> 

Hm, while unlikely, the IPv6 packet / header payload length might be
shorter than the frame / skb size.

And even though it wouldn't crash reading over the IPv6 packet
length, especially as skb_header_pointer() is used, I think we should
still avoid reading over the size indicated by the IPv6 header payload
length field, to stay protocol compliant.

Does that make sense?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check
  2020-07-05 19:49       ` Linus Lüssing
@ 2020-07-05 20:18         ` Nikolay Aleksandrov
  2020-07-06 10:13           ` Linus Lüssing
  0 siblings, 1 reply; 7+ messages in thread
From: Nikolay Aleksandrov @ 2020-07-05 20:18 UTC (permalink / raw)
  To: Linus Lüssing
  Cc: netdev, Roopa Prabhu, Martin Weinelt, David S . Miller, bridge,
	linux-kernel

On 7/5/20 10:49 PM, Linus Lüssing wrote:
> On Sun, Jul 05, 2020 at 10:11:39PM +0300, Nikolay Aleksandrov wrote:
>> On 7/5/20 10:08 PM, Linus Lüssing wrote:
>>> On Sun, Jul 05, 2020 at 09:33:13PM +0300, Nikolay Aleksandrov wrote:
>>>> On 05/07/2020 21:22, Linus Lüssing wrote:
>>>>> Commit e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in
>>>>> igmp3/mld2 report handling") introduced a small bug which would potentially
>>>>> lead to accepting an MLD2 Report with a broken IPv6 header payload length
>>>>> field.
>>>>>
>>>>> The check needs to take into account the 2 bytes for the "Number of
>>>>> Sources" field in the "Multicast Address Record" before reading it.
>>>>> And not the size of a pointer to this field.
>>>>>
>>>>> Fixes: e57f61858b7c ("net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling")
>>>>> Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
>>>>> ---
>>>>>    net/bridge/br_multicast.c | 2 +-
>>>>>    1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>
>>>>
>>>> I'd rather be more concerned with it rejecting a valid report due to wrong size. The ptr
>>>> size would always be bigger. :)
>>>>
>>>> Thanks!
>>>> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
>>>
>>> Aiy, you're right, it's the other way round. I'll update the
>>> commit message and send a v2 in a minute, with your Acked-by
>>> included.
>>>
>>
>> By the way, I can't verify at the moment, but I think we can drop that whole
>> hunk altogether since skb_header_pointer() is used and it will simply return
>> an error if there isn't enough data for nsrcs.
>>
> 
> Hm, while unlikely, the IPv6 packet / header payload length might be
> shorter than the frame / skb size.
> 
> And even though it wouldn't crash reading over the IPv6 packet
> length, especially as skb_header_pointer() is used, I think we should
> still avoid reading over the size indicated by the IPv6 header payload
> length field, to stay protocol compliant.
> 
> Does that make sense?
> 

Sure, I just thought the ipv6_mc_may_pull() call after that includes those 2 bytes as well, so
we're covered. That is, it seems to be doing the same check with the full grec size included.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check
  2020-07-05 20:18         ` Nikolay Aleksandrov
@ 2020-07-06 10:13           ` Linus Lüssing
  0 siblings, 0 replies; 7+ messages in thread
From: Linus Lüssing @ 2020-07-06 10:13 UTC (permalink / raw)
  To: Nikolay Aleksandrov
  Cc: netdev, Roopa Prabhu, Martin Weinelt, David S . Miller, bridge,
	linux-kernel

On Sun, Jul 05, 2020 at 11:18:36PM +0300, Nikolay Aleksandrov wrote:
> > > By the way, I can't verify at the moment, but I think we can drop that whole
> > > hunk altogether since skb_header_pointer() is used and it will simply return
> > > an error if there isn't enough data for nsrcs.
> > > 
> > 
> > Hm, while unlikely, the IPv6 packet / header payload length might be
> > shorter than the frame / skb size.
> > 
> > And even though it wouldn't crash reading over the IPv6 packet
> > length, especially as skb_header_pointer() is used, I think we should
> > still avoid reading over the size indicated by the IPv6 header payload
> > length field, to stay protocol compliant.
> > 
> > Does that make sense?
> > 
> 
> Sure, I just thought the ipv6_mc_may_pull() call after that includes those 2 bytes as well, so
> we're covered. That is, it seems to be doing the same check with the full grec size included.
> 

Ah, okay, that's what you mean! You're right, technically the
ipv6_mc_may_pull() later would cover it, too. And it should work,
even if nsrcs were outside of the IPv6 packet and had a bogus
value. (I think.)

My brain linearly parsing the parser code would probably get a bit
confused initially, as it'd look like a bit like a bug. But the
current check for nsrcs might look confusing, too (q.e.d.).

So as you prefer, I'd be okay with both leaving that check for
consistency or removing it for brevity.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-07-06 10:13 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-05 18:22 [PATCH net] bridge: mcast: Fix MLD2 Report IPv6 payload length check Linus Lüssing
2020-07-05 18:33 ` Nikolay Aleksandrov
2020-07-05 19:08   ` Linus Lüssing
2020-07-05 19:11     ` Nikolay Aleksandrov
2020-07-05 19:49       ` Linus Lüssing
2020-07-05 20:18         ` Nikolay Aleksandrov
2020-07-06 10:13           ` Linus Lüssing

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).