stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Alan Stern <stern@rowland.harvard.edu>,
	Felipe Balbi <felipe.balbi@linux.intel.com>
Subject: [PATCH 4.4 12/47] USB: dummy-hcd: Fix erroneous synchronization change
Date: Tue, 10 Oct 2017 21:50:25 +0200	[thread overview]
Message-ID: <20171010195020.092295088@linuxfoundation.org> (raw)
In-Reply-To: <20171010195019.584170396@linuxfoundation.org>

4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alan Stern <stern@rowland.harvard.edu>

commit 7dbd8f4cabd96db5a50513de9d83a8105a5ffc81 upstream.

A recent change to the synchronization in dummy-hcd was incorrect.
The issue was that dummy_udc_stop() contained no locking and therefore
could race with various gadget driver callbacks, and the fix was to
add locking and issue the callbacks with the private spinlock held.

UDC drivers aren't supposed to do this.  Gadget driver callback
routines are allowed to invoke functions in the UDC driver, and these
functions will generally try to acquire the private spinlock.  This
would deadlock the driver.

The correct solution is to drop the spinlock before issuing callbacks,
and avoid races by emulating the synchronize_irq() call that all real
UDC drivers must perform in their ->udc_stop() routines after
disabling interrupts.  This involves adding a flag to dummy-hcd's
private structure to keep track of whether interrupts are supposed to
be enabled, and adding a counter to keep track of ongoing callbacks so
that dummy_udc_stop() can wait for them all to finish.

A real UDC driver won't receive disconnect, reset, suspend, resume, or
setup events once it has disabled interrupts.  dummy-hcd will receive
them but won't try to issue any gadget driver callbacks, which should
be just as good.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Fixes: f16443a034c7 ("USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks")
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/usb/gadget/udc/dummy_hcd.c |   32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -255,11 +255,13 @@ struct dummy {
 	 */
 	struct dummy_ep			ep[DUMMY_ENDPOINTS];
 	int				address;
+	int				callback_usage;
 	struct usb_gadget		gadget;
 	struct usb_gadget_driver	*driver;
 	struct dummy_request		fifo_req;
 	u8				fifo_buf[FIFO_SIZE];
 	u16				devstatus;
+	unsigned			ints_enabled:1;
 	unsigned			udc_suspended:1;
 	unsigned			pullup:1;
 
@@ -442,18 +444,27 @@ static void set_link_state(struct dummy_
 				(~dum_hcd->old_status) & dum_hcd->port_status;
 
 		/* Report reset and disconnect events to the driver */
-		if (dum->driver && (disconnect || reset)) {
+		if (dum->ints_enabled && (disconnect || reset)) {
 			stop_activity(dum);
+			++dum->callback_usage;
+			spin_unlock(&dum->lock);
 			if (reset)
 				usb_gadget_udc_reset(&dum->gadget, dum->driver);
 			else
 				dum->driver->disconnect(&dum->gadget);
+			spin_lock(&dum->lock);
+			--dum->callback_usage;
 		}
-	} else if (dum_hcd->active != dum_hcd->old_active) {
+	} else if (dum_hcd->active != dum_hcd->old_active &&
+			dum->ints_enabled) {
+		++dum->callback_usage;
+		spin_unlock(&dum->lock);
 		if (dum_hcd->old_active && dum->driver->suspend)
 			dum->driver->suspend(&dum->gadget);
 		else if (!dum_hcd->old_active &&  dum->driver->resume)
 			dum->driver->resume(&dum->gadget);
+		spin_lock(&dum->lock);
+		--dum->callback_usage;
 	}
 
 	dum_hcd->old_status = dum_hcd->port_status;
@@ -969,8 +980,11 @@ static int dummy_udc_start(struct usb_ga
 	 * can't enumerate without help from the driver we're binding.
 	 */
 
+	spin_lock_irq(&dum->lock);
 	dum->devstatus = 0;
 	dum->driver = driver;
+	dum->ints_enabled = 1;
+	spin_unlock_irq(&dum->lock);
 
 	return 0;
 }
@@ -981,6 +995,16 @@ static int dummy_udc_stop(struct usb_gad
 	struct dummy		*dum = dum_hcd->dum;
 
 	spin_lock_irq(&dum->lock);
+	dum->ints_enabled = 0;
+	stop_activity(dum);
+
+	/* emulate synchronize_irq(): wait for callbacks to finish */
+	while (dum->callback_usage > 0) {
+		spin_unlock_irq(&dum->lock);
+		usleep_range(1000, 2000);
+		spin_lock_irq(&dum->lock);
+	}
+
 	dum->driver = NULL;
 	spin_unlock_irq(&dum->lock);
 
@@ -1526,6 +1550,8 @@ static struct dummy_ep *find_endpoint(st
 	if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ?
 			dum->ss_hcd : dum->hs_hcd)))
 		return NULL;
+	if (!dum->ints_enabled)
+		return NULL;
 	if ((address & ~USB_DIR_IN) == 0)
 		return &dum->ep[0];
 	for (i = 1; i < DUMMY_ENDPOINTS; i++) {
@@ -1867,10 +1893,12 @@ restart:
 			 * until setup() returns; no reentrancy issues etc.
 			 */
 			if (value > 0) {
+				++dum->callback_usage;
 				spin_unlock(&dum->lock);
 				value = dum->driver->setup(&dum->gadget,
 						&setup);
 				spin_lock(&dum->lock);
+				--dum->callback_usage;
 
 				if (value >= 0) {
 					/* no delays (max 64KB data stage) */

  parent reply	other threads:[~2017-10-10 19:50 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-10 19:50 [PATCH 4.4 00/47] 4.4.92-stable review Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 01/47] usb: gadget: inode.c: fix unbalanced spin_lock in ep0_write Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 02/47] USB: gadgetfs: Fix crash caused by inadequate synchronization Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 03/47] USB: gadgetfs: fix copy_to_user while holding spinlock Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 04/47] usb: gadget: udc: atmel: set vbus irqflags explicitly Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 05/47] usb-storage: unusual_devs entry to fix write-access regression for Seagate external drives Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 06/47] usb: renesas_usbhs: fix the BCLR setting condition for non-DCP pipe Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 07/47] usb: renesas_usbhs: fix usbhsf_fifo_clear() for RX direction Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 08/47] ALSA: usb-audio: Check out-of-bounds access by corrupted buffer descriptor Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 09/47] usb: pci-quirks.c: Corrected timeout values used in handshake Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 10/47] USB: dummy-hcd: fix connection failures (wrong speed) Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 11/47] USB: dummy-hcd: fix infinite-loop resubmission bug Greg Kroah-Hartman
2017-10-10 19:50 ` Greg Kroah-Hartman [this message]
2017-10-10 19:50 ` [PATCH 4.4 13/47] USB: devio: Dont corrupt user memory Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 14/47] usb: gadget: mass_storage: set msg_registered after msg registered Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 15/47] USB: g_mass_storage: Fix deadlock when driver is unbound Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 16/47] lsm: fix smack_inode_removexattr and xattr_getsecurity memleak Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 17/47] ALSA: compress: Remove unused variable Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 18/47] ALSA: usx2y: Suppress kernel warning at page allocation failures Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 19/47] driver core: platform: Dont read past the end of "driver_override" buffer Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 20/47] Drivers: hv: fcopy: restore correct transfer length Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 21/47] stm class: Fix a use-after-free Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 22/47] ftrace: Fix kmemleak in unregister_ftrace_graph Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 23/47] HID: i2c-hid: allocate hid buffers for real worst case Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 24/47] iwlwifi: add workaround to disable wide channels in 5GHz Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 25/47] scsi: sd: Do not override max_sectors_kb sysfs setting Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 26/47] USB: uas: fix bug in handling of alternate settings Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 27/47] USB: core: harden cdc_parse_cdc_header Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 28/47] usb: Increase quirk delay for USB devices Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 29/47] USB: fix out-of-bounds in usb_set_configuration Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 30/47] xhci: fix finding correct bus_state structure for USB 3.1 hosts Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 31/47] iio: adc: twl4030: Fix an error handling path in twl4030_madc_probe() Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 32/47] iio: adc: twl4030: Disable the vusb3v1 rugulator in the error handling path of twl4030_madc_probe() Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 33/47] iio: ad_sigma_delta: Implement a dedicated reset function Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 34/47] staging: iio: ad7192: Fix - use the dedicated reset function avoiding dma from stack Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 35/47] iio: core: Return error for failed read_reg Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 36/47] iio: ad7793: Fix the serial interface reset Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 37/47] iio: adc: mcp320x: Fix readout of negative voltages Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 38/47] iio: adc: mcp320x: Fix oops on module unload Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 39/47] uwb: properly check kthread_run return value Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 40/47] uwb: ensure that endpoint is interrupt Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 41/47] brcmfmac: setup passive scan if requested by user-space Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 43/47] nvme: protect against simultaneous shutdown invocations Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 44/47] sched/cpuset/pm: Fix cpuset vs. suspend-resume bugs Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 45/47] ext4: fix data corruption for mmap writes Greg Kroah-Hartman
2017-10-10 19:50 ` [PATCH 4.4 46/47] ext4: Dont clear SGID when inheriting ACLs Greg Kroah-Hartman
2017-10-10 19:51 ` [PATCH 4.4 47/47] ext4: dont allow encrypted operations without keys Greg Kroah-Hartman
2017-10-11  0:38 ` [PATCH 4.4 00/47] 4.4.92-stable review Shuah Khan
2017-10-11  3:46 ` Tom Gall
2017-10-11  4:28   ` Sumit Semwal
2017-10-11 13:18 ` Guenter Roeck
     [not found] ` <EA877027-37D3-4397-B48C-65FC1F686BCA@linaro.org>
2017-10-11 16:12   ` Tom Gall
2017-10-11 16:47     ` Greg Kroah-Hartman
2017-10-11 22:14       ` Tom Gall
2017-10-12  8:30         ` Milosz Wasilewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171010195020.092295088@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=felipe.balbi@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).