Commit 2b626dc1 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: cdc-acm: fix possible deadlock with multiple openers

The lock must be dropped before usb_autopm_interface_put() is called
Signed-off-by: default avatarOliver Neukum <oliver@neukum.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d7e18a9f
...@@ -553,7 +553,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -553,7 +553,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
acm = acm_table[tty->index]; acm = acm_table[tty->index];
if (!acm || !acm->dev) if (!acm || !acm->dev)
goto err_out; goto out;
else else
rv = 0; rv = 0;
...@@ -569,8 +569,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -569,8 +569,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
mutex_lock(&acm->mutex); mutex_lock(&acm->mutex);
if (acm->port.count++) { if (acm->port.count++) {
mutex_unlock(&acm->mutex);
usb_autopm_put_interface(acm->control); usb_autopm_put_interface(acm->control);
goto done; goto out;
} }
acm->ctrlurb->dev = acm->dev; acm->ctrlurb->dev = acm->dev;
...@@ -599,18 +600,18 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -599,18 +600,18 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
set_bit(ASYNCB_INITIALIZED, &acm->port.flags); set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
rv = tty_port_block_til_ready(&acm->port, tty, filp); rv = tty_port_block_til_ready(&acm->port, tty, filp);
tasklet_schedule(&acm->urb_task); tasklet_schedule(&acm->urb_task);
done:
mutex_unlock(&acm->mutex); mutex_unlock(&acm->mutex);
err_out: out:
mutex_unlock(&open_mutex); mutex_unlock(&open_mutex);
return rv; return rv;
full_bailout: full_bailout:
usb_kill_urb(acm->ctrlurb); usb_kill_urb(acm->ctrlurb);
bail_out: bail_out:
usb_autopm_put_interface(acm->control);
acm->port.count--; acm->port.count--;
mutex_unlock(&acm->mutex); mutex_unlock(&acm->mutex);
usb_autopm_put_interface(acm->control);
early_bail: early_bail:
mutex_unlock(&open_mutex); mutex_unlock(&open_mutex);
tty_port_tty_set(&acm->port, NULL); tty_port_tty_set(&acm->port, NULL);
......
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