diff options
author | Taehee Yoo <ap420073@gmail.com> | 2019-11-21 12:26:45 +0000 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-11-22 13:36:25 +0100 |
commit | bc71d8b580ba81b55b6e15b1c0320632515b4bac (patch) | |
tree | 4c4756b2651e1108e2d9391fd52ed7887b575c9f /drivers/net/wireless/virt_wifi.c | |
parent | 08a5bdde3812993cb8eb7aa9124703df0de28e4b (diff) | |
download | linux-bc71d8b580ba81b55b6e15b1c0320632515b4bac.tar.gz linux-bc71d8b580ba81b55b6e15b1c0320632515b4bac.tar.bz2 linux-bc71d8b580ba81b55b6e15b1c0320632515b4bac.zip |
virt_wifi: fix use-after-free in virt_wifi_newlink()
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: c7cdba31ed8b ("mac80211-next: rtnetlink wifi simulation device")
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
Link: https://lore.kernel.org/r/20191121122645.9355-1-ap420073@gmail.com
[trim stack dump a bit]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/virt_wifi.c')
-rw-r--r-- | drivers/net/wireless/virt_wifi.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/wireless/virt_wifi.c b/drivers/net/wireless/virt_wifi.c index 7997cc6de334..01305ba2d3aa 100644 --- a/drivers/net/wireless/virt_wifi.c +++ b/drivers/net/wireless/virt_wifi.c @@ -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; |