Skip to content

Commit 10a8053

Browse files
AlanSterngregkh
authored andcommitted
usb: usbtmc: Fix bug in pipe direction for control transfers
commit e9b667a upstream. 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. CC: <stable@vger.kernel.org> Reported-and-tested-by: syzbot+a48e3d1a875240cab5de@syzkaller.appspotmail.com Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Link: https://lore.kernel.org/r/YiEsYTPEE6lOCOA5@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 00bdd9b commit 10a8053

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

drivers/usb/class/usbtmc.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
18891889
struct usbtmc_ctrlrequest request;
18901890
u8 *buffer = NULL;
18911891
int rv;
1892+
unsigned int is_in, pipe;
18921893
unsigned long res;
18931894

18941895
res = copy_from_user(&request, arg, sizeof(struct usbtmc_ctrlrequest));
@@ -1898,12 +1899,14 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
18981899
if (request.req.wLength > USBTMC_BUFSIZE)
18991900
return -EMSGSIZE;
19001901

1902+
is_in = request.req.bRequestType & USB_DIR_IN;
1903+
19011904
if (request.req.wLength) {
19021905
buffer = kmalloc(request.req.wLength, GFP_KERNEL);
19031906
if (!buffer)
19041907
return -ENOMEM;
19051908

1906-
if ((request.req.bRequestType & USB_DIR_IN) == 0) {
1909+
if (!is_in) {
19071910
/* Send control data to device */
19081911
res = copy_from_user(buffer, request.data,
19091912
request.req.wLength);
@@ -1914,8 +1917,12 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
19141917
}
19151918
}
19161919

1920+
if (is_in)
1921+
pipe = usb_rcvctrlpipe(data->usb_dev, 0);
1922+
else
1923+
pipe = usb_sndctrlpipe(data->usb_dev, 0);
19171924
rv = usb_control_msg(data->usb_dev,
1918-
usb_rcvctrlpipe(data->usb_dev, 0),
1925+
pipe,
19191926
request.req.bRequest,
19201927
request.req.bRequestType,
19211928
request.req.wValue,
@@ -1927,7 +1934,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
19271934
goto exit;
19281935
}
19291936

1930-
if (rv && (request.req.bRequestType & USB_DIR_IN)) {
1937+
if (rv && is_in) {
19311938
/* Read control data from device */
19321939
res = copy_to_user(request.data, buffer, rv);
19331940
if (res)

0 commit comments

Comments
 (0)