lkml.org 
[lkml]   [2017]   [Dec]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 066/204] USB: dummy-hcd: fix infinite-loop resubmission bug
    3.16.52-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Alan Stern <stern@rowland.harvard.edu>

    commit 0173a68bfb0ad1c72a6ee39cc485aa2c97540b98 upstream.

    The dummy-hcd HCD/UDC emulator tries not to do too much work during
    each timer interrupt. But it doesn't try very hard; currently all
    it does is limit the total amount of bulk data transferred. Other
    transfer types aren't limited, and URBs that transfer no data (because
    of an error, perhaps) don't count toward the limit, even though on a
    real USB bus they would consume at least a minimum overhead.

    This means it's possible to get the driver stuck in an infinite loop,
    for example, if the host class driver resubmits an URB every time it
    completes (which is common for interrupt URBs). Each time the URB is
    resubmitted it gets added to the end of the pending-URBs list, and
    dummy-hcd doesn't stop until that list is empty. Andrey Konovalov was
    able to trigger this failure mode using the syzkaller fuzzer.

    This patch fixes the infinite-loop problem by restricting the URBs
    handled during each timer interrupt to those that were already on the
    pending list when the interrupt routine started. Newly added URBs
    won't be processed until the next timer interrupt. The problem of
    properly accounting for non-bulk bandwidth (as well as packet and
    transaction overhead) is not addressed here.

    Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
    Reported-by: Andrey Konovalov <andreyknvl@google.com>
    Tested-by: Andrey Konovalov <andreyknvl@google.com>
    Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
    [bwh: Backported to 3.16: adjust filename]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/usb/gadget/dummy_hcd.c | 9 +++++++++
    1 file changed, 9 insertions(+)

    --- a/drivers/usb/gadget/dummy_hcd.c
    +++ b/drivers/usb/gadget/dummy_hcd.c
    @@ -173,6 +173,8 @@ struct dummy_hcd {

    struct usb_device *udev;
    struct list_head urbp_list;
    + struct urbp *next_frame_urbp;
    +
    u32 stream_en_ep;
    u8 num_stream[30 / 2];

    @@ -1188,6 +1190,8 @@ static int dummy_urb_enqueue(

    list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list);
    urb->hcpriv = urbp;
    + if (!dum_hcd->next_frame_urbp)
    + dum_hcd->next_frame_urbp = urbp;
    if (usb_pipetype(urb->pipe) == PIPE_CONTROL)
    urb->error_count = 1; /* mark as a new urb */

    @@ -1691,6 +1695,7 @@ static void dummy_timer(unsigned long _d
    spin_unlock_irqrestore(&dum->lock, flags);
    return;
    }
    + dum_hcd->next_frame_urbp = NULL;

    for (i = 0; i < DUMMY_ENDPOINTS; i++) {
    if (!ep_name[i])
    @@ -1707,6 +1712,10 @@ restart:
    int type;
    int status = -EINPROGRESS;

    + /* stop when we reach URBs queued after the timer interrupt */
    + if (urbp == dum_hcd->next_frame_urbp)
    + break;
    +
    urb = urbp->urb;
    if (urb->unlinked)
    goto return_urb;
    \
     
     \ /
      Last update: 2017-12-28 19:01    [W:3.107 / U:0.244 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site