Message ID | 20210617185130.5834-1-paskripkin@gmail.com |
---|---|
State | New |
Headers | show |
Series | net: can: fix use-after-free in ems_usb_disconnect | expand |
On 17.06.2021 21:51:30, Pavel Skripkin wrote: > In ems_usb_disconnect() dev pointer, which is > netdev private data, is used after free_candev() call: > > if (dev) { > unregister_netdev(dev->netdev); > free_candev(dev->netdev); > > unlink_all_urbs(dev); > > usb_free_urb(dev->intr_urb); > > kfree(dev->intr_in_buffer); > kfree(dev->tx_msg_buffer); > } > > Fix it by simply moving free_candev() at the end of > the block. > > Fail log: > BUG: KASAN: use-after-free in ems_usb_disconnect > Read of size 8 at addr ffff88804e041008 by task kworker/1:2/2895 > > CPU: 1 PID: 2895 Comm: kworker/1:2 Not tainted 5.13.0-rc5+ #164 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.4 > Workqueue: usb_hub_wq hub_event > Call Trace: > dump_stack (lib/dump_stack.c:122) > print_address_description.constprop.0.cold (mm/kasan/report.c:234) > kasan_report.cold (mm/kasan/report.c:420 mm/kasan/report.c:436) > ems_usb_disconnect (drivers/net/can/usb/ems_usb.c:683 drivers/net/can/usb/ems_usb.c:1058) > > Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface") > Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> Applied to linux-can/testing and added stable on Cc. Thanks, Marc -- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 5af69787d9d5..0a37af4a3fa4 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -1053,7 +1053,6 @@ static void ems_usb_disconnect(struct usb_interface *intf) if (dev) { unregister_netdev(dev->netdev); - free_candev(dev->netdev); unlink_all_urbs(dev); @@ -1061,6 +1060,8 @@ static void ems_usb_disconnect(struct usb_interface *intf) kfree(dev->intr_in_buffer); kfree(dev->tx_msg_buffer); + + free_candev(dev->netdev); } }
In ems_usb_disconnect() dev pointer, which is netdev private data, is used after free_candev() call: if (dev) { unregister_netdev(dev->netdev); free_candev(dev->netdev); unlink_all_urbs(dev); usb_free_urb(dev->intr_urb); kfree(dev->intr_in_buffer); kfree(dev->tx_msg_buffer); } Fix it by simply moving free_candev() at the end of the block. Fail log: BUG: KASAN: use-after-free in ems_usb_disconnect Read of size 8 at addr ffff88804e041008 by task kworker/1:2/2895 CPU: 1 PID: 2895 Comm: kworker/1:2 Not tainted 5.13.0-rc5+ #164 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.4 Workqueue: usb_hub_wq hub_event Call Trace: dump_stack (lib/dump_stack.c:122) print_address_description.constprop.0.cold (mm/kasan/report.c:234) kasan_report.cold (mm/kasan/report.c:420 mm/kasan/report.c:436) ems_usb_disconnect (drivers/net/can/usb/ems_usb.c:683 drivers/net/can/usb/ems_usb.c:1058) Fixes: 702171adeed3 ("ems_usb: Added support for EMS CPC-USB/ARM7 CAN/USB interface") Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> --- drivers/net/can/usb/ems_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)