usb: cdc-wdm: close race between read and workqueue
commit339f83612f
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:
parent
2e82b8d423
commit
19f955ad94
|
@ -485,6 +485,7 @@ out_free_mem:
|
|||
static int service_outstanding_interrupt(struct wdm_device *desc)
|
||||
{
|
||||
int rv = 0;
|
||||
int used;
|
||||
|
||||
/* submit read urb only if the device is waiting for it */
|
||||
if (!desc->resp_count || !--desc->resp_count)
|
||||
|
@ -499,7 +500,10 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
|
|||
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);
|
||||
rv = usb_submit_urb(desc->response, GFP_KERNEL);
|
||||
spin_lock_irq(&desc->iuspin);
|
||||
|
|
Loading…
Reference in New Issue