Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b80349b17c6e1236a24616f71e59ed31279de25a
Commit:     b80349b17c6e1236a24616f71e59ed31279de25a
Parent:     b19d402a3450bb2597d0c1b54f6139462a5f35ae
Author:     Oliver Neukum <[EMAIL PROTECTED]>
AuthorDate: Fri Mar 23 11:58:03 2007 +0100
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Fri Apr 27 13:28:38 2007 -0700

    USB: fix race in visor_write
    
    this fixes a small race in visor_write.
    
    
    Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/usb/serial/visor.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 2f59ff2..ffbe601 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -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,19 +417,27 @@ 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);
        }
 
        /* we are done with this urb, so let the host driver
         * really free it when it is finished with it */
-       usb_free_urb (urb);
+       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;
 }
 
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to