Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c511058f authored by Taehee Yoo's avatar Taehee Yoo Committed by Greg Kroah-Hartman
Browse files

virt_wifi: fix use-after-free in virt_wifi_newlink()



commit bc71d8b580ba81b55b6e15b1c0320632515b4bac upstream.

When virt_wifi interface is created, virt_wifi_newlink() is called and
it calls register_netdevice().
if register_netdevice() fails, it internally would call
->priv_destructor(), which is virt_wifi_net_device_destructor() and
it frees netdev. but virt_wifi_newlink() still use netdev.
So, use-after-free would occur in virt_wifi_newlink().

Test commands:
    ip link add dummy0 type dummy
    modprobe bonding
    ip link add bonding_masters link dummy0 type virt_wifi

Splat looks like:
[  202.220554] BUG: KASAN: use-after-free in virt_wifi_newlink+0x88b/0x9a0 [virt_wifi]
[  202.221659] Read of size 8 at addr ffff888061629cb8 by task ip/852

[  202.222896] CPU: 1 PID: 852 Comm: ip Not tainted 5.4.0-rc5 #3
[  202.223765] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[  202.225073] Call Trace:
[  202.225532]  dump_stack+0x7c/0xbb
[  202.226869]  print_address_description.constprop.5+0x1be/0x360
[  202.229362]  __kasan_report+0x12a/0x16f
[  202.230714]  kasan_report+0xe/0x20
[  202.232595]  virt_wifi_newlink+0x88b/0x9a0 [virt_wifi]
[  202.233370]  __rtnl_newlink+0xb9f/0x11b0
[  202.244909]  rtnl_newlink+0x65/0x90
[ ... ]

Cc: stable@vger.kernel.org
Fixes: c7cdba31 ("mac80211-next: rtnetlink wifi simulation device")
Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
Link: https://lore.kernel.org/r/20191121122645.9355-1-ap420073@gmail.com


[trim stack dump a bit]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b0adf9e2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -450,7 +450,6 @@ static void virt_wifi_net_device_destructor(struct net_device *dev)
	 */
	kfree(dev->ieee80211_ptr);
	dev->ieee80211_ptr = NULL;
	free_netdev(dev);
}

/* No lock interaction. */
@@ -458,7 +457,7 @@ static void virt_wifi_setup(struct net_device *dev)
{
	ether_setup(dev);
	dev->netdev_ops = &virt_wifi_ops;
	dev->priv_destructor = virt_wifi_net_device_destructor;
	dev->needs_free_netdev  = true;
}

/* Called in a RCU read critical section from netif_receive_skb */
@@ -544,6 +543,7 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
		goto unregister_netdev;
	}

	dev->priv_destructor = virt_wifi_net_device_destructor;
	priv->being_deleted = false;
	priv->is_connected = false;
	priv->is_up = false;