lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <Z74cbT8aNIPn__FF@shredder>
Date: Tue, 25 Feb 2025 21:39:25 +0200
From: Ido Schimmel <idosch@...sch.org>
To: Oscar Maes <oscmaes92@...il.com>
Cc: netdev@...r.kernel.org, davem@...emloft.net, edumazet@...gle.com,
	kuba@...nel.org, pabeni@...hat.com, horms@...nel.org,
	viro@...iv.linux.org.uk, jiri@...nulli.us,
	linux-kernel@...r.kernel.org, security@...nel.org,
	syzbot <syzbot+91161fe81857b396c8a0@...kaller.appspotmail.com>
Subject: Re: [PATCH net] net: 802: enforce underlying device type for GARP
 and MRP

On Tue, Feb 25, 2025 at 03:11:57PM +0100, Oscar Maes wrote:
> On Wed, Feb 12, 2025 at 04:29:43PM +0200, Ido Schimmel wrote:
> > On Wed, Feb 12, 2025 at 12:32:18PM +0100, Oscar Maes wrote:
> > > When creating a VLAN device, we initialize GARP (garp_init_applicant)
> > > and MRP (mrp_init_applicant) for the underlying device.
> > > 
> > > As part of the initialization process, we add the multicast address of
> > > each applicant to the underlying device, by calling dev_mc_add.
> > > 
> > > __dev_mc_add uses dev->addr_len to determine the length of the new
> > > multicast address.
> > > 
> > > This causes an out-of-bounds read if dev->addr_len is greater than 6,
> > > since the multicast addresses provided by GARP and MRP are only 6 bytes
> > > long.
> > > 
> > > This behaviour can be reproduced using the following commands:
> > > 
> > > ip tunnel add gretest mode ip6gre local ::1 remote ::2 dev lo
> > > ip l set up dev gretest
> > > ip link add link gretest name vlantest type vlan id 100
> > > 
> > > Then, the following command will display the address of garp_pdu_rcv:
> > > 
> > > ip maddr show | grep 01:80:c2:00:00:21
> > > 
> > > Fix this by enforcing the type and address length of
> > > the underlying device during GARP and MRP initialization.
> > > 
> > > Fixes: 22bedad3ce11 ("net: convert multicast list to list_head")
> > > Reported-by: syzbot <syzbot+91161fe81857b396c8a0@...kaller.appspotmail.com>
> > > Closes: https://lore.kernel.org/netdev/000000000000ca9a81061a01ec20@google.com/
> > > Signed-off-by: Oscar Maes <oscmaes92@...il.com>
> > > ---
> > >  net/802/garp.c | 5 +++++
> > >  net/802/mrp.c  | 5 +++++
> > >  2 files changed, 10 insertions(+)
> > > 
> > > diff --git a/net/802/garp.c b/net/802/garp.c
> > > index 27f0ab146..2f383ee73 100644
> > > --- a/net/802/garp.c
> > > +++ b/net/802/garp.c
> > > @@ -9,6 +9,7 @@
> > >  #include <linux/skbuff.h>
> > >  #include <linux/netdevice.h>
> > >  #include <linux/etherdevice.h>
> > > +#include <linux/if_arp.h>
> > >  #include <linux/rtnetlink.h>
> > >  #include <linux/llc.h>
> > >  #include <linux/slab.h>
> > > @@ -574,6 +575,10 @@ int garp_init_applicant(struct net_device *dev, struct garp_application *appl)
> > >  
> > >  	ASSERT_RTNL();
> > >  
> > > +	err = -EINVAL;
> > > +	if (dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN)
> > 
> > Checking for 'ARPHRD_ETHER' is not enough? Other virtual devices such as
> > macsec, macvlan and ipvlan only look at 'dev->type' AFAICT.
> 
> Agreed, I will change this.
> 
> > 
> > Also, how about moving this to vlan_check_real_dev()? It's common to
> > both the IOCTL and netlink paths.
> 
> {garp,mrp}_init_applicant assume that the address length is 6-bytes, when they call dev_mc_add
> with a 6-byte buffer.
> I think that the ARPHRD check should be right before calling dev_mc_add.
> 
> Currently, GARP is only used by VLAN, which means your suggestion would technically work,
> but this assumption might be violated by future protocol implementations like GMRP, which
> could potentially resurface this bug.

I disagree. The problem is in the caller (the VLAN driver). It should
explicitly check for the error condition (real device not being
Ethernet) and bail out as soon as possible (in vlan_check_real_dev())
with an appropriate error message. It should not rely on the first
function where this error condition happened to explode to do the
verification, especially when this function can be compiled out (e.g.,
CONFIG_VLAN_8021Q_GVRP=n).

> 
> > 
> > > +		goto err1;
> > > +
> > >  	if (!rtnl_dereference(dev->garp_port)) {
> > >  		err = garp_init_port(dev);
> > >  		if (err < 0)
> > > diff --git a/net/802/mrp.c b/net/802/mrp.c
> > > index e0c96d0da..1efee0b39 100644
> > > --- a/net/802/mrp.c
> > > +++ b/net/802/mrp.c
> > > @@ -12,6 +12,7 @@
> > >  #include <linux/skbuff.h>
> > >  #include <linux/netdevice.h>
> > >  #include <linux/etherdevice.h>
> > > +#include <linux/if_arp.h>
> > >  #include <linux/rtnetlink.h>
> > >  #include <linux/slab.h>
> > >  #include <linux/module.h>
> > > @@ -859,6 +860,10 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
> > >  
> > >  	ASSERT_RTNL();
> > >  
> > > +	err = -EINVAL;
> > > +	if (dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN)
> > > +		goto err1;
> > > +
> > >  	if (!rtnl_dereference(dev->mrp_port)) {
> > >  		err = mrp_init_port(dev);
> > >  		if (err < 0)
> > > -- 
> > > 2.39.5
> > > 
> > > 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ