patch "usb: usbtmc: Fix bug in pipe direction for control transfers" added to usb-linus
Subsystems (2)
This is a note to let you know that I've just added the patch titled
usb: usbtmc: Fix bug in pipe direction for control transfers
to my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From e9b667a82cdcfe21d590344447d65daed52b353b Mon Sep 17 00:00:00 2001
From: Alan Stern <[email protected]>
Date: Thu, 3 Mar 2022 16:00:17 -0500
Subject: usb: usbtmc: Fix bug in pipe direction for control transfers
The syzbot fuzzer reported a minor bug in the usbtmc driver:
usb 5-1: BOGUS control dir, pipe 80001e80 doesn't match bRequestType 0
WARNING: CPU: 0 PID: 3813 at drivers/usb/core/urb.c:412 usb_submit_urb+0x13a5/0x1970 drivers/usb/core/urb.c:410 Modules linked in: CPU: 0 PID: 3813 Comm: syz-executor122 Not tainted 5.17.0-rc5-syzkaller-00306-g2293be58d6a1 #0 ... Call Trace: <TASK> usb_start_wait_urb+0x113/0x530 drivers/usb/core/message.c:58 usb_internal_control_msg drivers/usb/core/message.c:102 [inline] usb_control_msg+0x2a5/0x4b0 drivers/usb/core/message.c:153 usbtmc_ioctl_request drivers/usb/class/usbtmc.c:1947 [inline]
The problem is that usbtmc_ioctl_request() uses usb_rcvctrlpipe() for all of its transfers, whether they are in or out. It's easy to fix.
--- drivers/usb/class/usbtmc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/usb/class/usbtmc.c +10 -3
@@ -1919,6 +1919,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,struct usbtmc_ctrlrequest request;u8 *buffer =NULL ;int rv; +unsigned int is_in, pipe;unsigned long res; res =copy_from_user (&request, arg,sizeof (struct usbtmc_ctrlrequest ));
@@ -1928,12 +1929,14 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,if (request.req.wLength >USBTMC_BUFSIZE )return -EMSGSIZE ; + is_in = request.req.bRequestType &USB_DIR_IN ; +if (request.req.wLength) { buffer =kmalloc (request.req.wLength,GFP_KERNEL );if (!buffer)return -ENOMEM ; -if ((request.req.bRequestType &USB_DIR_IN ) ==0 ) { +if (!is_in) {/* Send control data to device */ res =copy_from_user (buffer, request.data, request.req.wLength);
@@ -1944,8 +1947,12 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data, } } +if (is_in) + pipe =usb_rcvctrlpipe (data->usb_dev,0 ); +else + pipe =usb_sndctrlpipe (data->usb_dev,0 ); rv = usb_control_msg(data->usb_dev, - usb_rcvctrlpipe(data->usb_dev, 0), + pipe, request.req.bRequest, request.req.bRequestType, request.req.wValue,
@@ -1957,7 +1964,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data, goto exit; } -if (rv && (request.req.bRequestType &USB_DIR_IN )) { +if (rv && is_in) {/* Read control data from device */ res =copy_to_user (request.data, buffer, rv);if (res)
Signature · 1 line
2.35.1