All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] USB: fix tty unthrottle races
@ 2019-04-25 16:05 Johan Hovold
  2019-04-25 16:05   ` [PATCH 1/5] " Johan Hovold
                   ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

This series fixes a couple of long-standing issues in USB serial and
cdc-acm which essentially share the same implementation.

As noted by Oliver a few years back, read-urb completion can race with
unthrottle() running on another CPU and this can potentially lead to
memory corruption. This particular bug in cdc-acm was unfortunately
reintroduced a year later.

There's also a second race due to missing memory barriers which could
theoretically lead to the port staying throttled until reopened on
weakly ordered systems. A second set of memory barriers should address
that.

I would appreciate your keen eyes on this one to make sure I got the
barriers right.

I noticed there's some on-going discussion about the atomic memory
barriers that Alan's involved in, and I'll try to catch up on his
data-race work as well. I'm still a little concerned about whether the
smp_mb__before_atomic() is sufficient to prevent the compiler from
messing things up without adding READ_ONCE().

Note that none of these have stable tags as the issues have been there
for eight years or so without anyone noticing (besides Oliver).

Still feels good to clean up your own mess.

Note that the cdc-acm patches have so far only been compile tested.

Johan


Johan Hovold (5):
  USB: serial: fix unthrottle races
  USB: serial: clean up throttle handling
  USB: serial: generic: drop unnecessary goto
  USB: cdc-acm: fix unthrottle races
  USB: cdc-acm: clean up throttle handling

 drivers/usb/class/cdc-acm.c  | 63 +++++++++++++++---------------
 drivers/usb/class/cdc-acm.h  |  3 +-
 drivers/usb/serial/generic.c | 76 +++++++++++++++++++-----------------
 include/linux/usb/serial.h   |  5 +--
 4 files changed, 75 insertions(+), 72 deletions(-)

-- 
2.21.0


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [1/5] USB: serial: fix unthrottle races
@ 2019-04-25 16:05   ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Fix two long-standing bugs which could potentially lead to memory
corruption or leave the port throttled until it is reopened (on weakly
ordered systems), respectively, when read-URB completion races with
unthrottle().

First, the URB must not be marked as free before processing is complete
to prevent it from being submitted by unthrottle() on another CPU.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  process_urb();
	  smp_mb__before_atomic();
	  set_bit(i, free);		  if (test_and_clear_bit(i, free))
	  					  submit_urb();

Second, the URB must be marked as free before checking the throttled
flag to prevent unthrottle() on another CPU from failing to observe that
the URB needs to be submitted if complete() sees that the throttled flag
is set.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  set_bit(i, free);		  throttled = 0;
	  smp_mb__after_atomic();	  smp_mb();
	  if (throttled)		  if (test_and_clear_bit(i, free))
	  	  return;			  submit_urb();

Note that test_and_clear_bit() only implies barriers when the test is
successful. To handle the case where the URB is still in use an explicit
barrier needs to be added to unthrottle() for the second race condition.

Fixes: d83b405383c9 ("USB: serial: add support for multiple read urbs")
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/generic.c | 39 +++++++++++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 2274d9625f63..0fff4968ea1b 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -376,6 +376,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 	struct usb_serial_port *port = urb->context;
 	unsigned char *data = urb->transfer_buffer;
 	unsigned long flags;
+	bool stopped = false;
 	int status = urb->status;
 	int i;
 
@@ -383,33 +384,51 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 		if (urb == port->read_urbs[i])
 			break;
 	}
-	set_bit(i, &port->read_urbs_free);
 
 	dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
 							urb->actual_length);
 	switch (status) {
 	case 0:
+		usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
+							data);
+		port->serial->type->process_read_urb(urb);
 		break;
 	case -ENOENT:
 	case -ECONNRESET:
 	case -ESHUTDOWN:
 		dev_dbg(&port->dev, "%s - urb stopped: %d\n",
 							__func__, status);
-		return;
+		stopped = true;
+		break;
 	case -EPIPE:
 		dev_err(&port->dev, "%s - urb stopped: %d\n",
 							__func__, status);
-		return;
+		stopped = true;
+		break;
 	default:
 		dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",
 							__func__, status);
-		goto resubmit;
+		break;
 	}
 
-	usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
-	port->serial->type->process_read_urb(urb);
+	/*
+	 * Make sure URB processing is done before marking as free to avoid
+	 * racing with unthrottle() on another CPU. Matches the barriers
+	 * implied by the test_and_clear_bit() in
+	 * usb_serial_generic_submit_read_urb().
+	 */
+	smp_mb__before_atomic();
+	set_bit(i, &port->read_urbs_free);
+	/*
+	 * Make sure URB is marked as free before checking the throttled flag
+	 * to avoid racing with unthrottle() on another CPU. Matches the
+	 * smp_mb() in unthrottle().
+	 */
+	smp_mb__after_atomic();
+
+	if (stopped)
+		return;
 
-resubmit:
 	/* Throttle the device if requested by tty */
 	spin_lock_irqsave(&port->lock, flags);
 	port->throttled = port->throttle_req;
@@ -484,6 +503,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
 	port->throttled = port->throttle_req = 0;
 	spin_unlock_irq(&port->lock);
 
+	/*
+	 * Matches the smp_mb__after_atomic() in
+	 * usb_serial_generic_read_bulk_callback().
+	 */
+	smp_mb();
+
 	if (was_throttled)
 		usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
 }

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 1/5] USB: serial: fix unthrottle races
@ 2019-04-25 16:05   ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Fix two long-standing bugs which could potentially lead to memory
corruption or leave the port throttled until it is reopened (on weakly
ordered systems), respectively, when read-URB completion races with
unthrottle().

First, the URB must not be marked as free before processing is complete
to prevent it from being submitted by unthrottle() on another CPU.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  process_urb();
	  smp_mb__before_atomic();
	  set_bit(i, free);		  if (test_and_clear_bit(i, free))
	  					  submit_urb();

Second, the URB must be marked as free before checking the throttled
flag to prevent unthrottle() on another CPU from failing to observe that
the URB needs to be submitted if complete() sees that the throttled flag
is set.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  set_bit(i, free);		  throttled = 0;
	  smp_mb__after_atomic();	  smp_mb();
	  if (throttled)		  if (test_and_clear_bit(i, free))
	  	  return;			  submit_urb();

Note that test_and_clear_bit() only implies barriers when the test is
successful. To handle the case where the URB is still in use an explicit
barrier needs to be added to unthrottle() for the second race condition.

Fixes: d83b405383c9 ("USB: serial: add support for multiple read urbs")
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/generic.c | 39 +++++++++++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 2274d9625f63..0fff4968ea1b 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -376,6 +376,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 	struct usb_serial_port *port = urb->context;
 	unsigned char *data = urb->transfer_buffer;
 	unsigned long flags;
+	bool stopped = false;
 	int status = urb->status;
 	int i;
 
@@ -383,33 +384,51 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 		if (urb == port->read_urbs[i])
 			break;
 	}
-	set_bit(i, &port->read_urbs_free);
 
 	dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
 							urb->actual_length);
 	switch (status) {
 	case 0:
+		usb_serial_debug_data(&port->dev, __func__, urb->actual_length,
+							data);
+		port->serial->type->process_read_urb(urb);
 		break;
 	case -ENOENT:
 	case -ECONNRESET:
 	case -ESHUTDOWN:
 		dev_dbg(&port->dev, "%s - urb stopped: %d\n",
 							__func__, status);
-		return;
+		stopped = true;
+		break;
 	case -EPIPE:
 		dev_err(&port->dev, "%s - urb stopped: %d\n",
 							__func__, status);
-		return;
+		stopped = true;
+		break;
 	default:
 		dev_dbg(&port->dev, "%s - nonzero urb status: %d\n",
 							__func__, status);
-		goto resubmit;
+		break;
 	}
 
-	usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
-	port->serial->type->process_read_urb(urb);
+	/*
+	 * Make sure URB processing is done before marking as free to avoid
+	 * racing with unthrottle() on another CPU. Matches the barriers
+	 * implied by the test_and_clear_bit() in
+	 * usb_serial_generic_submit_read_urb().
+	 */
+	smp_mb__before_atomic();
+	set_bit(i, &port->read_urbs_free);
+	/*
+	 * Make sure URB is marked as free before checking the throttled flag
+	 * to avoid racing with unthrottle() on another CPU. Matches the
+	 * smp_mb() in unthrottle().
+	 */
+	smp_mb__after_atomic();
+
+	if (stopped)
+		return;
 
-resubmit:
 	/* Throttle the device if requested by tty */
 	spin_lock_irqsave(&port->lock, flags);
 	port->throttled = port->throttle_req;
@@ -484,6 +503,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
 	port->throttled = port->throttle_req = 0;
 	spin_unlock_irq(&port->lock);
 
+	/*
+	 * Matches the smp_mb__after_atomic() in
+	 * usb_serial_generic_read_bulk_callback().
+	 */
+	smp_mb();
+
 	if (was_throttled)
 		usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
 }
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [2/5] USB: serial: clean up throttle handling
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Clean up the throttle implementation by dropping the redundant
throttle_req flag which was a remnant from back when there was only a
single read URB.

Also convert the throttled flag to an atomic bit flag.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/generic.c | 34 ++++++++--------------------------
 include/linux/usb/serial.h   |  5 +----
 2 files changed, 9 insertions(+), 30 deletions(-)

diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 0fff4968ea1b..67cef3ef1e5f 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -106,12 +106,8 @@ void usb_serial_generic_deregister(void)
 int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int result = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&port->lock, flags);
-	port->throttled = 0;
-	port->throttle_req = 0;
-	spin_unlock_irqrestore(&port->lock, flags);
+	clear_bit(USB_SERIAL_THROTTLED, &port->flags);
 
 	if (port->bulk_in_size)
 		result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
@@ -375,7 +371,6 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 {
 	struct usb_serial_port *port = urb->context;
 	unsigned char *data = urb->transfer_buffer;
-	unsigned long flags;
 	bool stopped = false;
 	int status = urb->status;
 	int i;
@@ -429,15 +424,10 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 	if (stopped)
 		return;
 
-	/* Throttle the device if requested by tty */
-	spin_lock_irqsave(&port->lock, flags);
-	port->throttled = port->throttle_req;
-	if (!port->throttled) {
-		spin_unlock_irqrestore(&port->lock, flags);
-		usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
-	} else {
-		spin_unlock_irqrestore(&port->lock, flags);
-	}
+	if (test_bit(USB_SERIAL_THROTTLED, &port->flags))
+		return;
+
+	usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
 
@@ -485,23 +475,16 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
 void usb_serial_generic_throttle(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&port->lock, flags);
-	port->throttle_req = 1;
-	spin_unlock_irqrestore(&port->lock, flags);
+	set_bit(USB_SERIAL_THROTTLED, &port->flags);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_throttle);
 
 void usb_serial_generic_unthrottle(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	int was_throttled;
 
-	spin_lock_irq(&port->lock);
-	was_throttled = port->throttled;
-	port->throttled = port->throttle_req = 0;
-	spin_unlock_irq(&port->lock);
+	clear_bit(USB_SERIAL_THROTTLED, &port->flags);
 
 	/*
 	 * Matches the smp_mb__after_atomic() in
@@ -509,8 +492,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
 	 */
 	smp_mb();
 
-	if (was_throttled)
-		usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
+	usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle);
 
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 1c19f77ed541..d8bdab8f3c26 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -28,6 +28,7 @@
 
 /* USB serial flags */
 #define USB_SERIAL_WRITE_BUSY	0
+#define USB_SERIAL_THROTTLED	1
 
 /**
  * usb_serial_port: structure for the specific ports of a device.
@@ -67,8 +68,6 @@
  * @flags: usb serial port flags
  * @write_wait: a wait_queue_head_t used by the port.
  * @work: work queue entry for the line discipline waking up.
- * @throttled: nonzero if the read urb is inactive to throttle the device
- * @throttle_req: nonzero if the tty wants to throttle us
  * @dev: pointer to the serial device
  *
  * This structure is used by the usb-serial core and drivers for the specific
@@ -115,8 +114,6 @@ struct usb_serial_port {
 	unsigned long		flags;
 	wait_queue_head_t	write_wait;
 	struct work_struct	work;
-	char			throttled;
-	char			throttle_req;
 	unsigned long		sysrq; /* sysrq timeout */
 	struct device		dev;
 };

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/5] USB: serial: clean up throttle handling
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Clean up the throttle implementation by dropping the redundant
throttle_req flag which was a remnant from back when there was only a
single read URB.

Also convert the throttled flag to an atomic bit flag.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/generic.c | 34 ++++++++--------------------------
 include/linux/usb/serial.h   |  5 +----
 2 files changed, 9 insertions(+), 30 deletions(-)

diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 0fff4968ea1b..67cef3ef1e5f 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -106,12 +106,8 @@ void usb_serial_generic_deregister(void)
 int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int result = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&port->lock, flags);
-	port->throttled = 0;
-	port->throttle_req = 0;
-	spin_unlock_irqrestore(&port->lock, flags);
+	clear_bit(USB_SERIAL_THROTTLED, &port->flags);
 
 	if (port->bulk_in_size)
 		result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
@@ -375,7 +371,6 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 {
 	struct usb_serial_port *port = urb->context;
 	unsigned char *data = urb->transfer_buffer;
-	unsigned long flags;
 	bool stopped = false;
 	int status = urb->status;
 	int i;
@@ -429,15 +424,10 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
 	if (stopped)
 		return;
 
-	/* Throttle the device if requested by tty */
-	spin_lock_irqsave(&port->lock, flags);
-	port->throttled = port->throttle_req;
-	if (!port->throttled) {
-		spin_unlock_irqrestore(&port->lock, flags);
-		usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
-	} else {
-		spin_unlock_irqrestore(&port->lock, flags);
-	}
+	if (test_bit(USB_SERIAL_THROTTLED, &port->flags))
+		return;
+
+	usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
 
@@ -485,23 +475,16 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
 void usb_serial_generic_throttle(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&port->lock, flags);
-	port->throttle_req = 1;
-	spin_unlock_irqrestore(&port->lock, flags);
+	set_bit(USB_SERIAL_THROTTLED, &port->flags);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_throttle);
 
 void usb_serial_generic_unthrottle(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	int was_throttled;
 
-	spin_lock_irq(&port->lock);
-	was_throttled = port->throttled;
-	port->throttled = port->throttle_req = 0;
-	spin_unlock_irq(&port->lock);
+	clear_bit(USB_SERIAL_THROTTLED, &port->flags);
 
 	/*
 	 * Matches the smp_mb__after_atomic() in
@@ -509,8 +492,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
 	 */
 	smp_mb();
 
-	if (was_throttled)
-		usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
+	usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle);
 
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 1c19f77ed541..d8bdab8f3c26 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -28,6 +28,7 @@
 
 /* USB serial flags */
 #define USB_SERIAL_WRITE_BUSY	0
+#define USB_SERIAL_THROTTLED	1
 
 /**
  * usb_serial_port: structure for the specific ports of a device.
@@ -67,8 +68,6 @@
  * @flags: usb serial port flags
  * @write_wait: a wait_queue_head_t used by the port.
  * @work: work queue entry for the line discipline waking up.
- * @throttled: nonzero if the read urb is inactive to throttle the device
- * @throttle_req: nonzero if the tty wants to throttle us
  * @dev: pointer to the serial device
  *
  * This structure is used by the usb-serial core and drivers for the specific
@@ -115,8 +114,6 @@ struct usb_serial_port {
 	unsigned long		flags;
 	wait_queue_head_t	write_wait;
 	struct work_struct	work;
-	char			throttled;
-	char			throttle_req;
 	unsigned long		sysrq; /* sysrq timeout */
 	struct device		dev;
 };
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [3/5] USB: serial: generic: drop unnecessary goto
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Drop an unnecessary goto from a write-urb completion error path.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/generic.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 67cef3ef1e5f..1be8bea372a2 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -463,10 +463,9 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
 	default:
 		dev_err_console(port, "%s - nonzero urb status: %d\n",
 							__func__, status);
-		goto resubmit;
+		break;
 	}
 
-resubmit:
 	usb_serial_generic_write_start(port, GFP_ATOMIC);
 	usb_serial_port_softint(port);
 }

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 3/5] USB: serial: generic: drop unnecessary goto
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Drop an unnecessary goto from a write-urb completion error path.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/serial/generic.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 67cef3ef1e5f..1be8bea372a2 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -463,10 +463,9 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
 	default:
 		dev_err_console(port, "%s - nonzero urb status: %d\n",
 							__func__, status);
-		goto resubmit;
+		break;
 	}
 
-resubmit:
 	usb_serial_generic_write_start(port, GFP_ATOMIC);
 	usb_serial_port_softint(port);
 }
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [4/5] USB: cdc-acm: fix unthrottle races
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Fix two long-standing bugs which could potentially lead to memory
corruption or leave the port throttled until it is reopened (on weakly
ordered systems), respectively, when read-URB completion races with
unthrottle().

First, the URB must not be marked as free before processing is complete
to prevent it from being submitted by unthrottle() on another CPU.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  process_urb();
	  smp_mb__before_atomic();
	  set_bit(i, free);		  if (test_and_clear_bit(i, free))
						  submit_urb();

Second, the URB must be marked as free before checking the throttled
flag to prevent unthrottle() on another CPU from failing to observe that
the URB needs to be submitted if complete() sees that the throttled flag
is set.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  set_bit(i, free);		  throttled = 0;
	  smp_mb__after_atomic();	  smp_mb();
	  if (throttled)		  if (test_and_clear_bit(i, free))
		  return;			  submit_urb();

Note that test_and_clear_bit() only implies barriers when the test is
successful. To handle the case where the URB is still in use an explicit
barrier needs to be added to unthrottle() for the second race condition.

Also note that the first race was fixed by 36e59e0d70d6 ("cdc-acm: fix
race between callback and unthrottle") back in 2015, but the bug was
reintroduced a year later.

Fixes: 1aba579f3cf5 ("cdc-acm: handle read pipe errors")
Fixes: 088c64f81284 ("USB: cdc-acm: re-write read processing")
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/class/cdc-acm.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index ec666eb4b7b4..c03aa8550980 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -470,12 +470,12 @@ static void acm_read_bulk_callback(struct urb *urb)
 	struct acm *acm = rb->instance;
 	unsigned long flags;
 	int status = urb->status;
+	bool stopped = false;
+	bool stalled = false;
 
 	dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n",
 		rb->index, urb->actual_length, status);
 
-	set_bit(rb->index, &acm->read_urbs_free);
-
 	if (!acm->dev) {
 		dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
 		return;
@@ -488,15 +488,16 @@ static void acm_read_bulk_callback(struct urb *urb)
 		break;
 	case -EPIPE:
 		set_bit(EVENT_RX_STALL, &acm->flags);
-		schedule_work(&acm->work);
-		return;
+		stalled = true;
+		break;
 	case -ENOENT:
 	case -ECONNRESET:
 	case -ESHUTDOWN:
 		dev_dbg(&acm->data->dev,
 			"%s - urb shutting down with status: %d\n",
 			__func__, status);
-		return;
+		stopped = true;
+		break;
 	default:
 		dev_dbg(&acm->data->dev,
 			"%s - nonzero urb status received: %d\n",
@@ -505,10 +506,24 @@ static void acm_read_bulk_callback(struct urb *urb)
 	}
 
 	/*
-	 * Unthrottle may run on another CPU which needs to see events
-	 * in the same order. Submission has an implict barrier
+	 * Make sure URB processing is done before marking as free to avoid
+	 * racing with unthrottle() on another CPU. Matches the barriers
+	 * implied by the test_and_clear_bit() in acm_submit_read_urb().
 	 */
 	smp_mb__before_atomic();
+	set_bit(rb->index, &acm->read_urbs_free);
+	/*
+	 * Make sure URB is marked as free before checking the throttled flag
+	 * to avoid racing with unthrottle() on another CPU. Matches the
+	 * smp_mb() in unthrottle().
+	 */
+	smp_mb__after_atomic();
+
+	if (stopped || stalled) {
+		if (stalled)
+			schedule_work(&acm->work);
+		return;
+	}
 
 	/* throttle device if requested by tty */
 	spin_lock_irqsave(&acm->read_lock, flags);
@@ -842,6 +857,9 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
 	acm->throttle_req = 0;
 	spin_unlock_irq(&acm->read_lock);
 
+	/* Matches the smp_mb__after_atomic() in acm_read_bulk_callback(). */
+	smp_mb();
+
 	if (was_throttled)
 		acm_submit_read_urbs(acm, GFP_KERNEL);
 }

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 4/5] USB: cdc-acm: fix unthrottle races
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Fix two long-standing bugs which could potentially lead to memory
corruption or leave the port throttled until it is reopened (on weakly
ordered systems), respectively, when read-URB completion races with
unthrottle().

First, the URB must not be marked as free before processing is complete
to prevent it from being submitted by unthrottle() on another CPU.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  process_urb();
	  smp_mb__before_atomic();
	  set_bit(i, free);		  if (test_and_clear_bit(i, free))
						  submit_urb();

Second, the URB must be marked as free before checking the throttled
flag to prevent unthrottle() on another CPU from failing to observe that
the URB needs to be submitted if complete() sees that the throttled flag
is set.

	CPU 1				CPU 2
	================		================
	complete()			unthrottle()
	  set_bit(i, free);		  throttled = 0;
	  smp_mb__after_atomic();	  smp_mb();
	  if (throttled)		  if (test_and_clear_bit(i, free))
		  return;			  submit_urb();

Note that test_and_clear_bit() only implies barriers when the test is
successful. To handle the case where the URB is still in use an explicit
barrier needs to be added to unthrottle() for the second race condition.

Also note that the first race was fixed by 36e59e0d70d6 ("cdc-acm: fix
race between callback and unthrottle") back in 2015, but the bug was
reintroduced a year later.

Fixes: 1aba579f3cf5 ("cdc-acm: handle read pipe errors")
Fixes: 088c64f81284 ("USB: cdc-acm: re-write read processing")
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/class/cdc-acm.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index ec666eb4b7b4..c03aa8550980 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -470,12 +470,12 @@ static void acm_read_bulk_callback(struct urb *urb)
 	struct acm *acm = rb->instance;
 	unsigned long flags;
 	int status = urb->status;
+	bool stopped = false;
+	bool stalled = false;
 
 	dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n",
 		rb->index, urb->actual_length, status);
 
-	set_bit(rb->index, &acm->read_urbs_free);
-
 	if (!acm->dev) {
 		dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
 		return;
@@ -488,15 +488,16 @@ static void acm_read_bulk_callback(struct urb *urb)
 		break;
 	case -EPIPE:
 		set_bit(EVENT_RX_STALL, &acm->flags);
-		schedule_work(&acm->work);
-		return;
+		stalled = true;
+		break;
 	case -ENOENT:
 	case -ECONNRESET:
 	case -ESHUTDOWN:
 		dev_dbg(&acm->data->dev,
 			"%s - urb shutting down with status: %d\n",
 			__func__, status);
-		return;
+		stopped = true;
+		break;
 	default:
 		dev_dbg(&acm->data->dev,
 			"%s - nonzero urb status received: %d\n",
@@ -505,10 +506,24 @@ static void acm_read_bulk_callback(struct urb *urb)
 	}
 
 	/*
-	 * Unthrottle may run on another CPU which needs to see events
-	 * in the same order. Submission has an implict barrier
+	 * Make sure URB processing is done before marking as free to avoid
+	 * racing with unthrottle() on another CPU. Matches the barriers
+	 * implied by the test_and_clear_bit() in acm_submit_read_urb().
 	 */
 	smp_mb__before_atomic();
+	set_bit(rb->index, &acm->read_urbs_free);
+	/*
+	 * Make sure URB is marked as free before checking the throttled flag
+	 * to avoid racing with unthrottle() on another CPU. Matches the
+	 * smp_mb() in unthrottle().
+	 */
+	smp_mb__after_atomic();
+
+	if (stopped || stalled) {
+		if (stalled)
+			schedule_work(&acm->work);
+		return;
+	}
 
 	/* throttle device if requested by tty */
 	spin_lock_irqsave(&acm->read_lock, flags);
@@ -842,6 +857,9 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
 	acm->throttle_req = 0;
 	spin_unlock_irq(&acm->read_lock);
 
+	/* Matches the smp_mb__after_atomic() in acm_read_bulk_callback(). */
+	smp_mb();
+
 	if (was_throttled)
 		acm_submit_read_urbs(acm, GFP_KERNEL);
 }
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [5/5] USB: cdc-acm: clean up throttle handling
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Clean up the throttle implementation by dropping the redundant
throttle_req flag which was a remnant from back when USB serial had only
a single read URB, something which was later carried over to cdc-acm.

Also convert the throttled flag to an atomic bit flag.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/class/cdc-acm.c | 33 ++++++++-------------------------
 drivers/usb/class/cdc-acm.h |  3 +--
 2 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index c03aa8550980..183b41753c98 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -468,7 +468,6 @@ static void acm_read_bulk_callback(struct urb *urb)
 {
 	struct acm_rb *rb = urb->context;
 	struct acm *acm = rb->instance;
-	unsigned long flags;
 	int status = urb->status;
 	bool stopped = false;
 	bool stalled = false;
@@ -525,15 +524,10 @@ static void acm_read_bulk_callback(struct urb *urb)
 		return;
 	}
 
-	/* throttle device if requested by tty */
-	spin_lock_irqsave(&acm->read_lock, flags);
-	acm->throttled = acm->throttle_req;
-	if (!acm->throttled) {
-		spin_unlock_irqrestore(&acm->read_lock, flags);
-		acm_submit_read_urb(acm, rb->index, GFP_ATOMIC);
-	} else {
-		spin_unlock_irqrestore(&acm->read_lock, flags);
-	}
+	if (test_bit(ACM_THROTTLED, &acm->flags))
+		return;
+
+	acm_submit_read_urb(acm, rb->index, GFP_ATOMIC);
 }
 
 /* data interface wrote those outgoing bytes */
@@ -670,10 +664,7 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty)
 	/*
 	 * Unthrottle device in case the TTY was closed while throttled.
 	 */
-	spin_lock_irq(&acm->read_lock);
-	acm->throttled = 0;
-	acm->throttle_req = 0;
-	spin_unlock_irq(&acm->read_lock);
+	clear_bit(ACM_THROTTLED, &acm->flags);
 
 	retval = acm_submit_read_urbs(acm, GFP_KERNEL);
 	if (retval)
@@ -841,27 +832,19 @@ static void acm_tty_throttle(struct tty_struct *tty)
 {
 	struct acm *acm = tty->driver_data;
 
-	spin_lock_irq(&acm->read_lock);
-	acm->throttle_req = 1;
-	spin_unlock_irq(&acm->read_lock);
+	set_bit(ACM_THROTTLED, &acm->flags);
 }
 
 static void acm_tty_unthrottle(struct tty_struct *tty)
 {
 	struct acm *acm = tty->driver_data;
-	unsigned int was_throttled;
 
-	spin_lock_irq(&acm->read_lock);
-	was_throttled = acm->throttled;
-	acm->throttled = 0;
-	acm->throttle_req = 0;
-	spin_unlock_irq(&acm->read_lock);
+	clear_bit(ACM_THROTTLED, &acm->flags);
 
 	/* Matches the smp_mb__after_atomic() in acm_read_bulk_callback(). */
 	smp_mb();
 
-	if (was_throttled)
-		acm_submit_read_urbs(acm, GFP_KERNEL);
+	acm_submit_read_urbs(acm, GFP_KERNEL);
 }
 
 static int acm_tty_break_ctl(struct tty_struct *tty, int state)
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 515aad0847ee..ca1c026382c2 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -108,6 +108,7 @@ struct acm {
 	unsigned long flags;
 #		define EVENT_TTY_WAKEUP	0
 #		define EVENT_RX_STALL	1
+#		define ACM_THROTTLED	2
 	struct usb_cdc_line_coding line;		/* bits, stop, parity */
 	struct work_struct work;			/* work queue entry for line discipline waking up */
 	unsigned int ctrlin;				/* input control lines (DCD, DSR, RI, break, overruns) */
@@ -122,8 +123,6 @@ struct acm {
 	unsigned int ctrl_caps;				/* control capabilities from the class specific header */
 	unsigned int susp_count;			/* number of suspended interfaces */
 	unsigned int combined_interfaces:1;		/* control and data collapsed */
-	unsigned int throttled:1;			/* actually throttled */
-	unsigned int throttle_req:1;			/* throttle requested */
 	u8 bInterval;
 	struct usb_anchor delayed;			/* writes queued for a device about to be woken */
 	unsigned long quirks;

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 5/5] USB: cdc-acm: clean up throttle handling
@ 2019-04-25 16:05 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-25 16:05 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

Clean up the throttle implementation by dropping the redundant
throttle_req flag which was a remnant from back when USB serial had only
a single read URB, something which was later carried over to cdc-acm.

Also convert the throttled flag to an atomic bit flag.

Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/usb/class/cdc-acm.c | 33 ++++++++-------------------------
 drivers/usb/class/cdc-acm.h |  3 +--
 2 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index c03aa8550980..183b41753c98 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -468,7 +468,6 @@ static void acm_read_bulk_callback(struct urb *urb)
 {
 	struct acm_rb *rb = urb->context;
 	struct acm *acm = rb->instance;
-	unsigned long flags;
 	int status = urb->status;
 	bool stopped = false;
 	bool stalled = false;
@@ -525,15 +524,10 @@ static void acm_read_bulk_callback(struct urb *urb)
 		return;
 	}
 
-	/* throttle device if requested by tty */
-	spin_lock_irqsave(&acm->read_lock, flags);
-	acm->throttled = acm->throttle_req;
-	if (!acm->throttled) {
-		spin_unlock_irqrestore(&acm->read_lock, flags);
-		acm_submit_read_urb(acm, rb->index, GFP_ATOMIC);
-	} else {
-		spin_unlock_irqrestore(&acm->read_lock, flags);
-	}
+	if (test_bit(ACM_THROTTLED, &acm->flags))
+		return;
+
+	acm_submit_read_urb(acm, rb->index, GFP_ATOMIC);
 }
 
 /* data interface wrote those outgoing bytes */
@@ -670,10 +664,7 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty)
 	/*
 	 * Unthrottle device in case the TTY was closed while throttled.
 	 */
-	spin_lock_irq(&acm->read_lock);
-	acm->throttled = 0;
-	acm->throttle_req = 0;
-	spin_unlock_irq(&acm->read_lock);
+	clear_bit(ACM_THROTTLED, &acm->flags);
 
 	retval = acm_submit_read_urbs(acm, GFP_KERNEL);
 	if (retval)
@@ -841,27 +832,19 @@ static void acm_tty_throttle(struct tty_struct *tty)
 {
 	struct acm *acm = tty->driver_data;
 
-	spin_lock_irq(&acm->read_lock);
-	acm->throttle_req = 1;
-	spin_unlock_irq(&acm->read_lock);
+	set_bit(ACM_THROTTLED, &acm->flags);
 }
 
 static void acm_tty_unthrottle(struct tty_struct *tty)
 {
 	struct acm *acm = tty->driver_data;
-	unsigned int was_throttled;
 
-	spin_lock_irq(&acm->read_lock);
-	was_throttled = acm->throttled;
-	acm->throttled = 0;
-	acm->throttle_req = 0;
-	spin_unlock_irq(&acm->read_lock);
+	clear_bit(ACM_THROTTLED, &acm->flags);
 
 	/* Matches the smp_mb__after_atomic() in acm_read_bulk_callback(). */
 	smp_mb();
 
-	if (was_throttled)
-		acm_submit_read_urbs(acm, GFP_KERNEL);
+	acm_submit_read_urbs(acm, GFP_KERNEL);
 }
 
 static int acm_tty_break_ctl(struct tty_struct *tty, int state)
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 515aad0847ee..ca1c026382c2 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -108,6 +108,7 @@ struct acm {
 	unsigned long flags;
 #		define EVENT_TTY_WAKEUP	0
 #		define EVENT_RX_STALL	1
+#		define ACM_THROTTLED	2
 	struct usb_cdc_line_coding line;		/* bits, stop, parity */
 	struct work_struct work;			/* work queue entry for line discipline waking up */
 	unsigned int ctrlin;				/* input control lines (DCD, DSR, RI, break, overruns) */
@@ -122,8 +123,6 @@ struct acm {
 	unsigned int ctrl_caps;				/* control capabilities from the class specific header */
 	unsigned int susp_count;			/* number of suspended interfaces */
 	unsigned int combined_interfaces:1;		/* control and data collapsed */
-	unsigned int throttled:1;			/* actually throttled */
-	unsigned int throttle_req:1;			/* throttle requested */
 	u8 bInterval;
 	struct usb_anchor delayed;			/* writes queued for a device about to be woken */
 	unsigned long quirks;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/5] USB: fix tty unthrottle races
  2019-04-25 16:05 [PATCH 0/5] USB: fix tty unthrottle races Johan Hovold
  2019-04-25 16:05   ` [PATCH 1/5] " Johan Hovold
@ 2019-04-25 20:58 ` Alan Stern
  2019-04-26  4:55   ` Johan Hovold
  2019-04-29  9:30 ` Johan Hovold
  2 siblings, 1 reply; 29+ messages in thread
From: Alan Stern @ 2019-04-25 20:58 UTC (permalink / raw)
  To: Johan Hovold; +Cc: Oliver Neukum, Greg Kroah-Hartman, linux-usb

On Thu, 25 Apr 2019, Johan Hovold wrote:

> This series fixes a couple of long-standing issues in USB serial and
> cdc-acm which essentially share the same implementation.
> 
> As noted by Oliver a few years back, read-urb completion can race with
> unthrottle() running on another CPU and this can potentially lead to
> memory corruption. This particular bug in cdc-acm was unfortunately
> reintroduced a year later.
> 
> There's also a second race due to missing memory barriers which could
> theoretically lead to the port staying throttled until reopened on
> weakly ordered systems. A second set of memory barriers should address
> that.
> 
> I would appreciate your keen eyes on this one to make sure I got the
> barriers right.
> 
> I noticed there's some on-going discussion about the atomic memory
> barriers that Alan's involved in, and I'll try to catch up on his
> data-race work as well. I'm still a little concerned about whether the
> smp_mb__before_atomic() is sufficient to prevent the compiler from
> messing things up without adding READ_ONCE().

I think your changes in patches 1 and 4 are correct.  Regardless of the
issues still undergoing discussion elsewhere, smp_mb__before_atomic()
should cause both the compiler and the CPU to order every preceding
operation (READ_ONCE or not) before the atomic op.

Alan Stern

> Note that none of these have stable tags as the issues have been there
> for eight years or so without anyone noticing (besides Oliver).
> 
> Still feels good to clean up your own mess.
> 
> Note that the cdc-acm patches have so far only been compile tested.
> 
> Johan
> 
> 
> Johan Hovold (5):
>   USB: serial: fix unthrottle races
>   USB: serial: clean up throttle handling
>   USB: serial: generic: drop unnecessary goto
>   USB: cdc-acm: fix unthrottle races
>   USB: cdc-acm: clean up throttle handling
> 
>  drivers/usb/class/cdc-acm.c  | 63 +++++++++++++++---------------
>  drivers/usb/class/cdc-acm.h  |  3 +-
>  drivers/usb/serial/generic.c | 76 +++++++++++++++++++-----------------
>  include/linux/usb/serial.h   |  5 +--
>  4 files changed, 75 insertions(+), 72 deletions(-)
> 
> 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/5] USB: fix tty unthrottle races
  2019-04-25 20:58 ` [PATCH 0/5] USB: fix tty " Alan Stern
@ 2019-04-26  4:55   ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-26  4:55 UTC (permalink / raw)
  To: Alan Stern; +Cc: Johan Hovold, Oliver Neukum, Greg Kroah-Hartman, linux-usb

On Thu, Apr 25, 2019 at 04:58:20PM -0400, Alan Stern wrote:
> On Thu, 25 Apr 2019, Johan Hovold wrote:
> 
> > This series fixes a couple of long-standing issues in USB serial and
> > cdc-acm which essentially share the same implementation.
> > 
> > As noted by Oliver a few years back, read-urb completion can race with
> > unthrottle() running on another CPU and this can potentially lead to
> > memory corruption. This particular bug in cdc-acm was unfortunately
> > reintroduced a year later.
> > 
> > There's also a second race due to missing memory barriers which could
> > theoretically lead to the port staying throttled until reopened on
> > weakly ordered systems. A second set of memory barriers should address
> > that.
> > 
> > I would appreciate your keen eyes on this one to make sure I got the
> > barriers right.
> > 
> > I noticed there's some on-going discussion about the atomic memory
> > barriers that Alan's involved in, and I'll try to catch up on his
> > data-race work as well. I'm still a little concerned about whether the
> > smp_mb__before_atomic() is sufficient to prevent the compiler from
> > messing things up without adding READ_ONCE().
> 
> I think your changes in patches 1 and 4 are correct.  Regardless of the
> issues still undergoing discussion elsewhere, smp_mb__before_atomic()
> should cause both the compiler and the CPU to order every preceding
> operation (READ_ONCE or not) before the atomic op.

Ok, thanks for taking a look!

Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/5] USB: fix tty unthrottle races
  2019-04-25 16:05 [PATCH 0/5] USB: fix tty unthrottle races Johan Hovold
  2019-04-25 16:05   ` [PATCH 1/5] " Johan Hovold
  2019-04-25 20:58 ` [PATCH 0/5] USB: fix tty " Alan Stern
@ 2019-04-29  9:30 ` Johan Hovold
  2 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-29  9:30 UTC (permalink / raw)
  To: Alan Stern, Oliver Neukum, Greg Kroah-Hartman; +Cc: linux-usb, Johan Hovold

On Thu, Apr 25, 2019 at 06:05:35PM +0200, Johan Hovold wrote:
> This series fixes a couple of long-standing issues in USB serial and
> cdc-acm which essentially share the same implementation.
> 
> As noted by Oliver a few years back, read-urb completion can race with
> unthrottle() running on another CPU and this can potentially lead to
> memory corruption. This particular bug in cdc-acm was unfortunately
> reintroduced a year later.
> 
> There's also a second race due to missing memory barriers which could
> theoretically lead to the port staying throttled until reopened on
> weakly ordered systems. A second set of memory barriers should address
> that.

> Note that the cdc-acm patches have so far only been compile tested.

I've tested also the cdc-acm changes now.

So unless anyone complains, I'll apply the USB-serial ones in a few
days, and maybe Greg can pick up the cdc-acm patches.

Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [1/5] USB: serial: fix unthrottle races
@ 2019-04-29  9:50 ` Oliver Neukum
  0 siblings, 0 replies; 29+ messages in thread
From: Oliver Neukum @ 2019-04-29  9:50 UTC (permalink / raw)
  To: Johan Hovold, Greg Kroah-Hartman, Alan Stern; +Cc: linux-usb

On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> @@ -484,6 +503,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
>         port->throttled = port->throttle_req = 0;
>         spin_unlock_irq(&port->lock);
>  
> +       /*
> +        * Matches the smp_mb__after_atomic() in
> +        * usb_serial_generic_read_bulk_callback().
> +        */
> +       smp_mb();
> +
>         if (was_throttled)
>                 usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);


Doesn't the spin_unlock_irq() imply smp_mb()?
Otherwise it looks correct to me.

	Regards
		Oliver

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
@ 2019-04-29  9:50 ` Oliver Neukum
  0 siblings, 0 replies; 29+ messages in thread
From: Oliver Neukum @ 2019-04-29  9:50 UTC (permalink / raw)
  To: Johan Hovold, Greg Kroah-Hartman, Alan Stern; +Cc: linux-usb

On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> @@ -484,6 +503,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
>         port->throttled = port->throttle_req = 0;
>         spin_unlock_irq(&port->lock);
>  
> +       /*
> +        * Matches the smp_mb__after_atomic() in
> +        * usb_serial_generic_read_bulk_callback().
> +        */
> +       smp_mb();
> +
>         if (was_throttled)
>                 usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);


Doesn't the spin_unlock_irq() imply smp_mb()?
Otherwise it looks correct to me.

	Regards
		Oliver


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [1/5] USB: serial: fix unthrottle races
@ 2019-04-29 10:03 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-29 10:03 UTC (permalink / raw)
  To: Oliver Neukum; +Cc: Johan Hovold, Greg Kroah-Hartman, Alan Stern, linux-usb

On Mon, Apr 29, 2019 at 11:50:58AM +0200, Oliver Neukum wrote:
> On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> > @@ -484,6 +503,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
> >         port->throttled = port->throttle_req = 0;
> >         spin_unlock_irq(&port->lock);
> >  
> > +       /*
> > +        * Matches the smp_mb__after_atomic() in
> > +        * usb_serial_generic_read_bulk_callback().
> > +        */
> > +       smp_mb();
> > +
> >         if (was_throttled)
> >                 usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
> 
> 
> Doesn't the spin_unlock_irq() imply smp_mb()?
> Otherwise it looks correct to me.

No, spin_unlock_irq() is only a one-way barrier, and doesn't prevent
later accesses from "moving" into the locked section.

Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
@ 2019-04-29 10:03 ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-04-29 10:03 UTC (permalink / raw)
  To: Oliver Neukum; +Cc: Johan Hovold, Greg Kroah-Hartman, Alan Stern, linux-usb

On Mon, Apr 29, 2019 at 11:50:58AM +0200, Oliver Neukum wrote:
> On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> > @@ -484,6 +503,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
> >         port->throttled = port->throttle_req = 0;
> >         spin_unlock_irq(&port->lock);
> >  
> > +       /*
> > +        * Matches the smp_mb__after_atomic() in
> > +        * usb_serial_generic_read_bulk_callback().
> > +        */
> > +       smp_mb();
> > +
> >         if (was_throttled)
> >                 usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);
> 
> 
> Doesn't the spin_unlock_irq() imply smp_mb()?
> Otherwise it looks correct to me.

No, spin_unlock_irq() is only a one-way barrier, and doesn't prevent
later accesses from "moving" into the locked section.

Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [4/5] USB: cdc-acm: fix unthrottle races
@ 2019-04-29 10:09 ` Oliver Neukum
  0 siblings, 0 replies; 29+ messages in thread
From: Oliver Neukum @ 2019-04-29 10:09 UTC (permalink / raw)
  To: Johan Hovold, Greg Kroah-Hartman, Alan Stern; +Cc: linux-usb

On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> Fix two long-standing bugs which could potentially lead to memory
> corruption or leave the port throttled until it is reopened (on weakly
> ordered systems), respectively, when read-URB completion races with
> unthrottle().
> 
> First, the URB must not be marked as free before processing is complete
> to prevent it from being submitted by unthrottle() on another CPU.
> 
>         CPU 1                           CPU 2
>         ================                ================
>         complete()                      unthrottle()
>           process_urb();
>           smp_mb__before_atomic();
>           set_bit(i, free);               if (test_and_clear_bit(i, free))
>                                                   submit_urb();
> 
> Second, the URB must be marked as free before checking the throttled
> flag to prevent unthrottle() on another CPU from failing to observe that
> the URB needs to be submitted if complete() sees that the throttled flag
> is set.
> 
>         CPU 1                           CPU 2
>         ================                ================
>         complete()                      unthrottle()
>           set_bit(i, free);               throttled = 0;
>           smp_mb__after_atomic();         smp_mb();
>           if (throttled)                  if (test_and_clear_bit(i, free))
>                   return;                         submit_urb();
> 
> Note that test_and_clear_bit() only implies barriers when the test is
> successful. To handle the case where the URB is still in use an explicit
> barrier needs to be added to unthrottle() for the second race condition.
> 
> Also note that the first race was fixed by 36e59e0d70d6 ("cdc-acm: fix
> race between callback and unthrottle") back in 2015, but the bug was
> reintroduced a year later.
> 
> Fixes: 1aba579f3cf5 ("cdc-acm: handle read pipe errors")
> Fixes: 088c64f81284 ("USB: cdc-acm: re-write read processing")
> Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Oliver Neukum <oneukum@suse.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 4/5] USB: cdc-acm: fix unthrottle races
@ 2019-04-29 10:09 ` Oliver Neukum
  0 siblings, 0 replies; 29+ messages in thread
From: Oliver Neukum @ 2019-04-29 10:09 UTC (permalink / raw)
  To: Johan Hovold, Greg Kroah-Hartman, Alan Stern; +Cc: linux-usb

On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> Fix two long-standing bugs which could potentially lead to memory
> corruption or leave the port throttled until it is reopened (on weakly
> ordered systems), respectively, when read-URB completion races with
> unthrottle().
> 
> First, the URB must not be marked as free before processing is complete
> to prevent it from being submitted by unthrottle() on another CPU.
> 
>         CPU 1                           CPU 2
>         ================                ================
>         complete()                      unthrottle()
>           process_urb();
>           smp_mb__before_atomic();
>           set_bit(i, free);               if (test_and_clear_bit(i, free))
>                                                   submit_urb();
> 
> Second, the URB must be marked as free before checking the throttled
> flag to prevent unthrottle() on another CPU from failing to observe that
> the URB needs to be submitted if complete() sees that the throttled flag
> is set.
> 
>         CPU 1                           CPU 2
>         ================                ================
>         complete()                      unthrottle()
>           set_bit(i, free);               throttled = 0;
>           smp_mb__after_atomic();         smp_mb();
>           if (throttled)                  if (test_and_clear_bit(i, free))
>                   return;                         submit_urb();
> 
> Note that test_and_clear_bit() only implies barriers when the test is
> successful. To handle the case where the URB is still in use an explicit
> barrier needs to be added to unthrottle() for the second race condition.
> 
> Also note that the first race was fixed by 36e59e0d70d6 ("cdc-acm: fix
> race between callback and unthrottle") back in 2015, but the bug was
> reintroduced a year later.
> 
> Fixes: 1aba579f3cf5 ("cdc-acm: handle read pipe errors")
> Fixes: 088c64f81284 ("USB: cdc-acm: re-write read processing")
> Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Oliver Neukum <oneukum@suse.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [5/5] USB: cdc-acm: clean up throttle handling
@ 2019-04-29 10:10 ` Oliver Neukum
  0 siblings, 0 replies; 29+ messages in thread
From: Oliver Neukum @ 2019-04-29 10:10 UTC (permalink / raw)
  To: Johan Hovold, Greg Kroah-Hartman, Alan Stern; +Cc: linux-usb

On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> Clean up the throttle implementation by dropping the redundant
> throttle_req flag which was a remnant from back when USB serial had only
> a single read URB, something which was later carried over to cdc-acm.
> 
> Also convert the throttled flag to an atomic bit flag.
> 
> Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Oliver Neukum <oneukum@suse.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 5/5] USB: cdc-acm: clean up throttle handling
@ 2019-04-29 10:10 ` Oliver Neukum
  0 siblings, 0 replies; 29+ messages in thread
From: Oliver Neukum @ 2019-04-29 10:10 UTC (permalink / raw)
  To: Johan Hovold, Greg Kroah-Hartman, Alan Stern; +Cc: linux-usb

On Do, 2019-04-25 at 18:05 +0200, Johan Hovold wrote:
> Clean up the throttle implementation by dropping the redundant
> throttle_req flag which was a remnant from back when USB serial had only
> a single read URB, something which was later carried over to cdc-acm.
> 
> Also convert the throttled flag to an atomic bit flag.
> 
> Signed-off-by: Johan Hovold <johan@kernel.org>
Acked-by: Oliver Neukum <oneukum@suse.com>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
  2019-04-25 16:05   ` [PATCH 1/5] " Johan Hovold
  (?)
@ 2019-05-13 10:43   ` Johan Hovold
  2019-05-13 10:56     ` Greg Kroah-Hartman
  -1 siblings, 1 reply; 29+ messages in thread
From: Johan Hovold @ 2019-05-13 10:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-usb, Johan Hovold, Alan Stern, Oliver Neukum, stable

On Thu, Apr 25, 2019 at 06:05:36PM +0200, Johan Hovold wrote:
> Fix two long-standing bugs which could potentially lead to memory
> corruption or leave the port throttled until it is reopened (on weakly
> ordered systems), respectively, when read-URB completion races with
> unthrottle().
> 
> First, the URB must not be marked as free before processing is complete
> to prevent it from being submitted by unthrottle() on another CPU.
> 
> 	CPU 1				CPU 2
> 	================		================
> 	complete()			unthrottle()
> 	  process_urb();
> 	  smp_mb__before_atomic();
> 	  set_bit(i, free);		  if (test_and_clear_bit(i, free))
> 	  					  submit_urb();
> 
> Second, the URB must be marked as free before checking the throttled
> flag to prevent unthrottle() on another CPU from failing to observe that
> the URB needs to be submitted if complete() sees that the throttled flag
> is set.
> 
> 	CPU 1				CPU 2
> 	================		================
> 	complete()			unthrottle()
> 	  set_bit(i, free);		  throttled = 0;
> 	  smp_mb__after_atomic();	  smp_mb();
> 	  if (throttled)		  if (test_and_clear_bit(i, free))
> 	  	  return;			  submit_urb();
> 
> Note that test_and_clear_bit() only implies barriers when the test is
> successful. To handle the case where the URB is still in use an explicit
> barrier needs to be added to unthrottle() for the second race condition.
> 
> Fixes: d83b405383c9 ("USB: serial: add support for multiple read urbs")
> Signed-off-by: Johan Hovold <johan@kernel.org>

Greg, I noticed you added a stable tag to the corresponding cdc-acm fix
and think I should have added on one from the start to this one as well.

Would you mind queuing this one up for stable?

Upstream commit 3f5edd58d040bfa4b74fb89bc02f0bc6b9cd06ab.

Thanks,
Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
  2019-05-13 10:43   ` Johan Hovold
@ 2019-05-13 10:56     ` Greg Kroah-Hartman
  2019-05-13 11:46       ` Johan Hovold
  0 siblings, 1 reply; 29+ messages in thread
From: Greg Kroah-Hartman @ 2019-05-13 10:56 UTC (permalink / raw)
  To: Johan Hovold; +Cc: linux-usb, Alan Stern, Oliver Neukum, stable

On Mon, May 13, 2019 at 12:43:39PM +0200, Johan Hovold wrote:
> On Thu, Apr 25, 2019 at 06:05:36PM +0200, Johan Hovold wrote:
> > Fix two long-standing bugs which could potentially lead to memory
> > corruption or leave the port throttled until it is reopened (on weakly
> > ordered systems), respectively, when read-URB completion races with
> > unthrottle().
> > 
> > First, the URB must not be marked as free before processing is complete
> > to prevent it from being submitted by unthrottle() on another CPU.
> > 
> > 	CPU 1				CPU 2
> > 	================		================
> > 	complete()			unthrottle()
> > 	  process_urb();
> > 	  smp_mb__before_atomic();
> > 	  set_bit(i, free);		  if (test_and_clear_bit(i, free))
> > 	  					  submit_urb();
> > 
> > Second, the URB must be marked as free before checking the throttled
> > flag to prevent unthrottle() on another CPU from failing to observe that
> > the URB needs to be submitted if complete() sees that the throttled flag
> > is set.
> > 
> > 	CPU 1				CPU 2
> > 	================		================
> > 	complete()			unthrottle()
> > 	  set_bit(i, free);		  throttled = 0;
> > 	  smp_mb__after_atomic();	  smp_mb();
> > 	  if (throttled)		  if (test_and_clear_bit(i, free))
> > 	  	  return;			  submit_urb();
> > 
> > Note that test_and_clear_bit() only implies barriers when the test is
> > successful. To handle the case where the URB is still in use an explicit
> > barrier needs to be added to unthrottle() for the second race condition.
> > 
> > Fixes: d83b405383c9 ("USB: serial: add support for multiple read urbs")
> > Signed-off-by: Johan Hovold <johan@kernel.org>
> 
> Greg, I noticed you added a stable tag to the corresponding cdc-acm fix
> and think I should have added on one from the start to this one as well.
> 
> Would you mind queuing this one up for stable?
> 
> Upstream commit 3f5edd58d040bfa4b74fb89bc02f0bc6b9cd06ab.

Sure, now queued up for 4.9+

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
  2019-05-13 10:56     ` Greg Kroah-Hartman
@ 2019-05-13 11:46       ` Johan Hovold
  2019-05-13 12:51         ` Greg Kroah-Hartman
  0 siblings, 1 reply; 29+ messages in thread
From: Johan Hovold @ 2019-05-13 11:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Johan Hovold, linux-usb, Alan Stern, Oliver Neukum, stable

On Mon, May 13, 2019 at 12:56:06PM +0200, Greg Kroah-Hartman wrote:
> On Mon, May 13, 2019 at 12:43:39PM +0200, Johan Hovold wrote:
> > On Thu, Apr 25, 2019 at 06:05:36PM +0200, Johan Hovold wrote:
> > > Fix two long-standing bugs which could potentially lead to memory
> > > corruption or leave the port throttled until it is reopened (on weakly
> > > ordered systems), respectively, when read-URB completion races with
> > > unthrottle().

> > > Fixes: d83b405383c9 ("USB: serial: add support for multiple read urbs")
> > > Signed-off-by: Johan Hovold <johan@kernel.org>
> > 
> > Greg, I noticed you added a stable tag to the corresponding cdc-acm fix
> > and think I should have added on one from the start to this one as well.
> > 
> > Would you mind queuing this one up for stable?
> > 
> > Upstream commit 3f5edd58d040bfa4b74fb89bc02f0bc6b9cd06ab.
> 
> Sure, now queued up for 4.9+

Thanks. The issue has been there since v3.3 so I guess you could queue
it for all stable trees.

Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
  2019-05-13 11:46       ` Johan Hovold
@ 2019-05-13 12:51         ` Greg Kroah-Hartman
  2019-05-13 12:59           ` Johan Hovold
  0 siblings, 1 reply; 29+ messages in thread
From: Greg Kroah-Hartman @ 2019-05-13 12:51 UTC (permalink / raw)
  To: Johan Hovold; +Cc: linux-usb, Alan Stern, Oliver Neukum, stable

On Mon, May 13, 2019 at 01:46:01PM +0200, Johan Hovold wrote:
> On Mon, May 13, 2019 at 12:56:06PM +0200, Greg Kroah-Hartman wrote:
> > On Mon, May 13, 2019 at 12:43:39PM +0200, Johan Hovold wrote:
> > > On Thu, Apr 25, 2019 at 06:05:36PM +0200, Johan Hovold wrote:
> > > > Fix two long-standing bugs which could potentially lead to memory
> > > > corruption or leave the port throttled until it is reopened (on weakly
> > > > ordered systems), respectively, when read-URB completion races with
> > > > unthrottle().
> 
> > > > Fixes: d83b405383c9 ("USB: serial: add support for multiple read urbs")
> > > > Signed-off-by: Johan Hovold <johan@kernel.org>
> > > 
> > > Greg, I noticed you added a stable tag to the corresponding cdc-acm fix
> > > and think I should have added on one from the start to this one as well.
> > > 
> > > Would you mind queuing this one up for stable?
> > > 
> > > Upstream commit 3f5edd58d040bfa4b74fb89bc02f0bc6b9cd06ab.
> > 
> > Sure, now queued up for 4.9+
> 
> Thanks. The issue has been there since v3.3 so I guess you could queue
> it for all stable trees.

Doesn't apply cleanly for 4.4.y or 3.18.y, so if it's really worth
adding there (and I kind of doubt it), I would need a backport :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
  2019-05-13 12:51         ` Greg Kroah-Hartman
@ 2019-05-13 12:59           ` Johan Hovold
  2019-05-14 12:53             ` Sasha Levin
  0 siblings, 1 reply; 29+ messages in thread
From: Johan Hovold @ 2019-05-13 12:59 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Johan Hovold, linux-usb, Alan Stern, Oliver Neukum, stable

On Mon, May 13, 2019 at 02:51:31PM +0200, Greg Kroah-Hartman wrote:
> On Mon, May 13, 2019 at 01:46:01PM +0200, Johan Hovold wrote:

> > Thanks. The issue has been there since v3.3 so I guess you could queue
> > it for all stable trees.
> 
> Doesn't apply cleanly for 4.4.y or 3.18.y, so if it's really worth
> adding there (and I kind of doubt it), I would need a backport :)

Ah ok, just wasn't sure why you chose 4.9+.

Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
  2019-05-13 12:59           ` Johan Hovold
@ 2019-05-14 12:53             ` Sasha Levin
  2019-05-14 12:57               ` Johan Hovold
  0 siblings, 1 reply; 29+ messages in thread
From: Sasha Levin @ 2019-05-14 12:53 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Greg Kroah-Hartman, linux-usb, Alan Stern, Oliver Neukum, stable

On Mon, May 13, 2019 at 02:59:09PM +0200, Johan Hovold wrote:
>On Mon, May 13, 2019 at 02:51:31PM +0200, Greg Kroah-Hartman wrote:
>> On Mon, May 13, 2019 at 01:46:01PM +0200, Johan Hovold wrote:
>
>> > Thanks. The issue has been there since v3.3 so I guess you could queue
>> > it for all stable trees.
>>
>> Doesn't apply cleanly for 4.4.y or 3.18.y, so if it's really worth
>> adding there (and I kind of doubt it), I would need a backport :)
>
>Ah ok, just wasn't sure why you chose 4.9+.

On 4.4 and 3.18 it just had a contextual conflict because of
3161da970d38c ("USB: serial: use variable for status"), I can queue both
3161da970d38c and 3f5edd58d040b for 4.4 and 3.18.

--
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/5] USB: serial: fix unthrottle races
  2019-05-14 12:53             ` Sasha Levin
@ 2019-05-14 12:57               ` Johan Hovold
  0 siblings, 0 replies; 29+ messages in thread
From: Johan Hovold @ 2019-05-14 12:57 UTC (permalink / raw)
  To: Sasha Levin
  Cc: Johan Hovold, Greg Kroah-Hartman, linux-usb, Alan Stern,
	Oliver Neukum, stable

On Tue, May 14, 2019 at 08:53:53AM -0400, Sasha Levin wrote:
> On Mon, May 13, 2019 at 02:59:09PM +0200, Johan Hovold wrote:
> >On Mon, May 13, 2019 at 02:51:31PM +0200, Greg Kroah-Hartman wrote:
> >> On Mon, May 13, 2019 at 01:46:01PM +0200, Johan Hovold wrote:
> >
> >> > Thanks. The issue has been there since v3.3 so I guess you could queue
> >> > it for all stable trees.
> >>
> >> Doesn't apply cleanly for 4.4.y or 3.18.y, so if it's really worth
> >> adding there (and I kind of doubt it), I would need a backport :)
> >
> >Ah ok, just wasn't sure why you chose 4.9+.
> 
> On 4.4 and 3.18 it just had a contextual conflict because of
> 3161da970d38c ("USB: serial: use variable for status"), I can queue both
> 3161da970d38c and 3f5edd58d040b for 4.4 and 3.18.

Sounds good, thanks!

Johan

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2019-05-14 12:57 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-25 16:05 [PATCH 0/5] USB: fix tty unthrottle races Johan Hovold
2019-04-25 16:05 ` [1/5] USB: serial: fix " Johan Hovold
2019-04-25 16:05   ` [PATCH 1/5] " Johan Hovold
2019-05-13 10:43   ` Johan Hovold
2019-05-13 10:56     ` Greg Kroah-Hartman
2019-05-13 11:46       ` Johan Hovold
2019-05-13 12:51         ` Greg Kroah-Hartman
2019-05-13 12:59           ` Johan Hovold
2019-05-14 12:53             ` Sasha Levin
2019-05-14 12:57               ` Johan Hovold
2019-04-25 20:58 ` [PATCH 0/5] USB: fix tty " Alan Stern
2019-04-26  4:55   ` Johan Hovold
2019-04-29  9:30 ` Johan Hovold
2019-04-25 16:05 [2/5] USB: serial: clean up throttle handling Johan Hovold
2019-04-25 16:05 ` [PATCH 2/5] " Johan Hovold
2019-04-25 16:05 [3/5] USB: serial: generic: drop unnecessary goto Johan Hovold
2019-04-25 16:05 ` [PATCH 3/5] " Johan Hovold
2019-04-25 16:05 [4/5] USB: cdc-acm: fix unthrottle races Johan Hovold
2019-04-25 16:05 ` [PATCH 4/5] " Johan Hovold
2019-04-25 16:05 [5/5] USB: cdc-acm: clean up throttle handling Johan Hovold
2019-04-25 16:05 ` [PATCH 5/5] " Johan Hovold
2019-04-29  9:50 [1/5] USB: serial: fix unthrottle races Oliver Neukum
2019-04-29  9:50 ` [PATCH 1/5] " Oliver Neukum
2019-04-29 10:03 [1/5] " Johan Hovold
2019-04-29 10:03 ` [PATCH 1/5] " Johan Hovold
2019-04-29 10:09 [4/5] USB: cdc-acm: " Oliver Neukum
2019-04-29 10:09 ` [PATCH 4/5] " Oliver Neukum
2019-04-29 10:10 [5/5] USB: cdc-acm: clean up throttle handling Oliver Neukum
2019-04-29 10:10 ` [PATCH 5/5] " Oliver Neukum

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.