USB: keyspan_pda: fix DMA buffers on stack
authorJohan Hovold <jhovold@gmail.com>
Mon, 28 Dec 2009 22:01:51 +0000 (23:01 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Mar 2010 22:53:54 +0000 (14:53 -0800)
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/serial/keyspan_pda.c

index 1296a09..427d377 100644 (file)
@@ -429,13 +429,20 @@ static int keyspan_pda_get_modem_info(struct usb_serial *serial,
                                      unsigned char *value)
 {
        int rc;
-       unsigned char data;
+       u8 *data;
+
+       data = kmalloc(1, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
        rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                             3, /* get pins */
                             USB_TYPE_VENDOR|USB_RECIP_INTERFACE|USB_DIR_IN,
-                            0, 0, &data, 1, 2000);
+                            0, 0, data, 1, 2000);
        if (rc >= 0)
-               *value = data;
+               *value = *data;
+
+       kfree(data);
        return rc;
 }
 
@@ -543,7 +550,14 @@ static int keyspan_pda_write(struct tty_struct *tty,
           device how much room it really has.  This is done only on
           scheduler time, since usb_control_msg() sleeps. */
        if (count > priv->tx_room && !in_interrupt()) {
-               unsigned char room;
+               u8 *room;
+
+               room = kmalloc(1, GFP_KERNEL);
+               if (!room) {
+                       rc = -ENOMEM;
+                       goto exit;
+               }
+
                rc = usb_control_msg(serial->dev,
                                     usb_rcvctrlpipe(serial->dev, 0),
                                     6, /* write_room */
@@ -551,9 +565,14 @@ static int keyspan_pda_write(struct tty_struct *tty,
                                     | USB_DIR_IN,
                                     0, /* value: 0 means "remaining room" */
                                     0, /* index */
-                                    &room,
+                                    room,
                                     1,
                                     2000);
+               if (rc > 0) {
+                       dbg(" roomquery says %d", *room);
+                       priv->tx_room = *room;
+               }
+               kfree(room);
                if (rc < 0) {
                        dbg(" roomquery failed");
                        goto exit;
@@ -563,8 +582,6 @@ static int keyspan_pda_write(struct tty_struct *tty,
                        rc = -EIO; /* device didn't return any data */
                        goto exit;
                }
-               dbg(" roomquery says %d", room);
-               priv->tx_room = room;
        }
        if (count > priv->tx_room) {
                /* we're about to completely fill the Tx buffer, so
@@ -684,18 +701,22 @@ static int keyspan_pda_open(struct tty_struct *tty,
                                        struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
-       unsigned char room;
+       u8 *room;
        int rc = 0;
        struct keyspan_pda_private *priv;
 
        /* find out how much room is in the Tx ring */
+       room = kmalloc(1, GFP_KERNEL);
+       if (!room)
+               return -ENOMEM;
+
        rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
                             6, /* write_room */
                             USB_TYPE_VENDOR | USB_RECIP_INTERFACE
                             | USB_DIR_IN,
                             0, /* value */
                             0, /* index */
-                            &room,
+                            room,
                             1,
                             2000);
        if (rc < 0) {
@@ -708,8 +729,8 @@ static int keyspan_pda_open(struct tty_struct *tty,
                goto error;
        }
        priv = usb_get_serial_port_data(port);
-       priv->tx_room = room;
-       priv->tx_throttled = room ? 0 : 1;
+       priv->tx_room = *room;
+       priv->tx_throttled = *room ? 0 : 1;
 
        /*Start reading from the device*/
        port->interrupt_in_urb->dev = serial->dev;
@@ -718,8 +739,8 @@ static int keyspan_pda_open(struct tty_struct *tty,
                dbg("%s - usb_submit_urb(read int) failed", __func__);
                goto error;
        }
-
 error:
+       kfree(room);
        return rc;
 }
 static void keyspan_pda_close(struct usb_serial_port *port)