diff options
author | Ethan Zonca <e@ethanzonca.com> | 2017-02-24 11:27:36 -0500 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2017-03-03 07:00:07 -0500 |
commit | c919a3069c775c1c876bec55e00b2305d5125caa (patch) | |
tree | c557bde084088248845ff1fac0b0cc9e82f8130a /drivers | |
parent | 9f674e48c13dcbc31ac903433727837795b81efe (diff) |
can: gs_usb: Don't use stack memory for USB transfers
Fixes: 05ca5270005c can: gs_usb: add ethtool set_phys_id callback to locate physical device
The gs_usb driver is performing USB transfers using buffers allocated on
the stack. This causes the driver to not function with vmapped stacks.
Instead, allocate memory for the transfer buffers.
Signed-off-by: Ethan Zonca <e@ethanzonca.com>
Cc: linux-stable <stable@vger.kernel.org> # >= v4.8
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/can/usb/gs_usb.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 77e3cc06a30c..a0dabd4038ba 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c | |||
@@ -908,10 +908,14 @@ static int gs_usb_probe(struct usb_interface *intf, | |||
908 | struct gs_usb *dev; | 908 | struct gs_usb *dev; |
909 | int rc = -ENOMEM; | 909 | int rc = -ENOMEM; |
910 | unsigned int icount, i; | 910 | unsigned int icount, i; |
911 | struct gs_host_config hconf = { | 911 | struct gs_host_config *hconf; |
912 | .byte_order = 0x0000beef, | 912 | struct gs_device_config *dconf; |
913 | }; | 913 | |
914 | struct gs_device_config dconf; | 914 | hconf = kmalloc(sizeof(*hconf), GFP_KERNEL); |
915 | if (!hconf) | ||
916 | return -ENOMEM; | ||
917 | |||
918 | hconf->byte_order = 0x0000beef; | ||
915 | 919 | ||
916 | /* send host config */ | 920 | /* send host config */ |
917 | rc = usb_control_msg(interface_to_usbdev(intf), | 921 | rc = usb_control_msg(interface_to_usbdev(intf), |
@@ -920,16 +924,22 @@ static int gs_usb_probe(struct usb_interface *intf, | |||
920 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | 924 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
921 | 1, | 925 | 1, |
922 | intf->altsetting[0].desc.bInterfaceNumber, | 926 | intf->altsetting[0].desc.bInterfaceNumber, |
923 | &hconf, | 927 | hconf, |
924 | sizeof(hconf), | 928 | sizeof(*hconf), |
925 | 1000); | 929 | 1000); |
926 | 930 | ||
931 | kfree(hconf); | ||
932 | |||
927 | if (rc < 0) { | 933 | if (rc < 0) { |
928 | dev_err(&intf->dev, "Couldn't send data format (err=%d)\n", | 934 | dev_err(&intf->dev, "Couldn't send data format (err=%d)\n", |
929 | rc); | 935 | rc); |
930 | return rc; | 936 | return rc; |
931 | } | 937 | } |
932 | 938 | ||
939 | dconf = kmalloc(sizeof(*dconf), GFP_KERNEL); | ||
940 | if (!dconf) | ||
941 | return -ENOMEM; | ||
942 | |||
933 | /* read device config */ | 943 | /* read device config */ |
934 | rc = usb_control_msg(interface_to_usbdev(intf), | 944 | rc = usb_control_msg(interface_to_usbdev(intf), |
935 | usb_rcvctrlpipe(interface_to_usbdev(intf), 0), | 945 | usb_rcvctrlpipe(interface_to_usbdev(intf), 0), |
@@ -937,28 +947,33 @@ static int gs_usb_probe(struct usb_interface *intf, | |||
937 | USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | 947 | USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
938 | 1, | 948 | 1, |
939 | intf->altsetting[0].desc.bInterfaceNumber, | 949 | intf->altsetting[0].desc.bInterfaceNumber, |
940 | &dconf, | 950 | dconf, |
941 | sizeof(dconf), | 951 | sizeof(*dconf), |
942 | 1000); | 952 | 1000); |
943 | if (rc < 0) { | 953 | if (rc < 0) { |
944 | dev_err(&intf->dev, "Couldn't get device config: (err=%d)\n", | 954 | dev_err(&intf->dev, "Couldn't get device config: (err=%d)\n", |
945 | rc); | 955 | rc); |
956 | kfree(dconf); | ||
946 | return rc; | 957 | return rc; |
947 | } | 958 | } |
948 | 959 | ||
949 | icount = dconf.icount + 1; | 960 | icount = dconf->icount + 1; |
950 | dev_info(&intf->dev, "Configuring for %d interfaces\n", icount); | 961 | dev_info(&intf->dev, "Configuring for %d interfaces\n", icount); |
951 | 962 | ||
952 | if (icount > GS_MAX_INTF) { | 963 | if (icount > GS_MAX_INTF) { |
953 | dev_err(&intf->dev, | 964 | dev_err(&intf->dev, |
954 | "Driver cannot handle more that %d CAN interfaces\n", | 965 | "Driver cannot handle more that %d CAN interfaces\n", |
955 | GS_MAX_INTF); | 966 | GS_MAX_INTF); |
967 | kfree(dconf); | ||
956 | return -EINVAL; | 968 | return -EINVAL; |
957 | } | 969 | } |
958 | 970 | ||
959 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 971 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
960 | if (!dev) | 972 | if (!dev) { |
973 | kfree(dconf); | ||
961 | return -ENOMEM; | 974 | return -ENOMEM; |
975 | } | ||
976 | |||
962 | init_usb_anchor(&dev->rx_submitted); | 977 | init_usb_anchor(&dev->rx_submitted); |
963 | 978 | ||
964 | atomic_set(&dev->active_channels, 0); | 979 | atomic_set(&dev->active_channels, 0); |
@@ -967,7 +982,7 @@ static int gs_usb_probe(struct usb_interface *intf, | |||
967 | dev->udev = interface_to_usbdev(intf); | 982 | dev->udev = interface_to_usbdev(intf); |
968 | 983 | ||
969 | for (i = 0; i < icount; i++) { | 984 | for (i = 0; i < icount; i++) { |
970 | dev->canch[i] = gs_make_candev(i, intf, &dconf); | 985 | dev->canch[i] = gs_make_candev(i, intf, dconf); |
971 | if (IS_ERR_OR_NULL(dev->canch[i])) { | 986 | if (IS_ERR_OR_NULL(dev->canch[i])) { |
972 | /* save error code to return later */ | 987 | /* save error code to return later */ |
973 | rc = PTR_ERR(dev->canch[i]); | 988 | rc = PTR_ERR(dev->canch[i]); |
@@ -978,12 +993,15 @@ static int gs_usb_probe(struct usb_interface *intf, | |||
978 | gs_destroy_candev(dev->canch[i]); | 993 | gs_destroy_candev(dev->canch[i]); |
979 | 994 | ||
980 | usb_kill_anchored_urbs(&dev->rx_submitted); | 995 | usb_kill_anchored_urbs(&dev->rx_submitted); |
996 | kfree(dconf); | ||
981 | kfree(dev); | 997 | kfree(dev); |
982 | return rc; | 998 | return rc; |
983 | } | 999 | } |
984 | dev->canch[i]->parent = dev; | 1000 | dev->canch[i]->parent = dev; |
985 | } | 1001 | } |
986 | 1002 | ||
1003 | kfree(dconf); | ||
1004 | |||
987 | return 0; | 1005 | return 0; |
988 | } | 1006 | } |
989 | 1007 | ||