summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorUttkarsh Aggarwal <quic_uaggarwa@quicinc.com>2024-01-19 12:48:25 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-02-23 11:24:57 +0300
commitc7ebd8149ee519d27232e6e4940e9c02071b568b (patch)
tree272b4baa20e63a4b61652c669ba16f8493043b5d /drivers/usb/dwc3/gadget.c
parented85777c640cf9e6920bb1b60ed8cd48e1f4d873 (diff)
downloadlinux-c7ebd8149ee519d27232e6e4940e9c02071b568b.tar.xz
usb: dwc3: gadget: Fix NULL pointer dereference in dwc3_gadget_suspend
commit 61a348857e869432e6a920ad8ea9132e8d44c316 upstream. In current scenario if Plug-out and Plug-In performed continuously there could be a chance while checking for dwc->gadget_driver in dwc3_gadget_suspend, a NULL pointer dereference may occur. Call Stack: CPU1: CPU2: gadget_unbind_driver dwc3_suspend_common dwc3_gadget_stop dwc3_gadget_suspend dwc3_disconnect_gadget CPU1 basically clears the variable and CPU2 checks the variable. Consider CPU1 is running and right before gadget_driver is cleared and in parallel CPU2 executes dwc3_gadget_suspend where it finds dwc->gadget_driver which is not NULL and resumes execution and then CPU1 completes execution. CPU2 executes dwc3_disconnect_gadget where it checks dwc->gadget_driver is already NULL because of which the NULL pointer deference occur. Cc: stable@vger.kernel.org Fixes: 9772b47a4c29 ("usb: dwc3: gadget: Fix suspend/resume during device mode") Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Uttkarsh Aggarwal <quic_uaggarwa@quicinc.com> Link: https://lore.kernel.org/r/20240119094825.26530-1-quic_uaggarwa@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 89de363ecf8b..4c8dd6724678 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -4703,15 +4703,13 @@ int dwc3_gadget_suspend(struct dwc3 *dwc)
unsigned long flags;
int ret;
- if (!dwc->gadget_driver)
- return 0;
-
ret = dwc3_gadget_soft_disconnect(dwc);
if (ret)
goto err;
spin_lock_irqsave(&dwc->lock, flags);
- dwc3_disconnect_gadget(dwc);
+ if (dwc->gadget_driver)
+ dwc3_disconnect_gadget(dwc);
spin_unlock_irqrestore(&dwc->lock, flags);
return 0;