Commit 985616f0 authored by Johan Hovold's avatar Johan Hovold
Browse files

USB: serial: cyberjack: fix write-URB completion race



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: 507ca9bc ("[PATCH] USB: add ability for usb-serial drivers to determine if their write urb is currently being used.")
Cc: stable <stable@vger.kernel.org>     # 2.6.13
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent a46b973b
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -357,11 +357,12 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
	struct device *dev = &port->dev;
	int status = urb->status;
	unsigned long flags;
	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;
	}

@@ -394,6 +395,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);

@@ -410,6 +413,8 @@ static void cyberjack_write_bulk_callback(struct urb *urb)

exit:
	spin_unlock_irqrestore(&priv->lock, flags);
	if (!resubmitted)
		set_bit(0, &port->write_urbs_free);
	usb_serial_port_softint(port);
}