[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220607165003.228890970@linuxfoundation.org>
Date: Tue, 7 Jun 2022 18:52:17 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, stable <stable@...nel.org>,
Albert Wang <albertccwang@...gle.com>
Subject: [PATCH 5.18 019/879] usb: dwc3: gadget: Move null pinter check to proper place
From: Albert Wang <albertccwang@...gle.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@...nel.org>
Signed-off-by: Albert Wang <albertccwang@...gle.com>
Link: https://lore.kernel.org/r/20220518061315.3359198-1-albertccwang@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.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
@@ -3380,14 +3380,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))
Powered by blists - more mailing lists