lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 018/667] usb: dwc3: gadget: Move null pinter check to proper place
    Date
    From: Albert Wang <albertccwang@google.com>

    commit 3c5880745b4439ac64eccdb040e37fc1cc4c5406 upstream.

    When dwc3_gadget_ep_cleanup_completed_requests() called to
    dwc3_gadget_giveback() where the dwc3 lock is released, other thread is
    able to execute. In this situation, usb_ep_disable() gets the chance to
    clear endpoint descriptor pointer which leds to the null pointer
    dereference problem. So needs to move the null pointer check to a proper
    place.

    Example call stack:

    Thread#1:
    dwc3_thread_interrupt()
    spin_lock
    -> dwc3_process_event_buf()
    -> dwc3_process_event_entry()
    -> dwc3_endpoint_interrupt()
    -> dwc3_gadget_endpoint_trbs_complete()
    -> dwc3_gadget_ep_cleanup_completed_requests()
    ...
    -> dwc3_giveback()
    spin_unlock
    Thread#2 executes

    Thread#2:
    configfs_composite_disconnect()
    -> __composite_disconnect()
    -> ffs_func_disable()
    -> ffs_func_set_alt()
    -> ffs_func_eps_disable()
    -> usb_ep_disable()
    wait for dwc3 spin_lock
    Thread#1 released lock
    clear endpoint.desc

    Fixes: 26288448120b ("usb: dwc3: gadget: Fix null pointer exception")
    Cc: stable <stable@kernel.org>
    Signed-off-by: Albert Wang <albertccwang@google.com>
    Link: https://lore.kernel.org/r/20220518061315.3359198-1-albertccwang@google.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/usb/dwc3/gadget.c | 6 +++---
    1 file changed, 3 insertions(+), 3 deletions(-)

    --- a/drivers/usb/dwc3/gadget.c
    +++ b/drivers/usb/dwc3/gadget.c
    @@ -3305,14 +3305,14 @@ static bool dwc3_gadget_endpoint_trbs_co
    struct dwc3 *dwc = dep->dwc;
    bool no_started_trb = true;

    - if (!dep->endpoint.desc)
    - return no_started_trb;
    -
    dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);

    if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
    goto out;

    + if (!dep->endpoint.desc)
    + return no_started_trb;
    +
    if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
    list_empty(&dep->started_list) &&
    (list_empty(&dep->pending_list) || status == -EXDEV))

    \
     
     \ /
      Last update: 2022-06-07 20:15    [W:4.522 / U:0.392 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site