[lkml]   [2012]   [Mar]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[ 098/149] usbnet: increase URB reference count before usb_unlink_urb
    3.2-stable review patch.  If anyone has any objections, please let me know.


    From: "" <>

    commit 0956a8c20b23d429e79ff86d4325583fc06f9eb4 upstream.

    Commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d(net/usbnet: avoid
    recursive locking in usbnet_stop()) fixes the recursive locking
    problem by releasing the skb queue lock, but it makes usb_unlink_urb
    racing with defer_bh, and the URB to being unlinked may be freed before
    or during calling usb_unlink_urb, so use-after-free problem may be
    triggerd inside usb_unlink_urb.

    The patch fixes the use-after-free problem by increasing URB
    reference count with skb queue lock held before calling
    usb_unlink_urb, so the URB won't be freed until return from

    Cc: Sebastian Andrzej Siewior <>
    Cc: Alan Stern <>
    Cc: Oliver Neukum <>
    Reported-by: Dave Jones <>
    Signed-off-by: Ming Lei <>
    Acked-by: Greg Kroah-Hartman <>
    Signed-off-by: David S. Miller <>
    Signed-off-by: Greg Kroah-Hartman <>

    drivers/net/usb/usbnet.c | 9 +++++++++
    1 file changed, 9 insertions(+)

    --- a/drivers/net/usb/usbnet.c
    +++ b/drivers/net/usb/usbnet.c
    @@ -589,6 +589,14 @@ static int unlink_urbs (struct usbnet *d
    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 *d
    netdev_dbg(dev->net, "unlink urb err, %d\n", retval);
    + usb_put_urb(urb);
    spin_lock_irqsave(&q->lock, flags);
    spin_unlock_irqrestore (&q->lock, flags);

     \ /
      Last update: 2012-03-30 23:17    [W:0.021 / U:5.356 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site