Skip to content

Commit e9b667a

Browse files
AlanSterngregkh
authored andcommitted
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. 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 2390710 commit e9b667a

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
@@ -1919,6 +1919,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
19191919
struct usbtmc_ctrlrequest request;
19201920
u8 *buffer = NULL;
19211921
int rv;
1922+
unsigned int is_in, pipe;
19221923
unsigned long res;
19231924

19241925
res = copy_from_user(&request, arg, sizeof(struct usbtmc_ctrlrequest));
@@ -1928,12 +1929,14 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
19281929
if (request.req.wLength > USBTMC_BUFSIZE)
19291930
return -EMSGSIZE;
19301931

1932+
is_in = request.req.bRequestType & USB_DIR_IN;
1933+
19311934
if (request.req.wLength) {
19321935
buffer = kmalloc(request.req.wLength, GFP_KERNEL);
19331936
if (!buffer)
19341937
return -ENOMEM;
19351938

1936-
if ((request.req.bRequestType & USB_DIR_IN) == 0) {
1939+
if (!is_in) {
19371940
/* Send control data to device */
19381941
res = copy_from_user(buffer, request.data,
19391942
request.req.wLength);
@@ -1944,8 +1947,12 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
19441947
}
19451948
}
19461949

1950+
if (is_in)
1951+
pipe = usb_rcvctrlpipe(data->usb_dev, 0);
1952+
else
1953+
pipe = usb_sndctrlpipe(data->usb_dev, 0);
19471954
rv = usb_control_msg(data->usb_dev,
1948-
usb_rcvctrlpipe(data->usb_dev, 0),
1955+
pipe,
19491956
request.req.bRequest,
19501957
request.req.bRequestType,
19511958
request.req.wValue,
@@ -1957,7 +1964,7 @@ static int usbtmc_ioctl_request(struct usbtmc_device_data *data,
19571964
goto exit;
19581965
}
19591966

1960-
if (rv && (request.req.bRequestType & USB_DIR_IN)) {
1967+
if (rv && is_in) {
19611968
/* Read control data from device */
19621969
res = copy_to_user(request.data, buffer, rv);
19631970
if (res)

0 commit comments

Comments
 (0)