From: Greg Kroah-Hartman Date: Fri, 27 Jun 2014 22:30:25 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.4.96~42 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b5ccc48a9c09dd0db39bebb482a4fa8ca4c1c96d;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-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.14/series b/queue-3.14/series index 8f6ad0d513b..2cba8f43994 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -44,3 +44,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.14/usb-sierra-fix-aa-deadlock-in-open-error-path.patch b/queue-3.14/usb-sierra-fix-aa-deadlock-in-open-error-path.patch new file mode 100644 index 00000000000..bb2fc626ce8 --- /dev/null +++ b/queue-3.14/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 +@@ -816,14 +816,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; +@@ -833,6 +828,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.14/usb-sierra-fix-remote-wakeup.patch b/queue-3.14/usb-sierra-fix-remote-wakeup.patch new file mode 100644 index 00000000000..dac31e1727a --- /dev/null +++ b/queue-3.14/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 +@@ -58,6 +58,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) +@@ -768,7 +769,6 @@ static void sierra_close(struct usb_seri + + 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); +@@ -779,6 +779,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 (;;) { +@@ -834,9 +836,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.14/usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch b/queue-3.14/usb-sierra-fix-urb-and-memory-leak-in-resume-error-path.patch new file mode 100644 index 00000000000..6a37abe3340 --- /dev/null +++ b/queue-3.14/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 +@@ -1004,8 +1004,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.14/usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch b/queue-3.14/usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch new file mode 100644 index 00000000000..eae9cdc9d7e --- /dev/null +++ b/queue-3.14/usb-sierra-fix-urb-and-memory-leak-on-disconnect.patch @@ -0,0 +1,52 @@ +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 | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -759,6 +759,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; + + portdata = usb_get_serial_port_data(port); + +@@ -780,6 +781,18 @@ 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); ++ } ++ + sierra_stop_rx_urbs(port); + for (i = 0; i < portdata->num_in_urbs; i++) { + sierra_release_urb(portdata->in_urbs[i]); diff --git a/queue-3.14/usb-sierra-fix-use-after-free-at-suspend-resume.patch b/queue-3.14/usb-sierra-fix-use-after-free-at-suspend-resume.patch new file mode 100644 index 00000000000..af2d3591ada --- /dev/null +++ b/queue-3.14/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 +@@ -933,6 +933,7 @@ static int sierra_port_remove(struct usb + struct sierra_port_private *portdata; + + portdata = usb_get_serial_port_data(port); ++ usb_set_serial_port_data(port, NULL); + kfree(portdata); + + return 0; +@@ -949,6 +950,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); + } +@@ -991,6 +994,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++;