Skip to content

Commit 339f836

Browse files
oneukumgregkh
authored andcommitted
usb: cdc-wdm: close race between read and workqueue
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: afba937 ("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>
1 parent 5d69a3b commit 339f836

1 file changed

Lines changed: 5 additions & 1 deletion

File tree

drivers/usb/class/cdc-wdm.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ static ssize_t wdm_write
485485
static int service_outstanding_interrupt(struct wdm_device *desc)
486486
{
487487
int rv = 0;
488+
int used;
488489

489490
/* submit read urb only if the device is waiting for it */
490491
if (!desc->resp_count || !--desc->resp_count)
@@ -499,7 +500,10 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
499500
goto out;
500501
}
501502

502-
set_bit(WDM_RESPONDING, &desc->flags);
503+
used = test_and_set_bit(WDM_RESPONDING, &desc->flags);
504+
if (used)
505+
goto out;
506+
503507
spin_unlock_irq(&desc->iuspin);
504508
rv = usb_submit_urb(desc->response, GFP_KERNEL);
505509
spin_lock_irq(&desc->iuspin);

0 commit comments

Comments
 (0)