diff options
author | Maksim Salau <maksim.salau@gmail.com> | 2017-04-25 15:49:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-25 09:44:29 -0400 |
commit | 810b7c5599540d4f17c4fbda2a5c03b5e0e39a11 (patch) | |
tree | 945f65ed2eb75d0d8c49534636d49aa76085c206 | |
parent | f5eea276d8de10a32e68721707ae8f2fdfaa0960 (diff) |
usb: misc: legousbtower: Fix buffers on stack
commit 942a48730faf149ccbf3e12ac718aee120bb3529 upstream.
Allocate buffers on HEAP instead of STACK for local structures
that are to be received using usb_control_msg().
Signed-off-by: Maksim Salau <maksim.salau@gmail.com>
Tested-by: Alfredo Rafael Vicente Boix <alviboi@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/misc/legousbtower.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index c8fbe7b739a0..9dd202ba1663 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -317,9 +317,16 @@ static int tower_open (struct inode *inode, struct file *file) | |||
317 | int subminor; | 317 | int subminor; |
318 | int retval = 0; | 318 | int retval = 0; |
319 | struct usb_interface *interface; | 319 | struct usb_interface *interface; |
320 | struct tower_reset_reply reset_reply; | 320 | struct tower_reset_reply *reset_reply; |
321 | int result; | 321 | int result; |
322 | 322 | ||
323 | reset_reply = kmalloc(sizeof(*reset_reply), GFP_KERNEL); | ||
324 | |||
325 | if (!reset_reply) { | ||
326 | retval = -ENOMEM; | ||
327 | goto exit; | ||
328 | } | ||
329 | |||
323 | nonseekable_open(inode, file); | 330 | nonseekable_open(inode, file); |
324 | subminor = iminor(inode); | 331 | subminor = iminor(inode); |
325 | 332 | ||
@@ -364,8 +371,8 @@ static int tower_open (struct inode *inode, struct file *file) | |||
364 | USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, | 371 | USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, |
365 | 0, | 372 | 0, |
366 | 0, | 373 | 0, |
367 | &reset_reply, | 374 | reset_reply, |
368 | sizeof(reset_reply), | 375 | sizeof(*reset_reply), |
369 | 1000); | 376 | 1000); |
370 | if (result < 0) { | 377 | if (result < 0) { |
371 | dev_err(&dev->udev->dev, | 378 | dev_err(&dev->udev->dev, |
@@ -406,6 +413,7 @@ unlock_exit: | |||
406 | mutex_unlock(&dev->lock); | 413 | mutex_unlock(&dev->lock); |
407 | 414 | ||
408 | exit: | 415 | exit: |
416 | kfree(reset_reply); | ||
409 | return retval; | 417 | return retval; |
410 | } | 418 | } |
411 | 419 | ||
@@ -808,7 +816,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device | |||
808 | struct lego_usb_tower *dev = NULL; | 816 | struct lego_usb_tower *dev = NULL; |
809 | struct usb_host_interface *iface_desc; | 817 | struct usb_host_interface *iface_desc; |
810 | struct usb_endpoint_descriptor* endpoint; | 818 | struct usb_endpoint_descriptor* endpoint; |
811 | struct tower_get_version_reply get_version_reply; | 819 | struct tower_get_version_reply *get_version_reply = NULL; |
812 | int i; | 820 | int i; |
813 | int retval = -ENOMEM; | 821 | int retval = -ENOMEM; |
814 | int result; | 822 | int result; |
@@ -886,6 +894,13 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device | |||
886 | dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; | 894 | dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; |
887 | dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; | 895 | dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; |
888 | 896 | ||
897 | get_version_reply = kmalloc(sizeof(*get_version_reply), GFP_KERNEL); | ||
898 | |||
899 | if (!get_version_reply) { | ||
900 | retval = -ENOMEM; | ||
901 | goto error; | ||
902 | } | ||
903 | |||
889 | /* get the firmware version and log it */ | 904 | /* get the firmware version and log it */ |
890 | result = usb_control_msg (udev, | 905 | result = usb_control_msg (udev, |
891 | usb_rcvctrlpipe(udev, 0), | 906 | usb_rcvctrlpipe(udev, 0), |
@@ -893,18 +908,19 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device | |||
893 | USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, | 908 | USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE, |
894 | 0, | 909 | 0, |
895 | 0, | 910 | 0, |
896 | &get_version_reply, | 911 | get_version_reply, |
897 | sizeof(get_version_reply), | 912 | sizeof(*get_version_reply), |
898 | 1000); | 913 | 1000); |
899 | if (result < 0) { | 914 | if (result < 0) { |
900 | dev_err(idev, "LEGO USB Tower get version control request failed\n"); | 915 | dev_err(idev, "LEGO USB Tower get version control request failed\n"); |
901 | retval = result; | 916 | retval = result; |
902 | goto error; | 917 | goto error; |
903 | } | 918 | } |
904 | dev_info(&interface->dev, "LEGO USB Tower firmware version is %d.%d " | 919 | dev_info(&interface->dev, |
905 | "build %d\n", get_version_reply.major, | 920 | "LEGO USB Tower firmware version is %d.%d build %d\n", |
906 | get_version_reply.minor, | 921 | get_version_reply->major, |
907 | le16_to_cpu(get_version_reply.build_no)); | 922 | get_version_reply->minor, |
923 | le16_to_cpu(get_version_reply->build_no)); | ||
908 | 924 | ||
909 | /* we can register the device now, as it is ready */ | 925 | /* we can register the device now, as it is ready */ |
910 | usb_set_intfdata (interface, dev); | 926 | usb_set_intfdata (interface, dev); |
@@ -928,6 +944,7 @@ exit: | |||
928 | return retval; | 944 | return retval; |
929 | 945 | ||
930 | error: | 946 | error: |
947 | kfree(get_version_reply); | ||
931 | tower_delete(dev); | 948 | tower_delete(dev); |
932 | return retval; | 949 | return retval; |
933 | } | 950 | } |