usb/mcs7830: Don't use buffers from stack for USB transfers
authorChristian Eggers <christian.eggers@kathrein.de>
Wed, 21 Jan 2009 20:56:24 +0000 (12:56 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 21 Jan 2009 20:56:24 +0000 (12:56 -0800)
mcs7830_set_reg() and mcs7830_get_reg() are called with buffers
from stack which must not be used directly for USB transfers.
This causes corruption of the stack particulary on non x86
architectures because DMA may be used for these transfers.

Signed-off-by: Christian Eggers <christian.eggers@kathrein.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/mcs7830.c

index 5385d66b306ebd284ac973e87a9209b4b7aa89ff..ced8f36ebd011617c0a42196b09549e59a634435 100644 (file)
@@ -94,10 +94,18 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data)
 {
        struct usb_device *xdev = dev->udev;
        int ret;
+       void *buffer;
+
+       buffer = kmalloc(size, GFP_NOIO);
+       if (buffer == NULL)
+               return -ENOMEM;
 
        ret = usb_control_msg(xdev, usb_rcvctrlpipe(xdev, 0), MCS7830_RD_BREQ,
-                             MCS7830_RD_BMREQ, 0x0000, index, data,
+                             MCS7830_RD_BMREQ, 0x0000, index, buffer,
                              size, MCS7830_CTRL_TIMEOUT);
+       memcpy(data, buffer, size);
+       kfree(buffer);
+
        return ret;
 }
 
@@ -105,10 +113,18 @@ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, void *data)
 {
        struct usb_device *xdev = dev->udev;
        int ret;
+       void *buffer;
+
+       buffer = kmalloc(size, GFP_NOIO);
+       if (buffer == NULL)
+               return -ENOMEM;
+
+       memcpy(buffer, data, size);
 
        ret = usb_control_msg(xdev, usb_sndctrlpipe(xdev, 0), MCS7830_WR_BREQ,
-                             MCS7830_WR_BMREQ, 0x0000, index, data,
+                             MCS7830_WR_BMREQ, 0x0000, index, buffer,
                              size, MCS7830_CTRL_TIMEOUT);
+       kfree(buffer);
        return ret;
 }