On Fri, Jun 04, 2004 at 05:34:41PM +0100, Ian Abbott wrote:
On 04/06/2004 15:59, nardelli wrote:
A related problem with the current implementation is that is easy to run out of memory by running something similar to this:
# cat /dev/zero > /dev/ttyUSB0
That affects both the ftdi_sio and visor drivers.
Care to try out the following (build test only) patch to the visor
driver to see if it prevents this from happening? I don't have a
working visor right now to test it out myself :(
Oops, ignore the fact that we never free the structure on disconnect, I
see that now...
thanks,
greg k-h
===== drivers/usb/serial/visor.c 1.114 vs edited =====
--- 1.114/drivers/usb/serial/visor.c Fri Jun 4 07:13:10 2004
+++ edited/drivers/usb/serial/visor.c Fri Jun 4 17:12:53 2004
+/* number of outstanding urbs to prevent userspace DoS from happening */
+#define URB_UPPER_LIMIT 42
static int visor_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
{
+ struct visor_private *priv = usb_get_serial_port_data(port);
struct usb_serial *serial = port->serial;
struct urb *urb;
unsigned char *buffer;
+ unsigned long flags;
int status;
dbg("%s - port %d", __FUNCTION__, port->number);
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dev_dbg(&port->dev, "write limit hit\n");
+ 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");
@@ -520,7 +545,10 @@
count = status;
kfree (buffer);
} else {
- bytes_out += count;
+ spin_lock_irqsave(&priv->lock, flags);
+ ++priv->outstanding_urbs;
+ priv->bytes_out += count;
+ spin_unlock_irqrestore(&priv->lock, flags);
}
/* we are done with this urb, so let the host driver