mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
usb: cdc-wdm: close race between read and workqueue
commit 339f83612f3a569b194680768b22bf113c26a29d upstream.
wdm_read() cannot race with itself. However, in
service_outstanding_interrupt() it can race with the
workqueue, which can be triggered by error handling.
Hence we need to make sure that the WDM_RESPONDING
flag is not just only set but tested.
Fixes: afba937e54 ("USB: CDC WDM driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Link: https://lore.kernel.org/r/20240314115132.3907-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
181f92abda
commit
916cd2fcbc
@@ -485,6 +485,7 @@ out_free_mem:
|
|||||||
static int service_outstanding_interrupt(struct wdm_device *desc)
|
static int service_outstanding_interrupt(struct wdm_device *desc)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
int used;
|
||||||
|
|
||||||
/* submit read urb only if the device is waiting for it */
|
/* submit read urb only if the device is waiting for it */
|
||||||
if (!desc->resp_count || !--desc->resp_count)
|
if (!desc->resp_count || !--desc->resp_count)
|
||||||
@@ -499,7 +500,10 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_bit(WDM_RESPONDING, &desc->flags);
|
used = test_and_set_bit(WDM_RESPONDING, &desc->flags);
|
||||||
|
if (used)
|
||||||
|
goto out;
|
||||||
|
|
||||||
spin_unlock_irq(&desc->iuspin);
|
spin_unlock_irq(&desc->iuspin);
|
||||||
rv = usb_submit_urb(desc->response, GFP_KERNEL);
|
rv = usb_submit_urb(desc->response, GFP_KERNEL);
|
||||||
spin_lock_irq(&desc->iuspin);
|
spin_lock_irq(&desc->iuspin);
|
||||||
|
|||||||
Reference in New Issue
Block a user