From 0f4bf3eee104ebd4794f10ff5efd0058e143ce09 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 17 Jan 2017 14:04:39 +0100 Subject: [PATCH] 4.4-stable patches added patches: usb-serial-ch341-fix-control-message-error-handling.patch usb-serial-ch341-fix-initial-modem-control-state.patch usb-serial-ch341-fix-open-and-resume-after-b0.patch usb-serial-ch341-fix-open-error-handling.patch usb-serial-ch341-fix-resume-after-reset.patch usb-serial-kl5kusb105-fix-line-state-error-handling.patch --- queue-4.4/series | 6 ++ ...1-fix-control-message-error-handling.patch | 98 +++++++++++++++++++ ...h341-fix-initial-modem-control-state.patch | 31 ++++++ ...l-ch341-fix-open-and-resume-after-b0.patch | 38 +++++++ ...serial-ch341-fix-open-error-handling.patch | 53 ++++++++++ ...-serial-ch341-fix-resume-after-reset.patch | 52 ++++++++++ ...usb105-fix-line-state-error-handling.patch | 41 ++++++++ 7 files changed, 319 insertions(+) create mode 100644 queue-4.4/usb-serial-ch341-fix-control-message-error-handling.patch create mode 100644 queue-4.4/usb-serial-ch341-fix-initial-modem-control-state.patch create mode 100644 queue-4.4/usb-serial-ch341-fix-open-and-resume-after-b0.patch create mode 100644 queue-4.4/usb-serial-ch341-fix-open-error-handling.patch create mode 100644 queue-4.4/usb-serial-ch341-fix-resume-after-reset.patch create mode 100644 queue-4.4/usb-serial-kl5kusb105-fix-line-state-error-handling.patch diff --git a/queue-4.4/series b/queue-4.4/series index e22f63598ad..cd6ea90332e 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -14,3 +14,9 @@ kvm-x86-add-asm_safe-wrapper.patch kvm-x86-emulate-fxsave-and-fxrstor.patch kvm-x86-introduce-segmented_write_std.patch nl80211-fix-sched-scan-netlink-socket-owner-destruction.patch +usb-serial-kl5kusb105-fix-line-state-error-handling.patch +usb-serial-ch341-fix-initial-modem-control-state.patch +usb-serial-ch341-fix-resume-after-reset.patch +usb-serial-ch341-fix-open-error-handling.patch +usb-serial-ch341-fix-control-message-error-handling.patch +usb-serial-ch341-fix-open-and-resume-after-b0.patch diff --git a/queue-4.4/usb-serial-ch341-fix-control-message-error-handling.patch b/queue-4.4/usb-serial-ch341-fix-control-message-error-handling.patch new file mode 100644 index 00000000000..c9a25aab763 --- /dev/null +++ b/queue-4.4/usb-serial-ch341-fix-control-message-error-handling.patch @@ -0,0 +1,98 @@ +From 2d5a9c72d0c4ac73cf97f4b7814ed6c44b1e49ae Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 6 Jan 2017 19:15:18 +0100 +Subject: USB: serial: ch341: fix control-message error handling + +From: Johan Hovold + +commit 2d5a9c72d0c4ac73cf97f4b7814ed6c44b1e49ae upstream. + +A short control transfer would currently fail to be detected, something +which could lead to stale buffer data being used as valid input. + +Check for short transfers, and make sure to log any transfer errors. + +Note that this also avoids leaking heap data to user space (TIOCMGET) +and the remote device (break control). + +Fixes: 6ce76104781a ("USB: Driver for CH341 USB-serial adaptor") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ch341.c | 32 +++++++++++++++++++++----------- + 1 file changed, 21 insertions(+), 11 deletions(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -99,6 +99,8 @@ static int ch341_control_out(struct usb_ + r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + value, index, NULL, 0, DEFAULT_TIMEOUT); ++ if (r < 0) ++ dev_err(&dev->dev, "failed to send control message: %d\n", r); + + return r; + } +@@ -116,7 +118,20 @@ static int ch341_control_in(struct usb_d + r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + value, index, buf, bufsize, DEFAULT_TIMEOUT); +- return r; ++ if (r < bufsize) { ++ if (r >= 0) { ++ dev_err(&dev->dev, ++ "short control message received (%d < %u)\n", ++ r, bufsize); ++ r = -EIO; ++ } ++ ++ dev_err(&dev->dev, "failed to receive control message: %d\n", ++ r); ++ return r; ++ } ++ ++ return 0; + } + + static int ch341_set_baudrate(struct usb_device *dev, +@@ -158,9 +173,9 @@ static int ch341_set_handshake(struct us + + static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv) + { ++ const unsigned int size = 2; + char *buffer; + int r; +- const unsigned size = 8; + unsigned long flags; + + buffer = kmalloc(size, GFP_KERNEL); +@@ -171,14 +186,9 @@ static int ch341_get_status(struct usb_d + if (r < 0) + goto out; + +- /* setup the private status if available */ +- if (r == 2) { +- r = 0; +- spin_lock_irqsave(&priv->lock, flags); +- priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT; +- spin_unlock_irqrestore(&priv->lock, flags); +- } else +- r = -EPROTO; ++ spin_lock_irqsave(&priv->lock, flags); ++ priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT; ++ spin_unlock_irqrestore(&priv->lock, flags); + + out: kfree(buffer); + return r; +@@ -188,9 +198,9 @@ out: kfree(buffer); + + static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) + { ++ const unsigned int size = 2; + char *buffer; + int r; +- const unsigned size = 8; + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) diff --git a/queue-4.4/usb-serial-ch341-fix-initial-modem-control-state.patch b/queue-4.4/usb-serial-ch341-fix-initial-modem-control-state.patch new file mode 100644 index 00000000000..923deae7a55 --- /dev/null +++ b/queue-4.4/usb-serial-ch341-fix-initial-modem-control-state.patch @@ -0,0 +1,31 @@ +From 4e2da44691cffbfffb1535f478d19bc2dca3e62b Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 6 Jan 2017 19:15:10 +0100 +Subject: USB: serial: ch341: fix initial modem-control state + +From: Johan Hovold + +commit 4e2da44691cffbfffb1535f478d19bc2dca3e62b upstream. + +DTR and RTS will be asserted by the tty-layer when the port is opened +and deasserted on close (if HUPCL is set). Make sure the initial state +is not-asserted before the port is first opened as well. + +Fixes: 664d5df92e88 ("USB: usb-serial ch341: support for DTR/RTS/CTS") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ch341.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -253,7 +253,6 @@ static int ch341_port_probe(struct usb_s + + spin_lock_init(&priv->lock); + priv->baud_rate = DEFAULT_BAUD_RATE; +- priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; + + r = ch341_configure(port->serial->dev, priv); + if (r < 0) diff --git a/queue-4.4/usb-serial-ch341-fix-open-and-resume-after-b0.patch b/queue-4.4/usb-serial-ch341-fix-open-and-resume-after-b0.patch new file mode 100644 index 00000000000..1b0d0fea722 --- /dev/null +++ b/queue-4.4/usb-serial-ch341-fix-open-and-resume-after-b0.patch @@ -0,0 +1,38 @@ +From a20047f36e2f6a1eea4f1fd261aaa55882369868 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 6 Jan 2017 19:15:11 +0100 +Subject: USB: serial: ch341: fix open and resume after B0 + +From: Johan Hovold + +commit a20047f36e2f6a1eea4f1fd261aaa55882369868 upstream. + +The private baud_rate variable is used to configure the port at open and +reset-resume and must never be set to (and left at) zero or reset-resume +and all further open attempts will fail. + +Fixes: aa91def41a7b ("USB: ch341: set tty baud speed according to tty struct") +Fixes: 664d5df92e88 ("USB: usb-serial ch341: support for DTR/RTS/CTS") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ch341.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -361,12 +361,11 @@ static void ch341_set_termios(struct tty + + baud_rate = tty_get_baud_rate(tty); + +- priv->baud_rate = baud_rate; +- + if (baud_rate) { + spin_lock_irqsave(&priv->lock, flags); + priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS); + spin_unlock_irqrestore(&priv->lock, flags); ++ priv->baud_rate = baud_rate; + ch341_set_baudrate(port->serial->dev, priv); + } else { + spin_lock_irqsave(&priv->lock, flags); diff --git a/queue-4.4/usb-serial-ch341-fix-open-error-handling.patch b/queue-4.4/usb-serial-ch341-fix-open-error-handling.patch new file mode 100644 index 00000000000..1c75ed522e4 --- /dev/null +++ b/queue-4.4/usb-serial-ch341-fix-open-error-handling.patch @@ -0,0 +1,53 @@ +From f2950b78547ffb8475297ada6b92bc2d774d5461 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 6 Jan 2017 19:15:13 +0100 +Subject: USB: serial: ch341: fix open error handling + +From: Johan Hovold + +commit f2950b78547ffb8475297ada6b92bc2d774d5461 upstream. + +Make sure to stop the interrupt URB before returning on errors during +open. + +Fixes: 664d5df92e88 ("USB: usb-serial ch341: support for DTR/RTS/CTS") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ch341.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -314,7 +314,7 @@ static int ch341_open(struct tty_struct + + r = ch341_configure(serial->dev, priv); + if (r) +- goto out; ++ return r; + + if (tty) + ch341_set_termios(tty, port, NULL); +@@ -324,12 +324,19 @@ static int ch341_open(struct tty_struct + if (r) { + dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n", + __func__, r); +- goto out; ++ return r; + } + + r = usb_serial_generic_open(tty, port); ++ if (r) ++ goto err_kill_interrupt_urb; ++ ++ return 0; ++ ++err_kill_interrupt_urb: ++ usb_kill_urb(port->interrupt_in_urb); + +-out: return r; ++ return r; + } + + /* Old_termios contains the original termios settings and diff --git a/queue-4.4/usb-serial-ch341-fix-resume-after-reset.patch b/queue-4.4/usb-serial-ch341-fix-resume-after-reset.patch new file mode 100644 index 00000000000..b68542a4eab --- /dev/null +++ b/queue-4.4/usb-serial-ch341-fix-resume-after-reset.patch @@ -0,0 +1,52 @@ +From ce5e292828117d1b71cbd3edf9e9137cf31acd30 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 6 Jan 2017 19:15:14 +0100 +Subject: USB: serial: ch341: fix resume after reset + +From: Johan Hovold + +commit ce5e292828117d1b71cbd3edf9e9137cf31acd30 upstream. + +Fix reset-resume handling which failed to resubmit the read and +interrupt URBs, thereby leaving a port that was open before suspend in a +broken state until closed and reopened. + +Fixes: 1ded7ea47b88 ("USB: ch341 serial: fix port number changed after resume") +Fixes: 2bfd1c96a9fb ("USB: serial: ch341: remove reset_resume callback") +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ch341.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -538,14 +538,23 @@ static int ch341_tiocmget(struct tty_str + + static int ch341_reset_resume(struct usb_serial *serial) + { +- struct ch341_private *priv; +- +- priv = usb_get_serial_port_data(serial->port[0]); ++ struct usb_serial_port *port = serial->port[0]; ++ struct ch341_private *priv = usb_get_serial_port_data(port); ++ int ret; + + /* reconfigure ch341 serial port after bus-reset */ + ch341_configure(serial->dev, priv); + +- return 0; ++ if (tty_port_initialized(&port->port)) { ++ ret = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); ++ if (ret) { ++ dev_err(&port->dev, "failed to submit interrupt urb: %d\n", ++ ret); ++ return ret; ++ } ++ } ++ ++ return usb_serial_generic_resume(serial); + } + + static struct usb_serial_driver ch341_device = { diff --git a/queue-4.4/usb-serial-kl5kusb105-fix-line-state-error-handling.patch b/queue-4.4/usb-serial-kl5kusb105-fix-line-state-error-handling.patch new file mode 100644 index 00000000000..b0969ef91b2 --- /dev/null +++ b/queue-4.4/usb-serial-kl5kusb105-fix-line-state-error-handling.patch @@ -0,0 +1,41 @@ +From 146cc8a17a3b4996f6805ee5c080e7101277c410 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 10 Jan 2017 12:05:37 +0100 +Subject: USB: serial: kl5kusb105: fix line-state error handling + +From: Johan Hovold + +commit 146cc8a17a3b4996f6805ee5c080e7101277c410 upstream. + +The current implementation failed to detect short transfers when +attempting to read the line state, and also, to make things worse, +logged the content of the uninitialised heap transfer buffer. + +Fixes: abf492e7b3ae ("USB: kl5kusb105: fix DMA buffers on stack") +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/kl5kusb105.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/kl5kusb105.c ++++ b/drivers/usb/serial/kl5kusb105.c +@@ -192,10 +192,11 @@ static int klsi_105_get_line_state(struc + status_buf, KLSI_STATUSBUF_LEN, + 10000 + ); +- if (rc < 0) +- dev_err(&port->dev, "Reading line status failed (error = %d)\n", +- rc); +- else { ++ if (rc != KLSI_STATUSBUF_LEN) { ++ dev_err(&port->dev, "reading line status failed: %d\n", rc); ++ if (rc >= 0) ++ rc = -EIO; ++ } else { + status = get_unaligned_le16(status_buf); + + dev_info(&port->serial->dev->dev, "read status %x %x\n", -- 2.47.3