From a81422efff2f3884def40f552c54c14b1c9e77af Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Wed, 18 May 2022 14:13:15 +0800 Subject: [PATCH] UPSTREAM: usb: dwc3: gadget: Move null pinter check to proper place 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 Signed-off-by: Albert Wang Link: https://lore.kernel.org/r/20220518061315.3359198-1-albertccwang@google.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 3c5880745b4439ac64eccdb040e37fc1cc4c5406) Change-Id: I15ad3eab4b946f4db6e52035c5dd0d6b3435472e Signed-off-by: Tao Huang --- drivers/usb/dwc3/gadget.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index dddd53230594..2852d8a62a9e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3533,14 +3533,14 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep, struct dwc3_request *req, *tmp; 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 MISS ISOC happens, we need to do the following three steps * to restart the reqs in the cancelled_list and pending_list