lkml.org 
[lkml]   [2009]   [Oct]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[112/136] USB: xhci: Check URBs actual transfer buffer size.
    2.6.31-stable review patch.  If anyone has any objections, please let us know.

    ------------------
    From: Sarah Sharp <sarah.a.sharp@linux.intel.com>

    commit 99eb32db45061443ab7552b8fdceae68b90fde55 upstream.

    Make sure that the amount of data the xHC says was transmitted is less
    than or equal to the size of the requested transfer buffer. Before, if
    the host controller erroneously reported that the number of bytes
    untransferred was bigger than the buffer in the URB, urb->actual_length
    could be set to a very large size.

    Make sure urb->actual_length <= urb->transfer_buffer_length.

    Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/usb/host/xhci-ring.c | 17 ++++++++++++++++-
    1 file changed, 16 insertions(+), 1 deletion(-)

    --- a/drivers/usb/host/xhci-ring.c
    +++ b/drivers/usb/host/xhci-ring.c
    @@ -1092,7 +1092,8 @@ static int handle_tx_event(struct xhci_h
    td->urb->actual_length =
    td->urb->transfer_buffer_length -
    TRB_LEN(event->transfer_len);
    - if (td->urb->actual_length < 0) {
    + if (td->urb->transfer_buffer_length <
    + td->urb->actual_length) {
    xhci_warn(xhci, "HC gave bad length "
    "of %d bytes left\n",
    TRB_LEN(event->transfer_len));
    @@ -1167,6 +1168,20 @@ static int handle_tx_event(struct xhci_h
    td_cleanup:
    /* Clean up the endpoint's TD list */
    urb = td->urb;
    + /* Do one last check of the actual transfer length.
    + * If the host controller said we transferred more data than
    + * the buffer length, urb->actual_length will be a very big
    + * number (since it's unsigned). Play it safe and say we didn't
    + * transfer anything.
    + */
    + if (urb->actual_length > urb->transfer_buffer_length) {
    + xhci_warn(xhci, "URB transfer length is wrong, "
    + "xHC issue? req. len = %u, "
    + "act. len = %u\n",
    + urb->transfer_buffer_length,
    + urb->actual_length);
    + urb->actual_length = 0;
    + }
    list_del(&td->td_list);
    /* Was this TD slated to be cancelled but completed anyway? */
    if (!list_empty(&td->cancelled_td_list)) {



    \
     
     \ /
      Last update: 2009-10-02 03:45    [W:2.387 / U:0.244 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site