Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: misc: ehset: update to use the usb_control_msg_{send|recv}() API

The newer usb_control_msg_{send|recv}() API ensures that a short read
is treated as an error, data can be used off the stack, and raw usb
pipes need not be created in the calling functions.
For this reason, instances of usb_control_msg() have been replaced with
usb_control_msg_{recv|send}() appropriately.

Now, we also test for a short device descriptor (which USB core
should already have fetched if you get to probe this driver), but which
wasn't verified again here before.

Reviewed-by: Peter Chen <peter.chen@nxp.com>
Reviewed-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Anant Thazhemadam <anant.thazhemadam@gmail.com>
Link: https://lore.kernel.org/r/20210326223251.753952-2-anant.thazhemadam@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Anant Thazhemadam and committed by
Greg Kroah-Hartman
f5ffdd3b c21161e4

+32 -44
+32 -44
drivers/usb/misc/ehset.c
··· 24 24 int ret = -EINVAL; 25 25 struct usb_device *dev = interface_to_usbdev(intf); 26 26 struct usb_device *hub_udev = dev->parent; 27 - struct usb_device_descriptor *buf; 27 + struct usb_device_descriptor buf; 28 28 u8 portnum = dev->portnum; 29 29 u16 test_pid = le16_to_cpu(dev->descriptor.idProduct); 30 30 31 31 switch (test_pid) { 32 32 case TEST_SE0_NAK_PID: 33 - ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), 34 - USB_REQ_SET_FEATURE, USB_RT_PORT, 35 - USB_PORT_FEAT_TEST, 36 - (USB_TEST_SE0_NAK << 8) | portnum, 37 - NULL, 0, 1000); 33 + ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, 34 + USB_RT_PORT, USB_PORT_FEAT_TEST, 35 + (USB_TEST_SE0_NAK << 8) | portnum, 36 + NULL, 0, 1000, GFP_KERNEL); 38 37 break; 39 38 case TEST_J_PID: 40 - ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), 41 - USB_REQ_SET_FEATURE, USB_RT_PORT, 42 - USB_PORT_FEAT_TEST, 43 - (USB_TEST_J << 8) | portnum, 44 - NULL, 0, 1000); 39 + ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, 40 + USB_RT_PORT, USB_PORT_FEAT_TEST, 41 + (USB_TEST_J << 8) | portnum, NULL, 0, 42 + 1000, GFP_KERNEL); 45 43 break; 46 44 case TEST_K_PID: 47 - ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), 48 - USB_REQ_SET_FEATURE, USB_RT_PORT, 49 - USB_PORT_FEAT_TEST, 50 - (USB_TEST_K << 8) | portnum, 51 - NULL, 0, 1000); 45 + ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, 46 + USB_RT_PORT, USB_PORT_FEAT_TEST, 47 + (USB_TEST_K << 8) | portnum, NULL, 0, 48 + 1000, GFP_KERNEL); 52 49 break; 53 50 case TEST_PACKET_PID: 54 - ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), 55 - USB_REQ_SET_FEATURE, USB_RT_PORT, 56 - USB_PORT_FEAT_TEST, 57 - (USB_TEST_PACKET << 8) | portnum, 58 - NULL, 0, 1000); 51 + ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, 52 + USB_RT_PORT, USB_PORT_FEAT_TEST, 53 + (USB_TEST_PACKET << 8) | portnum, 54 + NULL, 0, 1000, GFP_KERNEL); 59 55 break; 60 56 case TEST_HS_HOST_PORT_SUSPEND_RESUME: 61 57 /* Test: wait for 15secs -> suspend -> 15secs delay -> resume */ 62 58 msleep(15 * 1000); 63 - ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), 64 - USB_REQ_SET_FEATURE, USB_RT_PORT, 65 - USB_PORT_FEAT_SUSPEND, portnum, 66 - NULL, 0, 1000); 59 + ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, 60 + USB_RT_PORT, USB_PORT_FEAT_SUSPEND, 61 + portnum, NULL, 0, 1000, GFP_KERNEL); 67 62 if (ret < 0) 68 63 break; 69 64 70 65 msleep(15 * 1000); 71 - ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), 72 - USB_REQ_CLEAR_FEATURE, USB_RT_PORT, 73 - USB_PORT_FEAT_SUSPEND, portnum, 74 - NULL, 0, 1000); 66 + ret = usb_control_msg_send(hub_udev, 0, USB_REQ_CLEAR_FEATURE, 67 + USB_RT_PORT, USB_PORT_FEAT_SUSPEND, 68 + portnum, NULL, 0, 1000, GFP_KERNEL); 75 69 break; 76 70 case TEST_SINGLE_STEP_GET_DEV_DESC: 77 71 /* Test: wait for 15secs -> GetDescriptor request */ 78 72 msleep(15 * 1000); 79 - buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL); 80 - if (!buf) 81 - return -ENOMEM; 82 73 83 - ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 84 - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 85 - USB_DT_DEVICE << 8, 0, 86 - buf, USB_DT_DEVICE_SIZE, 87 - USB_CTRL_GET_TIMEOUT); 88 - kfree(buf); 74 + ret = usb_control_msg_recv(dev, 0, USB_REQ_GET_DESCRIPTOR, 75 + USB_DIR_IN, USB_DT_DEVICE << 8, 0, 76 + &buf, USB_DT_DEVICE_SIZE, 77 + USB_CTRL_GET_TIMEOUT, GFP_KERNEL); 89 78 break; 90 79 case TEST_SINGLE_STEP_SET_FEATURE: 91 80 /* ··· 89 100 break; 90 101 } 91 102 92 - ret = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0), 93 - USB_REQ_SET_FEATURE, USB_RT_PORT, 94 - USB_PORT_FEAT_TEST, 95 - (6 << 8) | portnum, 96 - NULL, 0, 60 * 1000); 103 + ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, 104 + USB_RT_PORT, USB_PORT_FEAT_TEST, 105 + (6 << 8) | portnum, NULL, 0, 106 + 60 * 1000, GFP_KERNEL); 97 107 98 108 break; 99 109 default: ··· 100 112 __func__, test_pid); 101 113 } 102 114 103 - return (ret < 0) ? ret : 0; 115 + return ret; 104 116 } 105 117 106 118 static void ehset_disconnect(struct usb_interface *intf)