summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>2013-08-21 01:43:19 -0700
committerDavid S. Miller <davem@davemloft.net>2013-08-21 20:47:59 -0700
commite75dc677ff8d06ffa61bef6fee436227ae5440c6 (patch)
tree15c3d8e0ae078ae6f9b3f008c9eb3a5a9c7fc29c /drivers
parent35e57e1b49a351aa804dab6010cd46ae6112a541 (diff)
downloadlinux-e75dc677ff8d06ffa61bef6fee436227ae5440c6.tar.gz
hso: Fix stack corruption on some architectures
As Sergei Shtylyov explained in the #mipslinux IRC channel:
[Mon 2013-08-19 12:28:21 PM PDT] <headless> guys, are you sure it's not "DMA off stack" case?
[Mon 2013-08-19 12:28:35 PM PDT] <headless> it's a known stack corruptor on non-coherent arches
[Mon 2013-08-19 12:31:48 PM PDT] <DonkeyHotei> headless: for usb/ehci?
[Mon 2013-08-19 12:34:11 PM PDT] <DonkeyHotei> headless: explain
[Mon 2013-08-19 12:35:38 PM PDT] <headless> usb_control_msg() (or other such func) should not use buffer on stack. DMA from/to stack is prohibited
[Mon 2013-08-19 12:35:58 PM PDT] <headless> and EHCI uses DMA on control xfers (as well as all the others)

Signed-off-by: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/usb/hso.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 5fb36ed23c1f..86292e6aaf49 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -2816,13 +2816,16 @@ exit:
 static int hso_get_config_data(struct usb_interface *interface)
 {
 	struct usb_device *usbdev = interface_to_usbdev(interface);
-	u8 config_data[17];
+	u8 *config_data = kmalloc(17, GFP_KERNEL);
 	u32 if_num = interface->altsetting->desc.bInterfaceNumber;
 	s32 result;
 
+	if (!config_data)
+		return -ENOMEM;
 	if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
 			    0x86, 0xC0, 0, 0, config_data, 17,
 			    USB_CTRL_SET_TIMEOUT) != 0x11) {
+		kfree(config_data);
 		return -EIO;
 	}
 
@@ -2873,6 +2876,7 @@ static int hso_get_config_data(struct usb_interface *interface)
 	if (config_data[16] & 0x1)
 		result |= HSO_INFO_CRC_BUG;
 
+	kfree(config_data);
 	return result;
 }