|
@@ -589,6 +589,14 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
|
|
|
entry = (struct skb_data *) skb->cb;
|
|
|
urb = entry->urb;
|
|
|
|
|
|
+ /*
|
|
|
+ * Get reference count of the URB to avoid it to be
|
|
|
+ * freed during usb_unlink_urb, which may trigger
|
|
|
+ * use-after-free problem inside usb_unlink_urb since
|
|
|
+ * usb_unlink_urb is always racing with .complete
|
|
|
+ * handler(include defer_bh).
|
|
|
+ */
|
|
|
+ usb_get_urb(urb);
|
|
|
spin_unlock_irqrestore(&q->lock, flags);
|
|
|
// during some PM-driven resume scenarios,
|
|
|
// these (async) unlinks complete immediately
|
|
@@ -597,6 +605,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
|
|
|
netdev_dbg(dev->net, "unlink urb err, %d\n", retval);
|
|
|
else
|
|
|
count++;
|
|
|
+ usb_put_urb(urb);
|
|
|
spin_lock_irqsave(&q->lock, flags);
|
|
|
}
|
|
|
spin_unlock_irqrestore (&q->lock, flags);
|