]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - queue-5.10/usb-cdc-wdm-close-race-between-read-and-workqueue.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / queue-5.10 / usb-cdc-wdm-close-race-between-read-and-workqueue.patch
CommitLineData
978ed369
GKH
1From 339f83612f3a569b194680768b22bf113c26a29d Mon Sep 17 00:00:00 2001
2From: Oliver Neukum <oneukum@suse.com>
3Date: Thu, 14 Mar 2024 12:50:48 +0100
4Subject: usb: cdc-wdm: close race between read and workqueue
5
6From: Oliver Neukum <oneukum@suse.com>
7
8commit 339f83612f3a569b194680768b22bf113c26a29d upstream.
9
10wdm_read() cannot race with itself. However, in
11service_outstanding_interrupt() it can race with the
12workqueue, which can be triggered by error handling.
13
14Hence we need to make sure that the WDM_RESPONDING
15flag is not just only set but tested.
16
17Fixes: afba937e540c9 ("USB: CDC WDM driver")
18Cc: stable <stable@kernel.org>
19Signed-off-by: Oliver Neukum <oneukum@suse.com>
20Link: https://lore.kernel.org/r/20240314115132.3907-1-oneukum@suse.com
21Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22---
23 drivers/usb/class/cdc-wdm.c | 6 +++++-
24 1 file changed, 5 insertions(+), 1 deletion(-)
25
26--- a/drivers/usb/class/cdc-wdm.c
27+++ b/drivers/usb/class/cdc-wdm.c
28@@ -471,6 +471,7 @@ out_free_mem:
29 static int service_outstanding_interrupt(struct wdm_device *desc)
30 {
31 int rv = 0;
32+ int used;
33
34 /* submit read urb only if the device is waiting for it */
35 if (!desc->resp_count || !--desc->resp_count)
36@@ -485,7 +486,10 @@ static int service_outstanding_interrupt
37 goto out;
38 }
39
40- set_bit(WDM_RESPONDING, &desc->flags);
41+ used = test_and_set_bit(WDM_RESPONDING, &desc->flags);
42+ if (used)
43+ goto out;
44+
45 spin_unlock_irq(&desc->iuspin);
46 rv = usb_submit_urb(desc->response, GFP_KERNEL);
47 spin_lock_irq(&desc->iuspin);