Sometimes, acm_tty_hangup and acm_tty_close are called concurrently. This results in acm pointer being null in acm_tty_hangup and panics when it is dereferenced. Signed-off-by: Vincent Palatin <vpalatin@xxxxxxxxxxxx> --- drivers/usb/class/cdc-acm.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index dac7676..3d389f3 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -539,7 +539,6 @@ static void acm_port_down(struct acm *acm) { int i; - mutex_lock(&open_mutex); if (acm->dev) { usb_autopm_get_interface(acm->control); acm_set_control(acm, acm->ctrlout = 0); @@ -551,14 +550,19 @@ static void acm_port_down(struct acm *acm) acm->control->needs_remote_wakeup = 0; usb_autopm_put_interface(acm->control); } - mutex_unlock(&open_mutex); } static void acm_tty_hangup(struct tty_struct *tty) { - struct acm *acm = tty->driver_data; - tty_port_hangup(&acm->port); - acm_port_down(acm); + struct acm *acm; + + mutex_lock(&open_mutex); + acm = tty->driver_data; + if (acm) { + tty_port_hangup(&acm->port); + acm_port_down(acm); + } + mutex_unlock(&open_mutex); } static void acm_tty_close(struct tty_struct *tty, struct file *filp) @@ -579,7 +583,9 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) mutex_unlock(&open_mutex); return; } + mutex_lock(&open_mutex); acm_port_down(acm); + mutex_unlock(&open_mutex); tty_port_close_end(&acm->port, tty); tty_port_tty_set(&acm->port, NULL); } -- 1.7.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html