linux-kernel.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>,
	Jiri Kosina <jkosina@suse.cz>,
	syzbot+7bf5a7b0f0a1f9446f4c@syzkaller.appspotmail.com
Subject: [PATCH 5.4 44/90] HID: usbhid: Fix race between usbhid_close() and usbhid_stop()
Date: Wed, 13 May 2020 11:44:40 +0200	[thread overview]
Message-ID: <20200513094413.466529428@linuxfoundation.org> (raw)
In-Reply-To: <20200513094408.810028856@linuxfoundation.org>

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

commit 0ed08faded1da03eb3def61502b27f81aef2e615 upstream.

The syzbot fuzzer discovered a bad race between in the usbhid driver
between usbhid_stop() and usbhid_close().  In particular,
usbhid_stop() does:

	usb_free_urb(usbhid->urbin);
	...
	usbhid->urbin = NULL; /* don't mess up next start */

and usbhid_close() does:

	usb_kill_urb(usbhid->urbin);

with no mutual exclusion.  If the two routines happen to run
concurrently so that usb_kill_urb() is called in between the
usb_free_urb() and the NULL assignment, it will access the
deallocated urb structure -- a use-after-free bug.

This patch adds a mutex to the usbhid private structure and uses it to
enforce mutual exclusion of the usbhid_start(), usbhid_stop(),
usbhid_open() and usbhid_close() callbacks.

Reported-and-tested-by: syzbot+7bf5a7b0f0a1f9446f4c@syzkaller.appspotmail.com
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@vger.kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/hid/usbhid/hid-core.c |   37 +++++++++++++++++++++++++++++--------
 drivers/hid/usbhid/usbhid.h   |    1 +
 2 files changed, 30 insertions(+), 8 deletions(-)

--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -682,16 +682,21 @@ static int usbhid_open(struct hid_device
 	struct usbhid_device *usbhid = hid->driver_data;
 	int res;
 
+	mutex_lock(&usbhid->mutex);
+
 	set_bit(HID_OPENED, &usbhid->iofl);
 
-	if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
-		return 0;
+	if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
+		res = 0;
+		goto Done;
+	}
 
 	res = usb_autopm_get_interface(usbhid->intf);
 	/* the device must be awake to reliably request remote wakeup */
 	if (res < 0) {
 		clear_bit(HID_OPENED, &usbhid->iofl);
-		return -EIO;
+		res = -EIO;
+		goto Done;
 	}
 
 	usbhid->intf->needs_remote_wakeup = 1;
@@ -725,6 +730,9 @@ static int usbhid_open(struct hid_device
 		msleep(50);
 
 	clear_bit(HID_RESUME_RUNNING, &usbhid->iofl);
+
+ Done:
+	mutex_unlock(&usbhid->mutex);
 	return res;
 }
 
@@ -732,6 +740,8 @@ static void usbhid_close(struct hid_devi
 {
 	struct usbhid_device *usbhid = hid->driver_data;
 
+	mutex_lock(&usbhid->mutex);
+
 	/*
 	 * Make sure we don't restart data acquisition due to
 	 * a resumption we no longer care about by avoiding racing
@@ -743,12 +753,13 @@ static void usbhid_close(struct hid_devi
 		clear_bit(HID_IN_POLLING, &usbhid->iofl);
 	spin_unlock_irq(&usbhid->lock);
 
-	if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
-		return;
+	if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) {
+		hid_cancel_delayed_stuff(usbhid);
+		usb_kill_urb(usbhid->urbin);
+		usbhid->intf->needs_remote_wakeup = 0;
+	}
 
-	hid_cancel_delayed_stuff(usbhid);
-	usb_kill_urb(usbhid->urbin);
-	usbhid->intf->needs_remote_wakeup = 0;
+	mutex_unlock(&usbhid->mutex);
 }
 
 /*
@@ -1057,6 +1068,8 @@ static int usbhid_start(struct hid_devic
 	unsigned int n, insize = 0;
 	int ret;
 
+	mutex_lock(&usbhid->mutex);
+
 	clear_bit(HID_DISCONNECTED, &usbhid->iofl);
 
 	usbhid->bufsize = HID_MIN_BUFFER_SIZE;
@@ -1177,6 +1190,8 @@ static int usbhid_start(struct hid_devic
 		usbhid_set_leds(hid);
 		device_set_wakeup_enable(&dev->dev, 1);
 	}
+
+	mutex_unlock(&usbhid->mutex);
 	return 0;
 
 fail:
@@ -1187,6 +1202,7 @@ fail:
 	usbhid->urbout = NULL;
 	usbhid->urbctrl = NULL;
 	hid_free_buffers(dev, hid);
+	mutex_unlock(&usbhid->mutex);
 	return ret;
 }
 
@@ -1202,6 +1218,8 @@ static void usbhid_stop(struct hid_devic
 		usbhid->intf->needs_remote_wakeup = 0;
 	}
 
+	mutex_lock(&usbhid->mutex);
+
 	clear_bit(HID_STARTED, &usbhid->iofl);
 	spin_lock_irq(&usbhid->lock);	/* Sync with error and led handlers */
 	set_bit(HID_DISCONNECTED, &usbhid->iofl);
@@ -1222,6 +1240,8 @@ static void usbhid_stop(struct hid_devic
 	usbhid->urbout = NULL;
 
 	hid_free_buffers(hid_to_usb_dev(hid), hid);
+
+	mutex_unlock(&usbhid->mutex);
 }
 
 static int usbhid_power(struct hid_device *hid, int lvl)
@@ -1382,6 +1402,7 @@ static int usbhid_probe(struct usb_inter
 	INIT_WORK(&usbhid->reset_work, hid_reset);
 	timer_setup(&usbhid->io_retry, hid_retry_timeout, 0);
 	spin_lock_init(&usbhid->lock);
+	mutex_init(&usbhid->mutex);
 
 	ret = hid_add_device(hid);
 	if (ret) {
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -80,6 +80,7 @@ struct usbhid_device {
 	dma_addr_t outbuf_dma;                                          /* Output buffer dma */
 	unsigned long last_out;							/* record of last output for timeouts */
 
+	struct mutex mutex;						/* start/stop/open/close */
 	spinlock_t lock;						/* fifo spinlock */
 	unsigned long iofl;                                             /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
 	struct timer_list io_retry;                                     /* Retry timer */



  parent reply	other threads:[~2020-05-13  9:51 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-13  9:43 [PATCH 5.4 00/90] 5.4.41-rc1 review Greg Kroah-Hartman
2020-05-13  9:43 ` [PATCH 5.4 01/90] USB: serial: qcserial: Add DW5816e support Greg Kroah-Hartman
2020-05-13  9:43 ` [PATCH 5.4 02/90] nvme: refactor nvme_identify_ns_descs error handling Greg Kroah-Hartman
2020-05-13  9:43 ` [PATCH 5.4 03/90] nvme: fix possible hang when ns scanning fails during error recovery Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 04/90] tracing/kprobes: Fix a double initialization typo Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 05/90] net: macb: Fix runtime PM refcounting Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 06/90] drm/amdgpu: move kfd suspend after ip_suspend_phase1 Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 07/90] drm/amdgpu: drop redundant cg/pg ungate on runpm enter Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 08/90] vt: fix unicode console freeing with a common interface Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 09/90] tty: xilinx_uartps: Fix missing id assignment to the console Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 10/90] devlink: fix return value after hitting end in region read Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 11/90] dp83640: reverse arguments to list_add_tail Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 12/90] fq_codel: fix TCA_FQ_CODEL_DROP_BATCH_SIZE sanity checks Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 13/90] ipv6: Use global sernum for dst validation with nexthop objects Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 14/90] mlxsw: spectrum_acl_tcam: Position vchunk in a vregion list properly Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 15/90] neigh: send protocol value in neighbor create notification Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 16/90] net: dsa: Do not leave DSA master with NULL netdev_ops Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 17/90] net: macb: fix an issue about leak related system resources Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 18/90] net: macsec: preserve ingress frame ordering Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 19/90] net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 20/90] net_sched: sch_skbprio: add message validation to skbprio_change() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 21/90] net: stricter validation of untrusted gso packets Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 22/90] net: tc35815: Fix phydev supported/advertising mask Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 23/90] net/tls: Fix sk_psock refcnt leak in bpf_exec_tx_verdict() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 24/90] net/tls: Fix sk_psock refcnt leak when in tls_data_ready() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 25/90] net: usb: qmi_wwan: add support for DW5816e Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 26/90] nfp: abm: fix a memory leak bug Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 27/90] sch_choke: avoid potential panic in choke_reset() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 28/90] sch_sfq: validate silly quantum values Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 29/90] tipc: fix partial topology connection closure Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 30/90] tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040 Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 31/90] bnxt_en: Fix VF anti-spoof filter setup Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 32/90] bnxt_en: Reduce BNXT_MSIX_VEC_MAX value to supported CQs per PF Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 33/90] bnxt_en: Improve AER slot reset Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 34/90] bnxt_en: Return error when allocating zero size context memory Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 35/90] bnxt_en: Fix VLAN acceleration handling in bnxt_fix_features() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 36/90] net/mlx5: DR, On creation set CQs arm_db member to right value Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 37/90] net/mlx5: Fix forced completion access non initialized command entry Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 38/90] net/mlx5: Fix command entry leak in Internal Error State Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 39/90] net: mvpp2: prevent buffer overflow in mvpp22_rss_ctx() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 40/90] net: mvpp2: cls: Prevent buffer overflow in mvpp2_ethtool_cls_rule_del() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 41/90] HID: wacom: Read HID_DG_CONTACTMAX directly for non-generic devices Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 42/90] sctp: Fix bundling of SHUTDOWN with COOKIE-ACK Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 43/90] Revert "HID: wacom: generic: read the number of expected touches on a per collection basis" Greg Kroah-Hartman
2020-05-13  9:44 ` Greg Kroah-Hartman [this message]
2020-05-13  9:44 ` [PATCH 5.4 45/90] HID: wacom: Report 2nd-gen Intuos Pro S center button status over BT Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 46/90] USB: uas: add quirk for LaCie 2Big Quadra Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 47/90] usb: chipidea: msm: Ensure proper controller reset using role switch API Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 48/90] USB: serial: garmin_gps: add sanity checking for data length Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 49/90] tracing: Add a vmalloc_sync_mappings() for safe measure Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 50/90] crypto: arch/nhpoly1305 - process in explicit 4k chunks Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 51/90] KVM: s390: Remove false WARN_ON_ONCE for the PQAP instruction Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 52/90] KVM: VMX: Explicitly clear RFLAGS.CF and RFLAGS.ZF in VM-Exit RSB path Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 53/90] KVM: arm: vgic: Fix limit condition when writing to GICD_I[CS]ACTIVER Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 54/90] KVM: arm64: Fix 32bit PC wrap-around Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 55/90] arm64: hugetlb: avoid potential NULL dereference Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 56/90] drm: ingenic-drm: add MODULE_DEVICE_TABLE Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 57/90] ipc/mqueue.c: change __do_notify() to bypass check_kill_permission() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 58/90] epoll: atomically remove wait entry on wake up Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 59/90] eventpoll: fix missing wakeup for ovflist in ep_poll_callback Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 60/90] mm/page_alloc: fix watchdog soft lockups during set_zone_contiguous() Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 61/90] mm: limit boost_watermark on small zones Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 62/90] ceph: fix endianness bug when handling MDS session feature bits Greg Kroah-Hartman
2020-05-13  9:44 ` [PATCH 5.4 63/90] ceph: demote quotarealm lookup warning to a debug message Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 64/90] staging: gasket: Check the return value of gasket_get_bar_index() Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 65/90] coredump: fix crash when umh is disabled Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 66/90] riscv: set max_pfn to the PFN of the last page Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 67/90] iocost: protect iocg->abs_vdebt with iocg->waitq.lock Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 68/90] batman-adv: fix batadv_nc_random_weight_tq Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 69/90] batman-adv: Fix refcnt leak in batadv_show_throughput_override Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 70/90] batman-adv: Fix refcnt leak in batadv_store_throughput_override Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 71/90] batman-adv: Fix refcnt leak in batadv_v_ogm_process Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 72/90] x86/entry/64: Fix unwind hints in register clearing code Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 73/90] x86/entry/64: Fix unwind hints in kernel exit path Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 74/90] x86/entry/64: Fix unwind hints in rewind_stack_do_exit() Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 75/90] x86/unwind/orc: Dont skip the first frame for inactive tasks Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 76/90] x86/unwind/orc: Prevent unwinding before ORC initialization Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 77/90] x86/unwind/orc: Fix error path for bad ORC entry type Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 78/90] x86/unwind/orc: Fix premature unwind stoppage due to IRET frames Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 79/90] KVM: x86: Fixes posted interrupt check for IRQs delivery modes Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 80/90] arch/x86/kvm/svm/sev.c: change flag passed to GUP fast in sev_pin_memory() Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 81/90] netfilter: nat: never update the UDP checksum when its 0 Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 82/90] netfilter: nf_osf: avoid passing pointer to local var Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 83/90] objtool: Fix stack offset tracking for indirect CFAs Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 84/90] iommu/virtio: Reverse arguments to list_add Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 85/90] scripts/decodecode: fix trapping instruction formatting Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 86/90] mm, memcg: fix error return value of mem_cgroup_css_alloc() Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 87/90] bdi: move bdi_dev_name out of line Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 88/90] bdi: add a ->dev_name field to struct backing_dev_info Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 89/90] fsnotify: replace inode pointer with an object id Greg Kroah-Hartman
2020-05-13  9:45 ` [PATCH 5.4 90/90] fanotify: merge duplicate events on parent and child Greg Kroah-Hartman
2020-05-13 13:46 ` [PATCH 5.4 00/90] 5.4.41-rc1 review Jon Hunter
2020-05-13 17:03 ` Guenter Roeck
2020-05-13 17:50 ` Naresh Kamboju
2020-05-13 23:01 ` shuah

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=20200513094413.466529428@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jkosina@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    --cc=syzbot+7bf5a7b0f0a1f9446f4c@syzkaller.appspotmail.com \
    /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).