Explorar o código

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>
Christian Eggers %!s(int64=16) %!d(string=hai) anos
pai
achega
6d31748294
Modificáronse 1 ficheiros con 18 adicións e 2 borrados
  1. 18 2
      drivers/net/usb/mcs7830.c

+ 18 - 2
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;
 	struct usb_device *xdev = dev->udev;
 	int ret;
 	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,
 	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);
 			      size, MCS7830_CTRL_TIMEOUT);
+	memcpy(data, buffer, size);
+	kfree(buffer);
+
 	return ret;
 	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;
 	struct usb_device *xdev = dev->udev;
 	int ret;
 	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,
 	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);
 			      size, MCS7830_CTRL_TIMEOUT);
+	kfree(buffer);
 	return ret;
 	return ret;
 }
 }