Skip to content

Commit

Permalink
usbnet: Fix memory leak in usbnet_disconnect()
Browse files Browse the repository at this point in the history
Currently usbnet_disconnect() unanchors and frees all deferred URBs
using usb_scuttle_anchored_urbs(), which does not free urb->context,
causing a memory leak as reported by syzbot.

Use a usb_get_from_anchor() while loop instead, similar to what we did
in commit 19cfe91 ("Bluetooth: btusb: Fix memory leak in
play_deferred").  Also free urb->sg.

Reported-and-tested-by: [email protected]
Fixes: 69ee472 ("usbnet & cdc-ether: Autosuspend for online devices")
Fixes: 638c511 ("USBNET: support DMA SG")
Signed-off-by: Peilin Ye <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
peilin-ye authored and kuba-moo committed Sep 26, 2022
1 parent 6052a4c commit a432061
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion drivers/net/usb/usbnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1598,6 +1598,7 @@ void usbnet_disconnect (struct usb_interface *intf)
struct usbnet *dev;
struct usb_device *xdev;
struct net_device *net;
struct urb *urb;

dev = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL);
Expand All @@ -1614,7 +1615,11 @@ void usbnet_disconnect (struct usb_interface *intf)
net = dev->net;
unregister_netdev (net);

usb_scuttle_anchored_urbs(&dev->deferred);
while ((urb = usb_get_from_anchor(&dev->deferred))) {
dev_kfree_skb(urb->context);
kfree(urb->sg);
usb_free_urb(urb);
}

if (dev->driver_info->unbind)
dev->driver_info->unbind(dev, intf);
Expand Down

0 comments on commit a432061

Please sign in to comment.