Commit 16142775 authored by Johan Hovold's avatar Johan Hovold Committed by Ben Hutchings

USB: cdc-acm: fix write and resume race

commit e144ed28 upstream.

Fix race between write() and resume() due to improper locking that could
lead to writes being reordered.

Resume must be done atomically and susp_count be protected by the
write_lock in order to prevent racing with write(). This could otherwise
lead to writes being reordered if write() grabs the write_lock after
susp_count is decremented, but before the delayed urb is submitted.

Fixes: 11ea859d ("USB: additional power savings for cdc-acm devices
that support remote wakeup")
Signed-off-by: default avatarJohan Hovold <jhovold@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2:
 - Adjust context
 - Move mutex_lock(acm->mutex) above acquisition of spinlocks]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 3627c075
......@@ -1371,28 +1371,21 @@ static int acm_resume(struct usb_interface *intf)
struct acm *acm = usb_get_intfdata(intf);
struct acm_wb *wb;
int rv = 0;
int cnt;
mutex_lock(&acm->mutex);
spin_lock_irq(&acm->read_lock);
acm->susp_count -= 1;
cnt = acm->susp_count;
spin_unlock_irq(&acm->read_lock);
spin_lock(&acm->write_lock);
if (cnt)
return 0;
if (--acm->susp_count)
goto out;
mutex_lock(&acm->mutex);
if (acm->port.count) {
rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);
rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
spin_lock_irq(&acm->write_lock);
if (acm->delayed_wb) {
wb = acm->delayed_wb;
acm->delayed_wb = NULL;
spin_unlock_irq(&acm->write_lock);
acm_start_wb(acm, wb);
} else {
spin_unlock_irq(&acm->write_lock);
}
/*
......@@ -1400,13 +1393,15 @@ static int acm_resume(struct usb_interface *intf)
* do the write path at all cost
*/
if (rv < 0)
goto err_out;
goto out;
rv = acm_submit_read_urbs(acm, GFP_NOIO);
rv = acm_submit_read_urbs(acm, GFP_ATOMIC);
}
err_out:
out:
spin_unlock(&acm->write_lock);
spin_unlock_irq(&acm->read_lock);
mutex_unlock(&acm->mutex);
return rv;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment