Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13e5c159 authored by Mayank Rana's avatar Mayank Rana
Browse files

usb: gadget: composite: Protect cdev in composite_suspend()



With USB cable disconnect case, there is race happening when
composite_suspend() is being pre-empted just after getting
reference to cdev structure (suspend flow) and cdev->config
set to NULL as part of reset_config() (disconnect flow). This
results into composite_suspend() using bad value with cdev->config
which is resulting in some cases multiple time calling f->suspend().
Fix this issue by protecting cdev in composite_suspend() API.

CRs-Fixed: 916718
Change-Id: Id0b2a254f64621fcbc19c0556265e9b7b32f1382
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent e9e13928
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -2364,11 +2364,13 @@ void composite_suspend(struct usb_gadget *gadget)
{
	struct usb_composite_dev	*cdev = get_gadget_data(gadget);
	struct usb_function		*f;
	unsigned long			flags;

	/* REVISIT:  should we have config level
	 * suspend/resume callbacks?
	 */
	DBG(cdev, "suspend\n");
	spin_lock_irqsave(&cdev->lock, flags);
	if (cdev->config) {
		list_for_each_entry(f, &cdev->config->functions, list) {
			if (f->suspend)
@@ -2379,6 +2381,7 @@ void composite_suspend(struct usb_gadget *gadget)
		cdev->driver->suspend(cdev);

	cdev->suspended = 1;
	spin_unlock_irqrestore(&cdev->lock, flags);

	usb_gadget_vbus_draw(gadget, 2);
}