From: Johan Hovold Date: Mon, 26 Oct 2020 08:25:48 +0000 (+0100) Subject: USB: serial: cyberjack: fix write-URB completion race X-Git-Tag: v4.9.242~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9690d9dcdfbe6e12bb942cb34ac9b80102a81f02;p=platform%2Fkernel%2Flinux-amlogic.git USB: serial: cyberjack: fix write-URB completion race commit 985616f0457d9f555fff417d0da56174f70cc14f upstream. The write-URB busy flag was being cleared before the completion handler was done with the URB, something which could lead to corrupt transfers due to a racing write request if the URB is resubmitted. Fixes: 507ca9bc0476 ("[PATCH] USB: add ability for usb-serial drivers to determine if their write urb is currently being used.") Cc: stable # 2.6.13 Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 80260b08398b..b22a7b487a9f 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -367,11 +367,12 @@ static void cyberjack_write_bulk_callback(struct urb *urb) struct cyberjack_private *priv = usb_get_serial_port_data(port); struct device *dev = &port->dev; int status = urb->status; + bool resubmitted = false; - set_bit(0, &port->write_urbs_free); if (status) { dev_dbg(dev, "%s - nonzero write bulk status received: %d\n", __func__, status); + set_bit(0, &port->write_urbs_free); return; } @@ -404,6 +405,8 @@ static void cyberjack_write_bulk_callback(struct urb *urb) goto exit; } + resubmitted = true; + dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent); dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled); @@ -420,6 +423,8 @@ static void cyberjack_write_bulk_callback(struct urb *urb) exit: spin_unlock(&priv->lock); + if (!resubmitted) + set_bit(0, &port->write_urbs_free); usb_serial_port_softint(port); }