]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jan 2017 10:32:16 +0000 (11:32 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Jan 2017 10:32:16 +0000 (11:32 +0100)
added patches:
usb-host-xhci-fix-possible-wild-pointer-when-handling-abort-command.patch
usb-return-error-code-when-platform_get_irq-fails.patch
usb-serial-cyberjack-fix-null-deref-at-open.patch
usb-serial-garmin_gps-fix-memory-leak-on-failed-urb-submit.patch
usb-serial-io_edgeport-fix-null-deref-at-open.patch
usb-serial-io_ti-fix-another-null-deref-at-open.patch
usb-serial-io_ti-fix-i-o-after-disconnect.patch
usb-serial-io_ti-fix-null-deref-at-open.patch
usb-serial-iuu_phoenix-fix-null-deref-at-open.patch
usb-serial-keyspan_pda-verify-endpoints-at-probe.patch
usb-serial-kobil_sct-fix-null-deref-in-write.patch
usb-serial-mos7720-fix-null-deref-at-open.patch
usb-serial-mos7720-fix-parallel-probe.patch
usb-serial-mos7720-fix-parport-use-after-free-on-probe-errors.patch
usb-serial-mos7720-fix-use-after-free-on-probe-errors.patch
usb-serial-mos7840-fix-null-deref-at-open.patch
usb-serial-omninet-fix-null-derefs-at-open-and-disconnect.patch
usb-serial-oti6858-fix-null-deref-at-open.patch
usb-serial-pl2303-fix-null-deref-at-open.patch
usb-serial-quatech2-fix-sleep-while-atomic-in-close.patch
usb-serial-spcp8x5-fix-null-deref-at-open.patch
usb-serial-ti_usb_3410_5052-fix-null-deref-at-open.patch
usb-xhci-apply-xhci_pme_stuck_quirk-to-intel-apollo-lake.patch
usb-xhci-fix-return-value-of-xhci_setup_device.patch
usb-xhci-hold-lock-over-xhci_abort_cmd_ring.patch
usb-xhci-mem-use-passed-in-gfp-flags-instead-of-gfp_kernel.patch
xhci-free-xhci-virtual-devices-with-leaf-nodes-first.patch
xhci-handle-command-completion-and-timeout-race.patch

29 files changed:
queue-4.9/series
queue-4.9/usb-host-xhci-fix-possible-wild-pointer-when-handling-abort-command.patch [new file with mode: 0644]
queue-4.9/usb-return-error-code-when-platform_get_irq-fails.patch [new file with mode: 0644]
queue-4.9/usb-serial-cyberjack-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-garmin_gps-fix-memory-leak-on-failed-urb-submit.patch [new file with mode: 0644]
queue-4.9/usb-serial-io_edgeport-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-io_ti-fix-another-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-io_ti-fix-i-o-after-disconnect.patch [new file with mode: 0644]
queue-4.9/usb-serial-io_ti-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-iuu_phoenix-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-keyspan_pda-verify-endpoints-at-probe.patch [new file with mode: 0644]
queue-4.9/usb-serial-kobil_sct-fix-null-deref-in-write.patch [new file with mode: 0644]
queue-4.9/usb-serial-mos7720-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-mos7720-fix-parallel-probe.patch [new file with mode: 0644]
queue-4.9/usb-serial-mos7720-fix-parport-use-after-free-on-probe-errors.patch [new file with mode: 0644]
queue-4.9/usb-serial-mos7720-fix-use-after-free-on-probe-errors.patch [new file with mode: 0644]
queue-4.9/usb-serial-mos7840-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-omninet-fix-null-derefs-at-open-and-disconnect.patch [new file with mode: 0644]
queue-4.9/usb-serial-oti6858-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-pl2303-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-quatech2-fix-sleep-while-atomic-in-close.patch [new file with mode: 0644]
queue-4.9/usb-serial-spcp8x5-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-serial-ti_usb_3410_5052-fix-null-deref-at-open.patch [new file with mode: 0644]
queue-4.9/usb-xhci-apply-xhci_pme_stuck_quirk-to-intel-apollo-lake.patch [new file with mode: 0644]
queue-4.9/usb-xhci-fix-return-value-of-xhci_setup_device.patch [new file with mode: 0644]
queue-4.9/usb-xhci-hold-lock-over-xhci_abort_cmd_ring.patch [new file with mode: 0644]
queue-4.9/usb-xhci-mem-use-passed-in-gfp-flags-instead-of-gfp_kernel.patch [new file with mode: 0644]
queue-4.9/xhci-free-xhci-virtual-devices-with-leaf-nodes-first.patch [new file with mode: 0644]
queue-4.9/xhci-handle-command-completion-and-timeout-race.patch [new file with mode: 0644]

index ddc8b5e1702f85458c6c7b47e4d5308d3acee149..39d80a3a75c5ba2461a40dca4566adaa716ff99c 100644 (file)
@@ -33,3 +33,31 @@ usb-dummy-hcd-fix-bug-in-stop_activity-handle-ep0.patch
 usb-gadget-composite-test-get_alt-presence-instead-of-set_alt.patch
 usb-dwc3-core-avoid-overflow-events.patch
 usb-xhci-fix-possible-wild-pointer.patch
+usb-xhci-apply-xhci_pme_stuck_quirk-to-intel-apollo-lake.patch
+xhci-free-xhci-virtual-devices-with-leaf-nodes-first.patch
+usb-xhci-fix-return-value-of-xhci_setup_device.patch
+usb-host-xhci-fix-possible-wild-pointer-when-handling-abort-command.patch
+xhci-handle-command-completion-and-timeout-race.patch
+usb-xhci-hold-lock-over-xhci_abort_cmd_ring.patch
+usb-return-error-code-when-platform_get_irq-fails.patch
+usb-serial-omninet-fix-null-derefs-at-open-and-disconnect.patch
+usb-serial-quatech2-fix-sleep-while-atomic-in-close.patch
+usb-serial-pl2303-fix-null-deref-at-open.patch
+usb-serial-keyspan_pda-verify-endpoints-at-probe.patch
+usb-serial-spcp8x5-fix-null-deref-at-open.patch
+usb-serial-io_ti-fix-null-deref-at-open.patch
+usb-serial-io_ti-fix-another-null-deref-at-open.patch
+usb-serial-io_ti-fix-i-o-after-disconnect.patch
+usb-serial-iuu_phoenix-fix-null-deref-at-open.patch
+usb-serial-garmin_gps-fix-memory-leak-on-failed-urb-submit.patch
+usb-serial-ti_usb_3410_5052-fix-null-deref-at-open.patch
+usb-serial-io_edgeport-fix-null-deref-at-open.patch
+usb-serial-oti6858-fix-null-deref-at-open.patch
+usb-serial-cyberjack-fix-null-deref-at-open.patch
+usb-serial-kobil_sct-fix-null-deref-in-write.patch
+usb-serial-mos7840-fix-null-deref-at-open.patch
+usb-serial-mos7720-fix-null-deref-at-open.patch
+usb-serial-mos7720-fix-use-after-free-on-probe-errors.patch
+usb-serial-mos7720-fix-parport-use-after-free-on-probe-errors.patch
+usb-serial-mos7720-fix-parallel-probe.patch
+usb-xhci-mem-use-passed-in-gfp-flags-instead-of-gfp_kernel.patch
diff --git a/queue-4.9/usb-host-xhci-fix-possible-wild-pointer-when-handling-abort-command.patch b/queue-4.9/usb-host-xhci-fix-possible-wild-pointer-when-handling-abort-command.patch
new file mode 100644 (file)
index 0000000..ceed981
--- /dev/null
@@ -0,0 +1,36 @@
+From 2a7cfdf37b7c08ac29df4c62ea5ccb01474b6597 Mon Sep 17 00:00:00 2001
+From: Baolin Wang <baolin.wang@linaro.org>
+Date: Tue, 3 Jan 2017 18:28:47 +0200
+Subject: usb: host: xhci: Fix possible wild pointer when handling abort command
+
+From: Baolin Wang <baolin.wang@linaro.org>
+
+commit 2a7cfdf37b7c08ac29df4c62ea5ccb01474b6597 upstream.
+
+When current command was supposed to be aborted, host will free the command
+in handle_cmd_completion() function. But it might be still referenced by
+xhci->current_cmd, which need to set NULL.
+
+Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1368,8 +1368,11 @@ static void handle_cmd_completion(struct
+        */
+       if (cmd_comp_code == COMP_CMD_ABORT) {
+               xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
+-              if (cmd->status == COMP_CMD_ABORT)
++              if (cmd->status == COMP_CMD_ABORT) {
++                      if (xhci->current_cmd == cmd)
++                              xhci->current_cmd = NULL;
+                       goto event_handled;
++              }
+       }
+       cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3]));
diff --git a/queue-4.9/usb-return-error-code-when-platform_get_irq-fails.patch b/queue-4.9/usb-return-error-code-when-platform_get_irq-fails.patch
new file mode 100644 (file)
index 0000000..7a18db1
--- /dev/null
@@ -0,0 +1,40 @@
+From 28bedb5ae463b9f7e5195cbc93f1795e374bdef8 Mon Sep 17 00:00:00 2001
+From: Pan Bian <bianpan2016@163.com>
+Date: Tue, 3 Jan 2017 18:28:45 +0200
+Subject: usb: return error code when platform_get_irq fails
+
+From: Pan Bian <bianpan2016@163.com>
+
+commit 28bedb5ae463b9f7e5195cbc93f1795e374bdef8 upstream.
+
+In function xhci_mtk_probe(), variable ret takes the return value. Its
+value should be negative on failures. However, when the call to function
+platform_get_irq() fails, it does not set the error code, and 0 will be
+returned. 0 indicates no error. As a result, the callers of function
+xhci_mtk_probe() will not be able to detect the error. This patch fixes
+the bug by assigning the return value of platform_get_irq() to variable
+ret if it fails.
+
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mtk.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -560,8 +560,10 @@ static int xhci_mtk_probe(struct platfor
+               goto disable_ldos;
+       irq = platform_get_irq(pdev, 0);
+-      if (irq < 0)
++      if (irq < 0) {
++              ret = irq;
+               goto disable_clk;
++      }
+       /* Initialize dma_mask and coherent_dma_mask to 32-bits */
+       ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
diff --git a/queue-4.9/usb-serial-cyberjack-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-cyberjack-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..a7f9b88
--- /dev/null
@@ -0,0 +1,57 @@
+From 3dca01114dcecb1cf324534cd8d75fd1306a516b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:40 +0100
+Subject: USB: serial: cyberjack: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 3dca01114dcecb1cf324534cd8d75fd1306a516b upstream.
+
+Fix NULL-pointer dereference when clearing halt at open should the device
+lack a bulk-out endpoint.
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+PC is at cyberjack_open+0x40/0x9c [cyberjack]
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/cyberjack.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/usb/serial/cyberjack.c
++++ b/drivers/usb/serial/cyberjack.c
+@@ -50,6 +50,7 @@
+ #define CYBERJACK_PRODUCT_ID  0x0100
+ /* Function prototypes */
++static int cyberjack_attach(struct usb_serial *serial);
+ static int cyberjack_port_probe(struct usb_serial_port *port);
+ static int cyberjack_port_remove(struct usb_serial_port *port);
+ static int  cyberjack_open(struct tty_struct *tty,
+@@ -77,6 +78,7 @@ static struct usb_serial_driver cyberjac
+       .description =          "Reiner SCT Cyberjack USB card reader",
+       .id_table =             id_table,
+       .num_ports =            1,
++      .attach =               cyberjack_attach,
+       .port_probe =           cyberjack_port_probe,
+       .port_remove =          cyberjack_port_remove,
+       .open =                 cyberjack_open,
+@@ -100,6 +102,14 @@ struct cyberjack_private {
+       short           wrsent;         /* Data already sent */
+ };
++static int cyberjack_attach(struct usb_serial *serial)
++{
++      if (serial->num_bulk_out < serial->num_ports)
++              return -ENODEV;
++
++      return 0;
++}
++
+ static int cyberjack_port_probe(struct usb_serial_port *port)
+ {
+       struct cyberjack_private *priv;
diff --git a/queue-4.9/usb-serial-garmin_gps-fix-memory-leak-on-failed-urb-submit.patch b/queue-4.9/usb-serial-garmin_gps-fix-memory-leak-on-failed-urb-submit.patch
new file mode 100644 (file)
index 0000000..3948f71
--- /dev/null
@@ -0,0 +1,30 @@
+From c4ac4496e835b78a45dfbf74f6173932217e4116 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:41 +0100
+Subject: USB: serial: garmin_gps: fix memory leak on failed URB submit
+
+From: Johan Hovold <johan@kernel.org>
+
+commit c4ac4496e835b78a45dfbf74f6173932217e4116 upstream.
+
+Make sure to free the URB transfer buffer in case submission fails (e.g.
+due to a disconnect).
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/garmin_gps.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/garmin_gps.c
++++ b/drivers/usb/serial/garmin_gps.c
+@@ -1043,6 +1043,7 @@ static int garmin_write_bulk(struct usb_
+                  "%s - usb_submit_urb(write bulk) failed with status = %d\n",
+                               __func__, status);
+               count = status;
++              kfree(buffer);
+       }
+       /* we are done with this urb, so let the host driver
diff --git a/queue-4.9/usb-serial-io_edgeport-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-io_edgeport-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..ee74a78
--- /dev/null
@@ -0,0 +1,41 @@
+From 0dd408425eb21ddf26a692b3c8044c9e7d1a7948 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:42 +0100
+Subject: USB: serial: io_edgeport: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 0dd408425eb21ddf26a692b3c8044c9e7d1a7948 upstream.
+
+Fix NULL-pointer dereference when initialising URBs at open should a
+non-EPIC device lack a bulk-in or interrupt-in endpoint.
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000028
+...
+PC is at edge_open+0x24c/0x3e8 [io_edgeport]
+
+Note that the EPIC-device probe path has the required sanity checks so
+this makes those checks partially redundant.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_edgeport.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -2754,6 +2754,11 @@ static int edge_startup(struct usb_seria
+                                       EDGE_COMPATIBILITY_MASK1,
+                                       EDGE_COMPATIBILITY_MASK2 };
++      if (serial->num_bulk_in < 1 || serial->num_interrupt_in < 1) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              return -ENODEV;
++      }
++
+       dev = serial->dev;
+       /* create our private serial structure */
diff --git a/queue-4.9/usb-serial-io_ti-fix-another-null-deref-at-open.patch b/queue-4.9/usb-serial-io_ti-fix-another-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..c3fe48d
--- /dev/null
@@ -0,0 +1,68 @@
+From 4f9785cc99feeb3673993b471f646b4dbaec2cc1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:44 +0100
+Subject: USB: serial: io_ti: fix another NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 4f9785cc99feeb3673993b471f646b4dbaec2cc1 upstream.
+
+In case a device is left in "boot-mode" we must not register any port
+devices in order to avoid a NULL-pointer dereference on open due to
+missing endpoints. This could be used by a malicious device to trigger
+an OOPS:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+[<bf0caa84>] (edge_open [io_ti]) from [<bf0b0118>] (serial_port_activate+0x68/0x98 [usbserial])
+[<bf0b0118>] (serial_port_activate [usbserial]) from [<c0470ca4>] (tty_port_open+0x9c/0xe8)
+[<c0470ca4>] (tty_port_open) from [<bf0b0da0>] (serial_open+0x48/0x6c [usbserial])
+[<bf0b0da0>] (serial_open [usbserial]) from [<c0469178>] (tty_open+0xcc/0x5cc)
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_ti.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -1508,7 +1508,7 @@ stayinbootmode:
+       dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__);
+       serial->product_info.TiMode = TI_MODE_BOOT;
+-      return 0;
++      return 1;
+ }
+ static int ti_do_config(struct edgeport_port *port, int feature, int on)
+@@ -2563,14 +2563,18 @@ static int edge_startup(struct usb_seria
+       mutex_init(&edge_serial->es_lock);
+       edge_serial->serial = serial;
++      INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
+       usb_set_serial_data(serial, edge_serial);
+       status = download_fw(edge_serial);
+-      if (status) {
++      if (status < 0) {
+               kfree(edge_serial);
+               return status;
+       }
++      if (status > 0)
++              return 1;       /* bind but do not register any ports */
++
+       product_id = le16_to_cpu(
+                       edge_serial->serial->dev->descriptor.idProduct);
+@@ -2582,7 +2586,6 @@ static int edge_startup(struct usb_seria
+               }
+       }
+-      INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
+       edge_heartbeat_schedule(edge_serial);
+       return 0;
diff --git a/queue-4.9/usb-serial-io_ti-fix-i-o-after-disconnect.patch b/queue-4.9/usb-serial-io_ti-fix-i-o-after-disconnect.patch
new file mode 100644 (file)
index 0000000..2b5ed4c
--- /dev/null
@@ -0,0 +1,35 @@
+From 2330d0a853da260d8a9834a70df448032b9ff623 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:45 +0100
+Subject: USB: serial: io_ti: fix I/O after disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 2330d0a853da260d8a9834a70df448032b9ff623 upstream.
+
+Cancel the heartbeat work on driver unbind in order to avoid I/O after
+disconnect in case the port is held open.
+
+Note that the cancel in release() is still needed to stop the heartbeat
+after late probe errors.
+
+Fixes: 26c78daade0f ("USB: io_ti: Add heartbeat to keep idle EP/416 ports from disconnecting")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_ti.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2593,6 +2593,9 @@ static int edge_startup(struct usb_seria
+ static void edge_disconnect(struct usb_serial *serial)
+ {
++      struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
++
++      cancel_delayed_work_sync(&edge_serial->heartbeat_work);
+ }
+ static void edge_release(struct usb_serial *serial)
diff --git a/queue-4.9/usb-serial-io_ti-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-io_ti-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..21c2021
--- /dev/null
@@ -0,0 +1,43 @@
+From a323fefc6f5079844dc62ffeb54f491d0242ca35 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:43 +0100
+Subject: USB: serial: io_ti: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit a323fefc6f5079844dc62ffeb54f491d0242ca35 upstream.
+
+Fix NULL-pointer dereference when clearing halt at open should a
+malicious device lack the expected endpoints when in download mode.
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+[<bf011ed8>] (edge_open [io_ti]) from [<bf000118>] (serial_port_activate+0x68/0x98 [usbserial])
+[<bf000118>] (serial_port_activate [usbserial]) from [<c0470ca4>] (tty_port_open+0x9c/0xe8)
+[<c0470ca4>] (tty_port_open) from [<bf000da0>] (serial_open+0x48/0x6c [usbserial])
+[<bf000da0>] (serial_open [usbserial]) from [<c0469178>] (tty_open+0xcc/0x5cc)
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_ti.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2549,6 +2549,13 @@ static int edge_startup(struct usb_seria
+       int status;
+       u16 product_id;
++      /* Make sure we have the required endpoints when in download mode. */
++      if (serial->interface->cur_altsetting->desc.bNumEndpoints > 1) {
++              if (serial->num_bulk_in < serial->num_ports ||
++                              serial->num_bulk_out < serial->num_ports)
++                      return -ENODEV;
++      }
++
+       /* create our private serial structure */
+       edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
+       if (!edge_serial)
diff --git a/queue-4.9/usb-serial-iuu_phoenix-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-iuu_phoenix-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..e151477
--- /dev/null
@@ -0,0 +1,52 @@
+From 90507d54f712d81b74815ef3a4bbb555cd9fab2f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:47 +0100
+Subject: USB: serial: iuu_phoenix: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 90507d54f712d81b74815ef3a4bbb555cd9fab2f upstream.
+
+Fix NULL-pointer dereference at open should the device lack a bulk-in or
+bulk-out endpoint:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+PC is at iuu_open+0x78/0x59c [iuu_phoenix]
+
+Fixes: 07c3b1a10016 ("USB: remove broken usb-serial num_endpoints
+check")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/iuu_phoenix.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/serial/iuu_phoenix.c
++++ b/drivers/usb/serial/iuu_phoenix.c
+@@ -68,6 +68,16 @@ struct iuu_private {
+       u32 clk;
+ };
++static int iuu_attach(struct usb_serial *serial)
++{
++      unsigned char num_ports = serial->num_ports;
++
++      if (serial->num_bulk_in < num_ports || serial->num_bulk_out < num_ports)
++              return -ENODEV;
++
++      return 0;
++}
++
+ static int iuu_port_probe(struct usb_serial_port *port)
+ {
+       struct iuu_private *priv;
+@@ -1196,6 +1206,7 @@ static struct usb_serial_driver iuu_devi
+       .tiocmset = iuu_tiocmset,
+       .set_termios = iuu_set_termios,
+       .init_termios = iuu_init_termios,
++      .attach = iuu_attach,
+       .port_probe = iuu_port_probe,
+       .port_remove = iuu_port_remove,
+ };
diff --git a/queue-4.9/usb-serial-keyspan_pda-verify-endpoints-at-probe.patch b/queue-4.9/usb-serial-keyspan_pda-verify-endpoints-at-probe.patch
new file mode 100644 (file)
index 0000000..b4037c5
--- /dev/null
@@ -0,0 +1,55 @@
+From 5d9b0f859babe96175cd33d7162a9463a875ffde Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:48 +0100
+Subject: USB: serial: keyspan_pda: verify endpoints at probe
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5d9b0f859babe96175cd33d7162a9463a875ffde upstream.
+
+Check for the expected endpoints in attach() and fail loudly if not
+present.
+
+Note that failing to do this appears to be benign since da280e348866
+("USB: keyspan_pda: clean up write-urb busy handling") which prevents a
+NULL-pointer dereference in write() by never marking a non-existent
+write-urb as free.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/keyspan_pda.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/usb/serial/keyspan_pda.c
++++ b/drivers/usb/serial/keyspan_pda.c
+@@ -699,6 +699,19 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda
+ MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
+ #endif
++static int keyspan_pda_attach(struct usb_serial *serial)
++{
++      unsigned char num_ports = serial->num_ports;
++
++      if (serial->num_bulk_out < num_ports ||
++                      serial->num_interrupt_in < num_ports) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
+ static int keyspan_pda_port_probe(struct usb_serial_port *port)
+ {
+@@ -776,6 +789,7 @@ static struct usb_serial_driver keyspan_
+       .break_ctl =            keyspan_pda_break_ctl,
+       .tiocmget =             keyspan_pda_tiocmget,
+       .tiocmset =             keyspan_pda_tiocmset,
++      .attach =               keyspan_pda_attach,
+       .port_probe =           keyspan_pda_port_probe,
+       .port_remove =          keyspan_pda_port_remove,
+ };
diff --git a/queue-4.9/usb-serial-kobil_sct-fix-null-deref-in-write.patch b/queue-4.9/usb-serial-kobil_sct-fix-null-deref-in-write.patch
new file mode 100644 (file)
index 0000000..c340866
--- /dev/null
@@ -0,0 +1,59 @@
+From 21ce57840243c7b70fbc1ebd3dceeb70bb6e9e09 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:49 +0100
+Subject: USB: serial: kobil_sct: fix NULL-deref in write
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 21ce57840243c7b70fbc1ebd3dceeb70bb6e9e09 upstream.
+
+Fix NULL-pointer dereference in write() should the device lack the
+expected interrupt-out endpoint:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000054
+...
+PC is at kobil_write+0x144/0x2a0 [kobil_sct]
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/kobil_sct.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/usb/serial/kobil_sct.c
++++ b/drivers/usb/serial/kobil_sct.c
+@@ -51,6 +51,7 @@
+ /* Function prototypes */
++static int kobil_attach(struct usb_serial *serial);
+ static int kobil_port_probe(struct usb_serial_port *probe);
+ static int kobil_port_remove(struct usb_serial_port *probe);
+ static int  kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
+@@ -86,6 +87,7 @@ static struct usb_serial_driver kobil_de
+       .description =          "KOBIL USB smart card terminal",
+       .id_table =             id_table,
+       .num_ports =            1,
++      .attach =               kobil_attach,
+       .port_probe =           kobil_port_probe,
+       .port_remove =          kobil_port_remove,
+       .ioctl =                kobil_ioctl,
+@@ -113,6 +115,16 @@ struct kobil_private {
+ };
++static int kobil_attach(struct usb_serial *serial)
++{
++      if (serial->num_interrupt_out < serial->num_ports) {
++              dev_err(&serial->interface->dev, "missing interrupt-out endpoint\n");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
+ static int kobil_port_probe(struct usb_serial_port *port)
+ {
+       struct usb_serial *serial = port->serial;
diff --git a/queue-4.9/usb-serial-mos7720-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-mos7720-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..0955b7b
--- /dev/null
@@ -0,0 +1,41 @@
+From b05aebc25fdc5aeeac3ee29f0dc9f58dd07c13cc Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:50 +0100
+Subject: USB: serial: mos7720: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b05aebc25fdc5aeeac3ee29f0dc9f58dd07c13cc upstream.
+
+Fix NULL-pointer dereference at port open if a device lacks the expected
+bulk in and out endpoints.
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+[<bf071c20>] (mos7720_open [mos7720]) from [<bf0490e0>] (serial_port_activate+0x68/0x98 [usbserial])
+[<bf0490e0>] (serial_port_activate [usbserial]) from [<c0470ca4>] (tty_port_open+0x9c/0xe8)
+[<c0470ca4>] (tty_port_open) from [<bf049d98>] (serial_open+0x48/0x6c [usbserial])
+[<bf049d98>] (serial_open [usbserial]) from [<c0469178>] (tty_open+0xcc/0x5cc)
+
+Fixes: 0f64478cbc7a ("USB: add USB serial mos7720 driver")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7720.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -1920,6 +1920,11 @@ static int mos7720_startup(struct usb_se
+       u16 product;
+       int ret_val;
++      if (serial->num_bulk_in < 2 || serial->num_bulk_out < 2) {
++              dev_err(&serial->interface->dev, "missing bulk endpoints\n");
++              return -ENODEV;
++      }
++
+       product = le16_to_cpu(serial->dev->descriptor.idProduct);
+       dev = serial->dev;
diff --git a/queue-4.9/usb-serial-mos7720-fix-parallel-probe.patch b/queue-4.9/usb-serial-mos7720-fix-parallel-probe.patch
new file mode 100644 (file)
index 0000000..f9bb6fe
--- /dev/null
@@ -0,0 +1,93 @@
+From fde1faf872ed86d88e245191bc15a8e57368cd1c Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:53 +0100
+Subject: USB: serial: mos7720: fix parallel probe
+
+From: Johan Hovold <johan@kernel.org>
+
+commit fde1faf872ed86d88e245191bc15a8e57368cd1c upstream.
+
+A static usb-serial-driver structure that is used to initialise the
+interrupt URB was modified during probe depending on the currently
+probed device type, something which could break a parallel probe of a
+device of a different type.
+
+Fix this up by overriding the default completion callback for MCS7715
+devices in attach() instead. We may want to use two usb-serial driver
+instances for the two types later.
+
+Fixes: fb088e335d78 ("USB: serial: add support for serial port on the moschip 7715")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7720.c |   30 +++++++-----------------------
+ 1 file changed, 7 insertions(+), 23 deletions(-)
+
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -65,8 +65,6 @@ struct moschip_port {
+       struct urb              *write_urb_pool[NUM_URBS];
+ };
+-static struct usb_serial_driver moschip7720_2port_driver;
+-
+ #define USB_VENDOR_ID_MOSCHIP         0x9710
+ #define MOSCHIP_DEVICE_ID_7720                0x7720
+ #define MOSCHIP_DEVICE_ID_7715                0x7715
+@@ -970,25 +968,6 @@ static void mos7720_bulk_out_data_callba
+               tty_port_tty_wakeup(&mos7720_port->port->port);
+ }
+-/*
+- * mos77xx_probe
+- *    this function installs the appropriate read interrupt endpoint callback
+- *    depending on whether the device is a 7720 or 7715, thus avoiding costly
+- *    run-time checks in the high-frequency callback routine itself.
+- */
+-static int mos77xx_probe(struct usb_serial *serial,
+-                       const struct usb_device_id *id)
+-{
+-      if (id->idProduct == MOSCHIP_DEVICE_ID_7715)
+-              moschip7720_2port_driver.read_int_callback =
+-                      mos7715_interrupt_callback;
+-      else
+-              moschip7720_2port_driver.read_int_callback =
+-                      mos7720_interrupt_callback;
+-
+-      return 0;
+-}
+-
+ static int mos77xx_calc_num_ports(struct usb_serial *serial)
+ {
+       u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
+@@ -1949,6 +1928,12 @@ static int mos7720_startup(struct usb_se
+                       tmp->interrupt_in_endpointAddress;
+               serial->port[1]->interrupt_in_urb = NULL;
+               serial->port[1]->interrupt_in_buffer = NULL;
++
++              if (serial->port[0]->interrupt_in_urb) {
++                      struct urb *urb = serial->port[0]->interrupt_in_urb;
++
++                      urb->complete = mos7715_interrupt_callback;
++              }
+       }
+       /* setting configuration feature to one */
+@@ -2063,7 +2048,6 @@ static struct usb_serial_driver moschip7
+       .close                  = mos7720_close,
+       .throttle               = mos7720_throttle,
+       .unthrottle             = mos7720_unthrottle,
+-      .probe                  = mos77xx_probe,
+       .attach                 = mos7720_startup,
+       .release                = mos7720_release,
+       .port_probe             = mos7720_port_probe,
+@@ -2077,7 +2061,7 @@ static struct usb_serial_driver moschip7
+       .chars_in_buffer        = mos7720_chars_in_buffer,
+       .break_ctl              = mos7720_break,
+       .read_bulk_callback     = mos7720_bulk_in_callback,
+-      .read_int_callback      = NULL  /* dynamically assigned in probe() */
++      .read_int_callback      = mos7720_interrupt_callback,
+ };
+ static struct usb_serial_driver * const serial_drivers[] = {
diff --git a/queue-4.9/usb-serial-mos7720-fix-parport-use-after-free-on-probe-errors.patch b/queue-4.9/usb-serial-mos7720-fix-parport-use-after-free-on-probe-errors.patch
new file mode 100644 (file)
index 0000000..cc2c28f
--- /dev/null
@@ -0,0 +1,55 @@
+From 75dd211e773afcbc264677b0749d1cf7d937ab2d Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:52 +0100
+Subject: USB: serial: mos7720: fix parport use-after-free on probe errors
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 75dd211e773afcbc264677b0749d1cf7d937ab2d upstream.
+
+Do not submit the interrupt URB until after the parport has been
+successfully registered to avoid another use-after-free in the
+completion handler when accessing the freed parport private data in case
+of a racing completion.
+
+Fixes: b69578df7e98 ("USB: usbserial: mos7720: add support for parallel port on moschip 7715")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7720.c |   18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -1955,22 +1955,20 @@ static int mos7720_startup(struct usb_se
+       usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+                       (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
+-      /* start the interrupt urb */
+-      ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
+-      if (ret_val)
+-              dev_err(&dev->dev,
+-                      "%s - Error %d submitting control urb\n",
+-                      __func__, ret_val);
+-
+ #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
+       if (product == MOSCHIP_DEVICE_ID_7715) {
+               ret_val = mos7715_parport_init(serial);
+-              if (ret_val < 0) {
+-                      usb_kill_urb(serial->port[0]->interrupt_in_urb);
++              if (ret_val < 0)
+                       return ret_val;
+-              }
+       }
+ #endif
++      /* start the interrupt urb */
++      ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
++      if (ret_val) {
++              dev_err(&dev->dev, "failed to submit interrupt urb: %d\n",
++                      ret_val);
++      }
++
+       /* LSR For Port 1 */
+       read_mos_reg(serial, 0, MOS7720_LSR, &data);
+       dev_dbg(&dev->dev, "LSR:%x\n", data);
diff --git a/queue-4.9/usb-serial-mos7720-fix-use-after-free-on-probe-errors.patch b/queue-4.9/usb-serial-mos7720-fix-use-after-free-on-probe-errors.patch
new file mode 100644 (file)
index 0000000..dec986f
--- /dev/null
@@ -0,0 +1,50 @@
+From 91a1ff4d53c5184d383d0baeeaeab6f9736f2ff3 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:51 +0100
+Subject: USB: serial: mos7720: fix use-after-free on probe errors
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 91a1ff4d53c5184d383d0baeeaeab6f9736f2ff3 upstream.
+
+The interrupt URB was submitted on probe but never stopped on probe
+errors. This can lead to use-after-free issues in the completion
+handler when accessing the freed usb-serial struct:
+
+Unable to handle kernel paging request at virtual address 6b6b6be7
+...
+[<bf052e70>] (mos7715_interrupt_callback [mos7720]) from [<c052a894>] (__usb_hcd_giveback_urb+0x80/0x140)
+[<c052a894>] (__usb_hcd_giveback_urb) from [<c052a9a4>] (usb_hcd_giveback_urb+0x50/0x138)
+[<c052a9a4>] (usb_hcd_giveback_urb) from [<c0550684>] (musb_giveback+0xc8/0x1cc)
+
+Fixes: b69578df7e98 ("USB: usbserial: mos7720: add support for parallel port on moschip 7715")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7720.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -1965,8 +1965,10 @@ static int mos7720_startup(struct usb_se
+ #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
+       if (product == MOSCHIP_DEVICE_ID_7715) {
+               ret_val = mos7715_parport_init(serial);
+-              if (ret_val < 0)
++              if (ret_val < 0) {
++                      usb_kill_urb(serial->port[0]->interrupt_in_urb);
+                       return ret_val;
++              }
+       }
+ #endif
+       /* LSR For Port 1 */
+@@ -1978,6 +1980,8 @@ static int mos7720_startup(struct usb_se
+ static void mos7720_release(struct usb_serial *serial)
+ {
++      usb_kill_urb(serial->port[0]->interrupt_in_urb);
++
+ #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
+       /* close the parallel port */
diff --git a/queue-4.9/usb-serial-mos7840-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-mos7840-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..f6e06b2
--- /dev/null
@@ -0,0 +1,55 @@
+From 5c75633ef751dd4cd8f443dc35152c1ae563162e Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:55 +0100
+Subject: USB: serial: mos7840: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5c75633ef751dd4cd8f443dc35152c1ae563162e upstream.
+
+Fix NULL-pointer dereference in open() should the device lack the
+expected endpoints:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+PC is at mos7840_open+0x88/0x8dc [mos7840]
+
+Note that we continue to treat the interrupt-in endpoint as optional for
+now.
+
+Fixes: 3f5429746d91 ("USB: Moschip 7840 USB-Serial Driver")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -2116,6 +2116,17 @@ static int mos7840_calc_num_ports(struct
+       return mos7840_num_ports;
+ }
++static int mos7840_attach(struct usb_serial *serial)
++{
++      if (serial->num_bulk_in < serial->num_ports ||
++                      serial->num_bulk_out < serial->num_ports) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
+ static int mos7840_port_probe(struct usb_serial_port *port)
+ {
+       struct usb_serial *serial = port->serial;
+@@ -2391,6 +2402,7 @@ static struct usb_serial_driver moschip7
+       .tiocmset = mos7840_tiocmset,
+       .tiocmiwait = usb_serial_generic_tiocmiwait,
+       .get_icount = usb_serial_generic_get_icount,
++      .attach = mos7840_attach,
+       .port_probe = mos7840_port_probe,
+       .port_remove = mos7840_port_remove,
+       .read_bulk_callback = mos7840_bulk_in_callback,
diff --git a/queue-4.9/usb-serial-omninet-fix-null-derefs-at-open-and-disconnect.patch b/queue-4.9/usb-serial-omninet-fix-null-derefs-at-open-and-disconnect.patch
new file mode 100644 (file)
index 0000000..a7e8b1f
--- /dev/null
@@ -0,0 +1,68 @@
+From a5bc01949e3b19d8a23b5eabc6fc71bb50dc820e Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:58 +0100
+Subject: USB: serial: omninet: fix NULL-derefs at open and disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit a5bc01949e3b19d8a23b5eabc6fc71bb50dc820e upstream.
+
+Fix NULL-pointer dereferences at open() and disconnect() should the
+device lack the expected bulk-out endpoints:
+
+Unable to handle kernel NULL pointer dereference at virtual address 000000b4
+...
+[c0170ff0>] (__lock_acquire) from [<c0172f00>] (lock_acquire+0x108/0x264)
+[<c0172f00>] (lock_acquire) from [<c06a5090>] (_raw_spin_lock_irqsave+0x58/0x6c)
+[<c06a5090>] (_raw_spin_lock_irqsave) from [<c0470684>] (tty_port_tty_set+0x28/0xa4)
+[<c0470684>] (tty_port_tty_set) from [<bf08d384>] (omninet_open+0x30/0x40 [omninet])
+[<bf08d384>] (omninet_open [omninet]) from [<bf07c118>] (serial_port_activate+0x68/0x98 [usbserial])
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000234
+...
+[<bf01f418>] (omninet_disconnect [omninet]) from [<bf0016c0>] (usb_serial_disconnect+0xe4/0x100 [usbserial])
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/omninet.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/usb/serial/omninet.c
++++ b/drivers/usb/serial/omninet.c
+@@ -38,6 +38,7 @@ static int  omninet_write(struct tty_str
+                               const unsigned char *buf, int count);
+ static int  omninet_write_room(struct tty_struct *tty);
+ static void omninet_disconnect(struct usb_serial *serial);
++static int omninet_attach(struct usb_serial *serial);
+ static int omninet_port_probe(struct usb_serial_port *port);
+ static int omninet_port_remove(struct usb_serial_port *port);
+@@ -56,6 +57,7 @@ static struct usb_serial_driver zyxel_om
+       .description =          "ZyXEL - omni.net lcd plus usb",
+       .id_table =             id_table,
+       .num_ports =            1,
++      .attach =               omninet_attach,
+       .port_probe =           omninet_port_probe,
+       .port_remove =          omninet_port_remove,
+       .open =                 omninet_open,
+@@ -104,6 +106,17 @@ struct omninet_data {
+       __u8    od_outseq;      /* Sequence number for bulk_out URBs */
+ };
++static int omninet_attach(struct usb_serial *serial)
++{
++      /* The second bulk-out endpoint is used for writing. */
++      if (serial->num_bulk_out < 2) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
+ static int omninet_port_probe(struct usb_serial_port *port)
+ {
+       struct omninet_data *od;
diff --git a/queue-4.9/usb-serial-oti6858-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-oti6858-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..4372cbf
--- /dev/null
@@ -0,0 +1,67 @@
+From 5afeef2366db14587b65558bbfd5a067542e07fb Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:39:59 +0100
+Subject: USB: serial: oti6858: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 5afeef2366db14587b65558bbfd5a067542e07fb upstream.
+
+Fix NULL-pointer dereference in open() should the device lack the
+expected endpoints:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+PC is at oti6858_open+0x30/0x1d0 [oti6858]
+
+Note that a missing interrupt-in endpoint would have caused open() to
+fail.
+
+Fixes: 49cdee0ed0fc ("USB: oti6858 usb-serial driver (in Nokia CA-42
+cable)")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/oti6858.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/usb/serial/oti6858.c
++++ b/drivers/usb/serial/oti6858.c
+@@ -134,6 +134,7 @@ static int oti6858_chars_in_buffer(struc
+ static int oti6858_tiocmget(struct tty_struct *tty);
+ static int oti6858_tiocmset(struct tty_struct *tty,
+                               unsigned int set, unsigned int clear);
++static int oti6858_attach(struct usb_serial *serial);
+ static int oti6858_port_probe(struct usb_serial_port *port);
+ static int oti6858_port_remove(struct usb_serial_port *port);
+@@ -158,6 +159,7 @@ static struct usb_serial_driver oti6858_
+       .write_bulk_callback =  oti6858_write_bulk_callback,
+       .write_room =           oti6858_write_room,
+       .chars_in_buffer =      oti6858_chars_in_buffer,
++      .attach =               oti6858_attach,
+       .port_probe =           oti6858_port_probe,
+       .port_remove =          oti6858_port_remove,
+ };
+@@ -324,6 +326,20 @@ static void send_data(struct work_struct
+       usb_serial_port_softint(port);
+ }
++static int oti6858_attach(struct usb_serial *serial)
++{
++      unsigned char num_ports = serial->num_ports;
++
++      if (serial->num_bulk_in < num_ports ||
++                      serial->num_bulk_out < num_ports ||
++                      serial->num_interrupt_in < num_ports) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
+ static int oti6858_port_probe(struct usb_serial_port *port)
+ {
+       struct oti6858_private *priv;
diff --git a/queue-4.9/usb-serial-pl2303-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-pl2303-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..eb49d48
--- /dev/null
@@ -0,0 +1,47 @@
+From 76ab439ed1b68778e9059c79ecc5d14de76c89a8 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:40:00 +0100
+Subject: USB: serial: pl2303: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 76ab439ed1b68778e9059c79ecc5d14de76c89a8 upstream.
+
+Fix NULL-pointer dereference in open() should a type-0 or type-1 device
+lack the expected endpoints:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+PC is at pl2303_open+0x38/0xec [pl2303]
+
+Note that a missing interrupt-in endpoint would have caused open() to
+fail.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/pl2303.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -220,9 +220,17 @@ static int pl2303_probe(struct usb_seria
+ static int pl2303_startup(struct usb_serial *serial)
+ {
+       struct pl2303_serial_private *spriv;
++      unsigned char num_ports = serial->num_ports;
+       enum pl2303_type type = TYPE_01;
+       unsigned char *buf;
++      if (serial->num_bulk_in < num_ports ||
++                      serial->num_bulk_out < num_ports ||
++                      serial->num_interrupt_in < num_ports) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              return -ENODEV;
++      }
++
+       spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
+       if (!spriv)
+               return -ENOMEM;
diff --git a/queue-4.9/usb-serial-quatech2-fix-sleep-while-atomic-in-close.patch b/queue-4.9/usb-serial-quatech2-fix-sleep-while-atomic-in-close.patch
new file mode 100644 (file)
index 0000000..0b23d9e
--- /dev/null
@@ -0,0 +1,42 @@
+From f09d1886a41e9063b43da493ef0e845ac8afd2fa Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:40:01 +0100
+Subject: USB: serial: quatech2: fix sleep-while-atomic in close
+
+From: Johan Hovold <johan@kernel.org>
+
+commit f09d1886a41e9063b43da493ef0e845ac8afd2fa upstream.
+
+The write URB was being killed using the synchronous interface while
+holding a spin lock in close().
+
+Simply drop the lock and busy-flag update, something which would have
+been taken care of by the completion handler if the URB was in flight.
+
+Fixes: f7a33e608d9a ("USB: serial: add quatech2 usb to serial driver")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/quatech2.c |    4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/usb/serial/quatech2.c
++++ b/drivers/usb/serial/quatech2.c
+@@ -408,16 +408,12 @@ static void qt2_close(struct usb_serial_
+ {
+       struct usb_serial *serial;
+       struct qt2_port_private *port_priv;
+-      unsigned long flags;
+       int i;
+       serial = port->serial;
+       port_priv = usb_get_serial_port_data(port);
+-      spin_lock_irqsave(&port_priv->urb_lock, flags);
+       usb_kill_urb(port_priv->write_urb);
+-      port_priv->urb_in_use = false;
+-      spin_unlock_irqrestore(&port_priv->urb_lock, flags);
+       /* flush the port transmit buffer */
+       i = usb_control_msg(serial->dev,
diff --git a/queue-4.9/usb-serial-spcp8x5-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-spcp8x5-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..01e5759
--- /dev/null
@@ -0,0 +1,54 @@
+From cc0909248258f679c4bb4cd315565d40abaf6bc6 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:40:02 +0100
+Subject: USB: serial: spcp8x5: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit cc0909248258f679c4bb4cd315565d40abaf6bc6 upstream.
+
+Fix NULL-pointer dereference in open() should the device lack the
+expected endpoints:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+...
+PC is at spcp8x5_open+0x30/0xd0 [spcp8x5]
+
+Fixes: 619a6f1d1423 ("USB: add usb-serial spcp8x5 driver")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/spcp8x5.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/usb/serial/spcp8x5.c
++++ b/drivers/usb/serial/spcp8x5.c
+@@ -154,6 +154,19 @@ static int spcp8x5_probe(struct usb_seri
+       return 0;
+ }
++static int spcp8x5_attach(struct usb_serial *serial)
++{
++      unsigned char num_ports = serial->num_ports;
++
++      if (serial->num_bulk_in < num_ports ||
++                      serial->num_bulk_out < num_ports) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              return -ENODEV;
++      }
++
++      return 0;
++}
++
+ static int spcp8x5_port_probe(struct usb_serial_port *port)
+ {
+       const struct usb_device_id *id = usb_get_serial_data(port->serial);
+@@ -477,6 +490,7 @@ static struct usb_serial_driver spcp8x5_
+       .tiocmget               = spcp8x5_tiocmget,
+       .tiocmset               = spcp8x5_tiocmset,
+       .probe                  = spcp8x5_probe,
++      .attach                 = spcp8x5_attach,
+       .port_probe             = spcp8x5_port_probe,
+       .port_remove            = spcp8x5_port_remove,
+ };
diff --git a/queue-4.9/usb-serial-ti_usb_3410_5052-fix-null-deref-at-open.patch b/queue-4.9/usb-serial-ti_usb_3410_5052-fix-null-deref-at-open.patch
new file mode 100644 (file)
index 0000000..7a36b6f
--- /dev/null
@@ -0,0 +1,40 @@
+From ef079936d3cd09e63612834fe2698eeada0d8e3f Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 3 Jan 2017 16:40:03 +0100
+Subject: USB: serial: ti_usb_3410_5052: fix NULL-deref at open
+
+From: Johan Hovold <johan@kernel.org>
+
+commit ef079936d3cd09e63612834fe2698eeada0d8e3f upstream.
+
+Fix NULL-pointer dereference in open() should a malicious device lack
+the expected endpoints:
+
+Unable to handle kernel NULL pointer dereference at virtual address 00000030
+..
+[<bf06a6b0>] (ti_open [ti_usb_3410_5052]) from [<bf02e118>] (serial_port_activate+0x68/0x98 [usbserial])
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ti_usb_3410_5052.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -579,6 +579,13 @@ static int ti_startup(struct usb_serial
+               goto free_tdev;
+       }
++      if (serial->num_bulk_in < serial->num_ports ||
++                      serial->num_bulk_out < serial->num_ports) {
++              dev_err(&serial->interface->dev, "missing endpoints\n");
++              status = -ENODEV;
++              goto free_tdev;
++      }
++
+       return 0;
+ free_tdev:
diff --git a/queue-4.9/usb-xhci-apply-xhci_pme_stuck_quirk-to-intel-apollo-lake.patch b/queue-4.9/usb-xhci-apply-xhci_pme_stuck_quirk-to-intel-apollo-lake.patch
new file mode 100644 (file)
index 0000000..7694ec4
--- /dev/null
@@ -0,0 +1,32 @@
+From 6c97cfc1a097b1e0786c836e92b7a72b4d031e25 Mon Sep 17 00:00:00 2001
+From: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>
+Date: Tue, 3 Jan 2017 18:28:52 +0200
+Subject: usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Apollo Lake
+
+From: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>
+
+commit 6c97cfc1a097b1e0786c836e92b7a72b4d031e25 upstream.
+
+Intel Apollo Lake also requires XHCI_PME_STUCK_QUIRK.
+Adding its PCI ID to quirk.
+
+Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-pci.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -165,7 +165,8 @@ static void xhci_pci_quirks(struct devic
+                pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
+                pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
+                pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
+-               pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) {
++               pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI ||
++               pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI)) {
+               xhci->quirks |= XHCI_PME_STUCK_QUIRK;
+       }
+       if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
diff --git a/queue-4.9/usb-xhci-fix-return-value-of-xhci_setup_device.patch b/queue-4.9/usb-xhci-fix-return-value-of-xhci_setup_device.patch
new file mode 100644 (file)
index 0000000..5f43f52
--- /dev/null
@@ -0,0 +1,42 @@
+From 90797aee5d6902b49a453c97d83c326408aeb5a8 Mon Sep 17 00:00:00 2001
+From: Lu Baolu <baolu.lu@linux.intel.com>
+Date: Tue, 3 Jan 2017 18:28:44 +0200
+Subject: usb: xhci: fix return value of xhci_setup_device()
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+commit 90797aee5d6902b49a453c97d83c326408aeb5a8 upstream.
+
+xhci_setup_device() should return failure with correct error number
+when xhci host has died, removed or halted.
+
+During usb device enumeration, if usb host is not accessible (died,
+removed or halted), the hc_driver->address_device() should return
+a corresponding error code to usb core. But current xhci driver just
+returns success. This misleads usb core to continue the enumeration
+by reading the device descriptor, which will result in failure, and
+users will get a misleading message like "device descriptor read/8,
+error -110".
+
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3783,8 +3783,10 @@ static int xhci_setup_device(struct usb_
+       mutex_lock(&xhci->mutex);
+-      if (xhci->xhc_state)    /* dying, removing or halted */
++      if (xhci->xhc_state) {  /* dying, removing or halted */
++              ret = -ESHUTDOWN;
+               goto out;
++      }
+       if (!udev->slot_id) {
+               xhci_dbg_trace(xhci, trace_xhci_dbg_address,
diff --git a/queue-4.9/usb-xhci-hold-lock-over-xhci_abort_cmd_ring.patch b/queue-4.9/usb-xhci-hold-lock-over-xhci_abort_cmd_ring.patch
new file mode 100644 (file)
index 0000000..6e27af3
--- /dev/null
@@ -0,0 +1,72 @@
+From 4dea70778c0f48b4385c7720c363ec8d37a401b4 Mon Sep 17 00:00:00 2001
+From: Lu Baolu <baolu.lu@linux.intel.com>
+Date: Tue, 3 Jan 2017 18:28:49 +0200
+Subject: usb: xhci: hold lock over xhci_abort_cmd_ring()
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+commit 4dea70778c0f48b4385c7720c363ec8d37a401b4 upstream.
+
+In command timer function, xhci_handle_command_timeout(), xhci->lock
+is unlocked before call into xhci_abort_cmd_ring(). This might cause
+race between the timer function and the event handler.
+
+The xhci_abort_cmd_ring() function sets the CMD_RING_ABORT bit in the
+command register and polling it until the setting takes effect. A stop
+command ring event might be handled between writing the abort bit and
+polling for it. The event handler will restart the command ring, which
+causes the failure of polling, and we ever believed that we failed to
+stop it.
+
+As a bonus, this also fixes some issues of calling functions without
+locking in xhci_handle_command_timeout().
+
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1291,29 +1291,34 @@ void xhci_handle_command_timeout(unsigne
+       hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+       if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
+           (hw_ring_state & CMD_RING_RUNNING))  {
+-              spin_unlock_irqrestore(&xhci->lock, flags);
+               xhci_dbg(xhci, "Command timeout\n");
+               ret = xhci_abort_cmd_ring(xhci);
+               if (unlikely(ret == -ESHUTDOWN)) {
+                       xhci_err(xhci, "Abort command ring failed\n");
+                       xhci_cleanup_command_queue(xhci);
++                      spin_unlock_irqrestore(&xhci->lock, flags);
+                       usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
+                       xhci_dbg(xhci, "xHCI host controller is dead.\n");
++
++                      return;
+               }
+-              return;
++
++              goto time_out_completed;
+       }
+       /* command ring failed to restart, or host removed. Bail out */
+       if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) {
+-              spin_unlock_irqrestore(&xhci->lock, flags);
+               xhci_dbg(xhci, "command timed out twice, ring start fail?\n");
+               xhci_cleanup_command_queue(xhci);
+-              return;
++
++              goto time_out_completed;
+       }
+       /* command timeout on stopped ring, ring can't be aborted */
+       xhci_dbg(xhci, "Command timeout on stopped ring\n");
+       xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd);
++
++time_out_completed:
+       spin_unlock_irqrestore(&xhci->lock, flags);
+       return;
+ }
diff --git a/queue-4.9/usb-xhci-mem-use-passed-in-gfp-flags-instead-of-gfp_kernel.patch b/queue-4.9/usb-xhci-mem-use-passed-in-gfp-flags-instead-of-gfp_kernel.patch
new file mode 100644 (file)
index 0000000..3b67e1a
--- /dev/null
@@ -0,0 +1,42 @@
+From c95a9f83711bf53faeb4ed9bbb63a3f065613dfb Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 10 Nov 2016 22:33:17 +0300
+Subject: usb: xhci-mem: use passed in GFP flags instead of GFP_KERNEL
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit c95a9f83711bf53faeb4ed9bbb63a3f065613dfb upstream.
+
+We normally use the passed in gfp flags for allocations, it's just these
+two which were missed.
+
+Fixes: 22d45f01a836 ("usb/xhci: replace pci_*_consistent() with dma_*_coherent()")
+Cc: Mathias Nyman <mathias.nyman@intel.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -2418,7 +2418,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+        * "physically contiguous and 64-byte (cache line) aligned".
+        */
+       xhci->dcbaa = dma_alloc_coherent(dev, sizeof(*xhci->dcbaa), &dma,
+-                      GFP_KERNEL);
++                      flags);
+       if (!xhci->dcbaa)
+               goto fail;
+       memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa));
+@@ -2514,7 +2514,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+       xhci->erst.entries = dma_alloc_coherent(dev,
+                       sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS, &dma,
+-                      GFP_KERNEL);
++                      flags);
+       if (!xhci->erst.entries)
+               goto fail;
+       xhci_dbg_trace(xhci, trace_xhci_dbg_init,
diff --git a/queue-4.9/xhci-free-xhci-virtual-devices-with-leaf-nodes-first.patch b/queue-4.9/xhci-free-xhci-virtual-devices-with-leaf-nodes-first.patch
new file mode 100644 (file)
index 0000000..dd561fb
--- /dev/null
@@ -0,0 +1,81 @@
+From ee8665e28e8d90ce69d4abe5a469c14a8707ae0e Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Tue, 3 Jan 2017 18:28:43 +0200
+Subject: xhci: free xhci virtual devices with leaf nodes first
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit ee8665e28e8d90ce69d4abe5a469c14a8707ae0e upstream.
+
+the tt_info provided by a HS hub might be in use to by a child device
+Make sure we free the devices in the correct order.
+
+This is needed in special cases such as when xhci controller is
+reset when resuming from hibernate, and all virt_devices are freed.
+
+Also free the virt_devices starting from max slot_id as children
+more commonly have higher slot_id than parent.
+
+Reported-by: Guenter Roeck <groeck@chromium.org>
+Tested-by: Guenter Roeck <groeck@chromium.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c |   38 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 36 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -979,6 +979,40 @@ void xhci_free_virt_device(struct xhci_h
+       xhci->devs[slot_id] = NULL;
+ }
++/*
++ * Free a virt_device structure.
++ * If the virt_device added a tt_info (a hub) and has children pointing to
++ * that tt_info, then free the child first. Recursive.
++ * We can't rely on udev at this point to find child-parent relationships.
++ */
++void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_id)
++{
++      struct xhci_virt_device *vdev;
++      struct list_head *tt_list_head;
++      struct xhci_tt_bw_info *tt_info, *next;
++      int i;
++
++      vdev = xhci->devs[slot_id];
++      if (!vdev)
++              return;
++
++      tt_list_head = &(xhci->rh_bw[vdev->real_port - 1].tts);
++      list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) {
++              /* is this a hub device that added a tt_info to the tts list */
++              if (tt_info->slot_id == slot_id) {
++                      /* are any devices using this tt_info? */
++                      for (i = 1; i < HCS_MAX_SLOTS(xhci->hcs_params1); i++) {
++                              vdev = xhci->devs[i];
++                              if (vdev && (vdev->tt_info == tt_info))
++                                      xhci_free_virt_devices_depth_first(
++                                              xhci, i);
++                      }
++              }
++      }
++      /* we are now at a leaf device */
++      xhci_free_virt_device(xhci, slot_id);
++}
++
+ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
+               struct usb_device *udev, gfp_t flags)
+ {
+@@ -1829,8 +1863,8 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+               }
+       }
+-      for (i = 1; i < MAX_HC_SLOTS; ++i)
+-              xhci_free_virt_device(xhci, i);
++      for (i = HCS_MAX_SLOTS(xhci->hcs_params1); i > 0; i--)
++              xhci_free_virt_devices_depth_first(xhci, i);
+       dma_pool_destroy(xhci->segment_pool);
+       xhci->segment_pool = NULL;
diff --git a/queue-4.9/xhci-handle-command-completion-and-timeout-race.patch b/queue-4.9/xhci-handle-command-completion-and-timeout-race.patch
new file mode 100644 (file)
index 0000000..a373a08
--- /dev/null
@@ -0,0 +1,48 @@
+From a5a1b9514154437aa1ed35c291191f82fd3e941a Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Tue, 3 Jan 2017 18:28:48 +0200
+Subject: xhci: Handle command completion and timeout race
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit a5a1b9514154437aa1ed35c291191f82fd3e941a upstream.
+
+If we get a command completion event at the same time as the command
+timeout work starts on another cpu we might end up aborting the wrong
+command.
+
+If the command completion takes the xhci lock before the timeout work, it
+will handle the command, pick the next command, mark it as current_cmd, and
+re-queue the timeout work. When the timeout work finally gets the lock
+It will start aborting the wrong command.
+
+This case can be resolved by checking if the timeout work is pending inside
+the timeout function itself. A new timeout work can only be pending if the
+command completed and a new command was queued.
+
+If there are no more commands pending then command completion will set
+the current_cmd to NULL, which is already handled in the timeout work.
+
+Reported-by: Baolin Wang <baolin.wang@linaro.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1273,7 +1273,11 @@ void xhci_handle_command_timeout(unsigne
+       spin_lock_irqsave(&xhci->lock, flags);
+-      if (!xhci->current_cmd) {
++      /*
++       * If timeout work is pending, or current_cmd is NULL, it means we
++       * raced with command completion. Command is handled so just return.
++       */
++      if (!xhci->current_cmd || timer_pending(&xhci->cmd_timer)) {
+               spin_unlock_irqrestore(&xhci->lock, flags);
+               return;
+       }