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,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Alan Stern <stern@rowland.harvard.edu>,
	Felipe Balbi <felipe.balbi@linux.intel.com>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.19 17/93] usb: gadget: mass_storage: Fix races between fsg_disable and fsg_set_alt
Date: Wed,  4 Sep 2019 19:53:19 +0200	[thread overview]
Message-ID: <20190904175304.746167206@linuxfoundation.org> (raw)
In-Reply-To: <20190904175302.845828956@linuxfoundation.org>

[ Upstream commit 4a56a478a525d6427be90753451c40e1327caa1a ]

If fsg_disable() and fsg_set_alt() are called too closely to each
other (for example due to a quick reset/reconnect), what can happen
is that fsg_set_alt sets common->new_fsg from an interrupt while
handle_exception is trying to process the config change caused by
fsg_disable():

	fsg_disable()
	...
	handle_exception()
		sets state back to FSG_STATE_NORMAL
		hasn't yet called do_set_interface()
		or is inside it.

 ---> interrupt
	fsg_set_alt
		sets common->new_fsg
		queues a new FSG_STATE_CONFIG_CHANGE
 <---

Now, the first handle_exception can "see" the updated
new_fsg, treats it as if it was a fsg_set_alt() response,
call usb_composite_setup_continue() etc...

But then, the thread sees the second FSG_STATE_CONFIG_CHANGE,
and goes back down the same path, wipes and reattaches a now
active fsg, and .. calls usb_composite_setup_continue() which
at this point is wrong.

Not only we get a backtrace, but I suspect the second set_interface
wrecks some state causing the host to get upset in my case.

This fixes it by replacing "new_fsg" by a "state argument" (same
principle) which is set in the same lock section as the state
update, and retrieved similarly.

That way, there is never any discrepancy between the dequeued
state and the observed value of it. We keep the ability to have
the latest reconfig operation take precedence, but we guarantee
that once "dequeued" the argument (new_fsg) will not be clobbered
by any new event.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/usb/gadget/function/f_mass_storage.c | 28 +++++++++++++-------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index 1074cb82ec172..0b7b4d09785b6 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -261,7 +261,7 @@ struct fsg_common;
 struct fsg_common {
 	struct usb_gadget	*gadget;
 	struct usb_composite_dev *cdev;
-	struct fsg_dev		*fsg, *new_fsg;
+	struct fsg_dev		*fsg;
 	wait_queue_head_t	io_wait;
 	wait_queue_head_t	fsg_wait;
 
@@ -290,6 +290,7 @@ struct fsg_common {
 	unsigned int		bulk_out_maxpacket;
 	enum fsg_state		state;		/* For exception handling */
 	unsigned int		exception_req_tag;
+	void			*exception_arg;
 
 	enum data_direction	data_dir;
 	u32			data_size;
@@ -391,7 +392,8 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
 
 /* These routines may be called in process context or in_irq */
 
-static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
+static void __raise_exception(struct fsg_common *common, enum fsg_state new_state,
+			      void *arg)
 {
 	unsigned long		flags;
 
@@ -404,6 +406,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
 	if (common->state <= new_state) {
 		common->exception_req_tag = common->ep0_req_tag;
 		common->state = new_state;
+		common->exception_arg = arg;
 		if (common->thread_task)
 			send_sig_info(SIGUSR1, SEND_SIG_FORCED,
 				      common->thread_task);
@@ -411,6 +414,10 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
 	spin_unlock_irqrestore(&common->lock, flags);
 }
 
+static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
+{
+	__raise_exception(common, new_state, NULL);
+}
 
 /*-------------------------------------------------------------------------*/
 
@@ -2285,16 +2292,16 @@ reset:
 static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
 {
 	struct fsg_dev *fsg = fsg_from_func(f);
-	fsg->common->new_fsg = fsg;
-	raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+
+	__raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, fsg);
 	return USB_GADGET_DELAYED_STATUS;
 }
 
 static void fsg_disable(struct usb_function *f)
 {
 	struct fsg_dev *fsg = fsg_from_func(f);
-	fsg->common->new_fsg = NULL;
-	raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+
+	__raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL);
 }
 
 
@@ -2307,6 +2314,7 @@ static void handle_exception(struct fsg_common *common)
 	enum fsg_state		old_state;
 	struct fsg_lun		*curlun;
 	unsigned int		exception_req_tag;
+	struct fsg_dev		*new_fsg;
 
 	/*
 	 * Clear the existing signals.  Anything but SIGUSR1 is converted
@@ -2360,6 +2368,7 @@ static void handle_exception(struct fsg_common *common)
 	common->next_buffhd_to_fill = &common->buffhds[0];
 	common->next_buffhd_to_drain = &common->buffhds[0];
 	exception_req_tag = common->exception_req_tag;
+	new_fsg = common->exception_arg;
 	old_state = common->state;
 	common->state = FSG_STATE_NORMAL;
 
@@ -2413,8 +2422,8 @@ static void handle_exception(struct fsg_common *common)
 		break;
 
 	case FSG_STATE_CONFIG_CHANGE:
-		do_set_interface(common, common->new_fsg);
-		if (common->new_fsg)
+		do_set_interface(common, new_fsg);
+		if (new_fsg)
 			usb_composite_setup_continue(common->cdev);
 		break;
 
@@ -2989,8 +2998,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
 
 	DBG(fsg, "unbind\n");
 	if (fsg->common->fsg == fsg) {
-		fsg->common->new_fsg = NULL;
-		raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
+		__raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL);
 		/* FIXME: make interruptible or killable somehow? */
 		wait_event(common->fsg_wait, common->fsg != fsg);
 	}
-- 
2.20.1




  parent reply	other threads:[~2019-09-04 18:05 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-04 17:53 [PATCH 4.19 00/93] 4.19.70-stable review Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 01/93] dmaengine: ste_dma40: fix unneeded variable warning Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 02/93] nvme-multipath: revalidate nvme_ns_head gendisk in nvme_validate_ns Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 03/93] afs: Fix the CB.ProbeUuid service handler to reply correctly Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 04/93] afs: Fix loop index mixup in afs_deliver_vl_get_entry_by_name_u() Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 05/93] fs: afs: Fix a possible null-pointer dereference in afs_put_read() Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 06/93] afs: Only update d_fsdata if different in afs_d_revalidate() Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 07/93] nvmet-loop: Flush nvme_delete_wq when removing the port Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 08/93] nvme: fix a possible deadlock when passthru commands sent to a multipath device Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 09/93] nvme-pci: Fix async probe remove race Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 10/93] soundwire: cadence_master: fix register definition for SLAVE_STATE Greg Kroah-Hartman
2019-09-06 13:54   ` Pavel Machek
2019-09-04 17:53 ` [PATCH 4.19 11/93] soundwire: cadence_master: fix definitions for INTSTAT0/1 Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 12/93] auxdisplay: panel: need to delete scan_timer when misc_register fails in panel_attach Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 13/93] dmaengine: stm32-mdma: Fix a possible null-pointer dereference in stm32_mdma_irq_handler() Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 14/93] omap-dma/omap_vout_vrfb: fix off-by-one fi value Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 15/93] iommu/dma: Handle SG length overflow better Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 16/93] usb: gadget: composite: Clear "suspended" on reset/disconnect Greg Kroah-Hartman
2019-09-04 17:53 ` Greg Kroah-Hartman [this message]
2019-09-04 17:53 ` [PATCH 4.19 18/93] xen/blkback: fix memory leaks Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 19/93] arm64: cpufeature: Dont treat granule sizes as strict Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 20/93] i2c: rcar: avoid race when unregistering slave client Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 21/93] i2c: emev2: " Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 22/93] drm/ast: Fixed reboot test may cause system hanged Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 23/93] usb: host: fotg2: restart hcd after port reset Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 24/93] tools: hv: fixed Python pep8/flake8 warnings for lsvmbus Greg Kroah-Hartman
2019-09-06 13:52   ` Pavel Machek
2019-09-04 17:53 ` [PATCH 4.19 25/93] tools: hv: fix KVP and VSS daemons exit code Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 26/93] drm/i915: fix broadwell EU computation Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 27/93] watchdog: bcm2835_wdt: Fix module autoload Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 28/93] drm/bridge: tfp410: fix memleak in get_modes() Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 29/93] scsi: ufs: Fix RX_TERMINATION_FORCE_ENABLE define value Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 30/93] drm/tilcdc: Register cpufreq notifier after we have initialized crtc Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 31/93] net/tls: Fixed return value when tls_complete_pending_work() fails Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 32/93] net/tls: swap sk_write_space on close Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 33/93] net: tls, fix sk_write_space NULL write when tx disabled Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 34/93] ipv6/addrconf: allow adding multicast addr if IFA_F_MCAUTOJOIN is set Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 35/93] ipv6: Default fib6_type to RTN_UNICAST when not set Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 36/93] net/smc: make sure EPOLLOUT is raised Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 37/93] tcp: make sure EPOLLOUT wont be missed Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 38/93] ipv4/icmp: fix rt dst dev null pointer dereference Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 39/93] mm/zsmalloc.c: fix build when CONFIG_COMPACTION=n Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 40/93] ALSA: usb-audio: Check mixer unit bitmap yet more strictly Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 41/93] ALSA: line6: Fix memory leak at line6_init_pcm() error path Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 42/93] ALSA: hda - Fixes inverted Conexant GPIO mic mute led Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 43/93] ALSA: seq: Fix potential concurrent access to the deleted pool Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 44/93] ALSA: usb-audio: Fix invalid NULL check in snd_emuusb_set_samplerate() Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 45/93] ALSA: usb-audio: Add implicit fb quirk for Behringer UFX1604 Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 46/93] kvm: x86: skip populating logical dest map if apic is not sw enabled Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 47/93] KVM: x86: Dont update RIP or do single-step on faulting emulation Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 48/93] uprobes/x86: Fix detection of 32-bit user mode Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 49/93] x86/apic: Do not initialize LDR and DFR for bigsmp Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 50/93] x86/apic: Include the LDR when clearing out APIC registers Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 51/93] ftrace: Fix NULL pointer dereference in t_probe_next() Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 52/93] ftrace: Check for successful allocation of hash Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 53/93] ftrace: Check for empty hash and comment the race with registering probes Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 54/93] usb-storage: Add new JMS567 revision to unusual_devs Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 55/93] USB: cdc-wdm: fix race between write and disconnect due to flag abuse Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 56/93] usb: hcd: use managed device resources Greg Kroah-Hartman
2019-09-04 17:53 ` [PATCH 4.19 57/93] usb: chipidea: udc: dont do hardware access if gadget has stopped Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 58/93] usb: host: ohci: fix a race condition between shutdown and irq Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 59/93] usb: host: xhci: rcar: Fix typo in compatible string matching Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 60/93] USB: storage: ums-realtek: Update module parameter description for auto_delink_en Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 61/93] USB: storage: ums-realtek: Whitelist auto-delink support Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 62/93] mei: me: add Tiger Lake point LP device ID Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 63/93] mmc: sdhci-of-at91: add quirk for broken HS200 Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 64/93] mmc: core: Fix init of SD cards reporting an invalid VDD range Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 65/93] stm class: Fix a double free of stm_source_device Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 66/93] intel_th: pci: Add support for another Lewisburg PCH Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 67/93] intel_th: pci: Add Tiger Lake support Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 68/93] typec: tcpm: fix a typo in the comparison of pdo_max_voltage Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 69/93] fsi: scom: Dont abort operations for minor errors Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 70/93] lib: logic_pio: Fix RCU usage Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 71/93] lib: logic_pio: Avoid possible overlap for unregistering regions Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 72/93] lib: logic_pio: Add logic_pio_unregister_range() Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 73/93] drm/amdgpu: Add APTX quirk for Dell Latitude 5495 Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 74/93] drm/i915: Dont deballoon unused ggtt drm_mm_node in linux guest Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 75/93] drm/i915: Call dma_set_max_seg_size() in i915_driver_hw_probe() Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 76/93] bus: hisi_lpc: Unregister logical PIO range to avoid potential use-after-free Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 77/93] bus: hisi_lpc: Add .remove method to avoid driver unbind crash Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 78/93] VMCI: Release resource if the work is already queued Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 79/93] crypto: ccp - Ignore unconfigured CCP device on suspend/resume Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 80/93] Revert "cfg80211: fix processing world regdomain when non modular" Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 81/93] mac80211: fix possible sta leak Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 82/93] mac80211: Dont memset RXCB prior to PAE intercept Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 83/93] mac80211: Correctly set noencrypt for PAE frames Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 84/93] KVM: PPC: Book3S: Fix incorrect guest-to-user-translation error handling Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 85/93] KVM: arm/arm64: vgic: Fix potential deadlock when ap_list is long Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 86/93] KVM: arm/arm64: vgic-v2: Handle SGI bits in GICD_I{S,C}PENDR0 as WI Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 87/93] NFS: Clean up list moves of struct nfs_page Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 88/93] NFSv4/pnfs: Fix a page lock leak in nfs_pageio_resend() Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 89/93] NFS: Pass error information to the pgio error cleanup routine Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 90/93] NFS: Ensure O_DIRECT reports an error if the bytes read/written is 0 Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 91/93] i2c: piix4: Fix port selection for AMD Family 16h Model 30h Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 92/93] x86/ptrace: fix up botched merge of spectrev1 fix Greg Kroah-Hartman
2019-09-04 17:54 ` [PATCH 4.19 93/93] mt76: mt76x0u: do not reset radio on resume Greg Kroah-Hartman
2019-09-04 22:18 ` [PATCH 4.19 00/93] 4.19.70-stable review kernelci.org bot
2019-09-05 14:57 ` shuah
2019-09-05 16:56 ` Guenter Roeck
2019-09-05 17:28 ` Daniel Díaz
2019-09-05 19:51 ` Kelsey Skunberg
2019-09-06  7:37 ` Jon Hunter

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=20190904175304.746167206@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=benh@kernel.crashing.org \
    --cc=felipe.balbi@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sashal@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).