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

usb: usbip: fix isoc packet num validation in get_pipe

Change the validation of number_of_packets in get_pipe to compare the
number of packets to a fixed maximum number of packets allowed, set to
be 1024. This number was chosen due to it being used by other drivers as
well, for example drivers/usb/host/uhci-q.c

Background/reason:
The get_pipe function in stub_rx.c validates the number of packets in
isochronous mode and aborts with an error if that number is too large,
in order to prevent malicious input from possibly triggering large
memory allocations. This was previously done by checking whether
pdu->u.cmd_submit.number_of_packets is bigger than the number of packets
that would be needed for pdu->u.cmd_submit.transfer_buffer_length bytes
if all except possibly the last packet had maximum length, given by
usb_endpoint_maxp(epd) * usb_endpoint_maxp_mult(epd). This leads to an
error if URBs with packets shorter than the maximum possible length are
submitted, which is allowed according to
Documentation/driver-api/usb/URB.rst and occurs for example with the
snd-usb-audio driver.

Fixes: c6688ef9f297 ("usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input")
Signed-off-by: Malte Leip <malte@leip.net>
Cc: stable <stable@vger.kernel.org>
Acked-by: Shuah Khan <skhan@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Malte Leip and committed by
Greg Kroah-Hartman
c409ca3b c2b71462

+10 -9
+3 -9
drivers/usb/usbip/stub_rx.c
··· 361 361 } 362 362 363 363 if (usb_endpoint_xfer_isoc(epd)) { 364 - /* validate packet size and number of packets */ 365 - unsigned int maxp, packets, bytes; 366 - 367 - maxp = usb_endpoint_maxp(epd); 368 - maxp *= usb_endpoint_maxp_mult(epd); 369 - bytes = pdu->u.cmd_submit.transfer_buffer_length; 370 - packets = DIV_ROUND_UP(bytes, maxp); 371 - 364 + /* validate number of packets */ 372 365 if (pdu->u.cmd_submit.number_of_packets < 0 || 373 - pdu->u.cmd_submit.number_of_packets > packets) { 366 + pdu->u.cmd_submit.number_of_packets > 367 + USBIP_MAX_ISO_PACKETS) { 374 368 dev_err(&sdev->udev->dev, 375 369 "CMD_SUBMIT: isoc invalid num packets %d\n", 376 370 pdu->u.cmd_submit.number_of_packets);
+7
drivers/usb/usbip/usbip_common.h
··· 121 121 #define USBIP_DIR_OUT 0x00 122 122 #define USBIP_DIR_IN 0x01 123 123 124 + /* 125 + * Arbitrary limit for the maximum number of isochronous packets in an URB, 126 + * compare for example the uhci_submit_isochronous function in 127 + * drivers/usb/host/uhci-q.c 128 + */ 129 + #define USBIP_MAX_ISO_PACKETS 1024 130 + 124 131 /** 125 132 * struct usbip_header_basic - data pertinent to every request 126 133 * @command: the usbip request type