diff options
author | Christian Eggers <christian.eggers@kathrein.de> | 2009-01-21 12:56:24 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-21 12:56:24 -0800 |
commit | 6d317482944250228255bcbe97a95b7e7ad9a538 (patch) | |
tree | 699fd50b7ff360c0cb0c82cf1f28388d8996d461 | |
parent | 0b491eee46012772cbf029450d123e933c2e7940 (diff) |
usb/mcs7830: Don't use buffers from stack for USB transfers
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>
-rw-r--r-- | drivers/net/usb/mcs7830.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 5385d66b306e..ced8f36ebd01 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -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; } |