Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b80349b1 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

USB: fix race in visor_write



this fixes a small race in visor_write.


Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent b19d402a
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -384,19 +384,21 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
		dbg("%s - write limit hit\n", __FUNCTION__);
		return 0;
	}
	priv->outstanding_urbs++;
	spin_unlock_irqrestore(&priv->lock, flags);

	buffer = kmalloc (count, GFP_ATOMIC);
	if (!buffer) {
		dev_err(&port->dev, "out of memory\n");
		return -ENOMEM;
		count = -ENOMEM;
		goto error_no_buffer;
	}

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		dev_err(&port->dev, "no more free urbs\n");
		kfree (buffer);
		return -ENOMEM;
		count = -ENOMEM;
		goto error_no_urb;
	}

	memcpy (buffer, buf, count);
@@ -415,10 +417,9 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
		dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n",
			__FUNCTION__, status);
		count = status;
		kfree (buffer);
		goto error;
	} else {
		spin_lock_irqsave(&priv->lock, flags);
		++priv->outstanding_urbs;
		priv->bytes_out += count;
		spin_unlock_irqrestore(&priv->lock, flags);
	}
@@ -427,6 +428,15 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
	 * really free it when it is finished with it */
	usb_free_urb(urb);

	return count;
error:
	usb_free_urb(urb);
error_no_urb:
	kfree(buffer);
error_no_buffer:
	spin_lock_irqsave(&priv->lock, flags);
	--priv->outstanding_urbs;
	spin_unlock_irqrestore(&priv->lock, flags);
	return count;
}