From: Greg Kroah-Hartman Date: Fri, 27 Jun 2014 22:30:41 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.4.96~40 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=47d7c4723a054882b74a31e5d81667c9d1240d1f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: usb-sierra-fix-aa-deadlock-in-open-error-path.patch usb-sierra-fix-remote-wakeup.patch usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch usb-sierra-fix-use-after-free-at-suspend-resume.patch --- diff --git a/queue-3.4/series b/queue-3.4/series index 254a5a70b66..ce1f7a596eb 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -21,3 +21,8 @@ usb-usb_wwan-fix-write-and-suspend-race.patch usb-usb_wwan-fix-urb-leak-at-shutdown.patch usb-usb_wwan-fix-potential-null-deref-at-resume.patch usb-usb_wwan-fix-potential-blocked-i-o-after-resume.patch +usb-sierra-fix-aa-deadlock-in-open-error-path.patch +usb-sierra-fix-use-after-free-at-suspend-resume.patch +usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch +usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch +usb-sierra-fix-remote-wakeup.patch diff --git a/queue-3.4/usb-sierra-fix-aa-deadlock-in-open-error-path.patch b/queue-3.4/usb-sierra-fix-aa-deadlock-in-open-error-path.patch new file mode 100644 index 00000000000..0f67fb64a3a --- /dev/null +++ b/queue-3.4/usb-sierra-fix-aa-deadlock-in-open-error-path.patch @@ -0,0 +1,58 @@ +From 353fe198602e8b4d1c7bdcceb8e60955087201b1 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 26 May 2014 19:22:50 +0200 +Subject: USB: sierra: fix AA deadlock in open error path + +From: Johan Hovold + +commit 353fe198602e8b4d1c7bdcceb8e60955087201b1 upstream. + +Fix AA deadlock in open error path that would call close() and try to +grab the already held disc_mutex. + +Fixes: b9a44bc19f48 ("sierra: driver urb handling improvements") + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/sierra.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -867,14 +867,9 @@ static int sierra_open(struct tty_struct + usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN); + + err = sierra_submit_rx_urbs(port, GFP_KERNEL); +- if (err) { +- /* get rid of everything as in close */ +- sierra_close(port); +- /* restore balance for autopm */ +- if (!serial->disconnected) +- usb_autopm_put_interface(serial->interface); +- return err; +- } ++ if (err) ++ goto err_submit; ++ + sierra_send_setup(port); + + serial->interface->needs_remote_wakeup = 1; +@@ -884,6 +879,16 @@ static int sierra_open(struct tty_struct + usb_autopm_put_interface(serial->interface); + + return 0; ++ ++err_submit: ++ sierra_stop_rx_urbs(port); ++ ++ for (i = 0; i < portdata->num_in_urbs; i++) { ++ sierra_release_urb(portdata->in_urbs[i]); ++ portdata->in_urbs[i] = NULL; ++ } ++ ++ return err; + } + + diff --git a/queue-3.4/usb-sierra-fix-remote-wakeup.patch b/queue-3.4/usb-sierra-fix-remote-wakeup.patch new file mode 100644 index 00000000000..aa10b6bf350 --- /dev/null +++ b/queue-3.4/usb-sierra-fix-remote-wakeup.patch @@ -0,0 +1,69 @@ +From 80cc0fcbdaeaf10d04ba27779a2d7ceb73d2717a Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 26 May 2014 19:22:54 +0200 +Subject: USB: sierra: fix remote wakeup + +From: Johan Hovold + +commit 80cc0fcbdaeaf10d04ba27779a2d7ceb73d2717a upstream. + +Make sure that needs_remote_wake up is always set when there are open +ports. + +Currently close() would unconditionally set needs_remote_wakeup to 0 +even though there might still be open ports. This could lead to blocked +input and possibly dropped data on devices that do not support remote +wakeup (and which must therefore not be runtime suspended while open). + +Add an open_ports counter (protected by the susp_lock) and only clear +needs_remote_wakeup when the last port is closed. + +Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while +online") + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/sierra.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -59,6 +59,7 @@ struct sierra_intf_private { + spinlock_t susp_lock; + unsigned int suspended:1; + int in_flight; ++ unsigned int open_ports; + }; + + static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) +@@ -813,7 +814,6 @@ static void sierra_close(struct usb_seri + if (serial->dev) { + mutex_lock(&serial->disc_mutex); + if (!serial->disconnected) { +- serial->interface->needs_remote_wakeup = 0; + /* odd error handling due to pm counters */ + if (!usb_autopm_get_interface(serial->interface)) + sierra_send_setup(port); +@@ -824,6 +824,8 @@ static void sierra_close(struct usb_seri + mutex_unlock(&serial->disc_mutex); + spin_lock_irq(&intfdata->susp_lock); + portdata->opened = 0; ++ if (--intfdata->open_ports == 0) ++ serial->interface->needs_remote_wakeup = 0; + spin_unlock_irq(&intfdata->susp_lock); + + for (;;) { +@@ -884,9 +886,10 @@ static int sierra_open(struct tty_struct + + sierra_send_setup(port); + +- serial->interface->needs_remote_wakeup = 1; + spin_lock_irq(&intfdata->susp_lock); + portdata->opened = 1; ++ if (++intfdata->open_ports == 1) ++ serial->interface->needs_remote_wakeup = 1; + spin_unlock_irq(&intfdata->susp_lock); + usb_autopm_put_interface(serial->interface); + diff --git a/queue-3.4/usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch b/queue-3.4/usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch new file mode 100644 index 00000000000..8f333763552 --- /dev/null +++ b/queue-3.4/usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch @@ -0,0 +1,49 @@ +From 7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 26 May 2014 19:22:52 +0200 +Subject: USB: sierra: fix urb and memory leak in resume error path + +From: Johan Hovold + +commit 7fdd26a01eb7b6cb6855ff8f69ef4a720720dfcb upstream. + +Neither the transfer buffer or the urb itself were released in the +resume error path for delayed writes. Also on errors, the remainder of +the queue was not even processed, which leads to further urb and buffer +leaks. + +The same error path also failed to balance the outstanding-urb counter, +something which results in degraded throughput or completely blocked +writes. + +Fix this by releasing urb and buffer and balancing counters on errors, +and by always processing the whole queue even when submission of one urb +fails. + +Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while +online") + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/sierra.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -1070,8 +1070,12 @@ static int sierra_resume(struct usb_seri + if (err < 0) { + intfdata->in_flight--; + usb_unanchor_urb(urb); +- usb_scuttle_anchored_urbs(&portdata->delayed); +- break; ++ kfree(urb->transfer_buffer); ++ usb_free_urb(urb); ++ spin_lock(&portdata->lock); ++ portdata->outstanding_urbs--; ++ spin_unlock(&portdata->lock); ++ continue; + } + } + diff --git a/queue-3.4/usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch b/queue-3.4/usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch new file mode 100644 index 00000000000..4c44cc08a93 --- /dev/null +++ b/queue-3.4/usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch @@ -0,0 +1,51 @@ +From 014333f77c0b71123d6ef7d31a9724e0699c9548 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 26 May 2014 19:22:53 +0200 +Subject: USB: sierra: fix urb and memory leak on disconnect + +From: Johan Hovold + +commit 014333f77c0b71123d6ef7d31a9724e0699c9548 upstream. + +The delayed-write queue was never emptied on disconnect, something which +would lead to leaked urbs and transfer buffers if the device is +disconnected before being runtime resumed due to a write. + +Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while +online") + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/sierra.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -801,6 +801,7 @@ static void sierra_close(struct usb_seri + struct usb_serial *serial = port->serial; + struct sierra_port_private *portdata; + struct sierra_intf_private *intfdata = port->serial->private; ++ struct urb *urb; + + + dev_dbg(&port->dev, "%s\n", __func__); +@@ -825,6 +826,17 @@ static void sierra_close(struct usb_seri + portdata->opened = 0; + spin_unlock_irq(&intfdata->susp_lock); + ++ for (;;) { ++ urb = usb_get_from_anchor(&portdata->delayed); ++ if (!urb) ++ break; ++ kfree(urb->transfer_buffer); ++ usb_free_urb(urb); ++ usb_autopm_put_interface_async(serial->interface); ++ spin_lock(&portdata->lock); ++ portdata->outstanding_urbs--; ++ spin_unlock(&portdata->lock); ++ } + + /* Stop reading urbs */ + sierra_stop_rx_urbs(port); diff --git a/queue-3.4/usb-sierra-fix-use-after-free-at-suspend-resume.patch b/queue-3.4/usb-sierra-fix-use-after-free-at-suspend-resume.patch new file mode 100644 index 00000000000..d544866b544 --- /dev/null +++ b/queue-3.4/usb-sierra-fix-use-after-free-at-suspend-resume.patch @@ -0,0 +1,55 @@ +From 8452727de70f6ad850cd6d0aaa18b5d9050aa63b Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 26 May 2014 19:22:51 +0200 +Subject: USB: sierra: fix use after free at suspend/resume + +From: Johan Hovold + +commit 8452727de70f6ad850cd6d0aaa18b5d9050aa63b upstream. + +Fix use after free or NULL-pointer dereference during suspend and +resume. + +The port data may never have been allocated (port probe failed) +or may already have been released by port_remove (e.g. driver is +unloaded) when suspend and resume are called. + +Fixes: e6929a9020ac ("USB: support for autosuspend in sierra while +online") + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/sierra.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -999,6 +999,7 @@ static void sierra_release(struct usb_se + portdata = usb_get_serial_port_data(port); + if (!portdata) + continue; ++ usb_set_serial_port_data(port, NULL); + kfree(portdata); + } + kfree(serial->private); +@@ -1015,6 +1016,8 @@ static void stop_read_write_urbs(struct + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + portdata = usb_get_serial_port_data(port); ++ if (!portdata) ++ continue; + sierra_stop_rx_urbs(port); + usb_kill_anchored_urbs(&portdata->active); + } +@@ -1057,6 +1060,9 @@ static int sierra_resume(struct usb_seri + port = serial->port[i]; + portdata = usb_get_serial_port_data(port); + ++ if (!portdata) ++ continue; ++ + while ((urb = usb_get_from_anchor(&portdata->delayed))) { + usb_anchor_urb(urb, &portdata->active); + intfdata->in_flight++;