summaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorMalte Leip <malte@leip.net>2019-04-14 12:00:12 +0200
committerBen Hutchings <ben@decadent.org.uk>2019-08-13 12:39:16 +0100
commit2d399f685b07d23fdd4a8d3b1a1ea8c9f2dd9457 (patch)
treeba3f1533d2863aaf8f8d63541d5297afe62f289b /drivers/staging
parentef6b71388a795e0142c23b5c45266d41f8c4cd2b (diff)
downloadlinux-stable-2d399f685b07d23fdd4a8d3b1a1ea8c9f2dd9457.tar.gz
linux-stable-2d399f685b07d23fdd4a8d3b1a1ea8c9f2dd9457.tar.bz2
linux-stable-2d399f685b07d23fdd4a8d3b1a1ea8c9f2dd9457.zip
usb: usbip: fix isoc packet num validation in get_pipe
commit c409ca3be3c6ff3a1eeb303b191184e80d412862 upstream. 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> Acked-by: Shuah Khan <skhan@linuxfoundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> [bwh: Backported to 3.16: adjust filenames] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/usbip/stub_rx.c12
-rw-r--r--drivers/staging/usbip/usbip_common.h7
2 files changed, 10 insertions, 9 deletions
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 2ed1118d3d8b..7f10bc79a719 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -375,16 +375,10 @@ static int get_pipe(struct stub_device *sdev, struct usbip_header *pdu)
}
if (usb_endpoint_xfer_isoc(epd)) {
- /* validate packet size and number of packets */
- unsigned int maxp, packets, bytes;
-
- maxp = usb_endpoint_maxp(epd);
- maxp *= usb_endpoint_maxp_mult(epd);
- bytes = pdu->u.cmd_submit.transfer_buffer_length;
- packets = DIV_ROUND_UP(bytes, maxp);
-
+ /* validate number of packets */
if (pdu->u.cmd_submit.number_of_packets < 0 ||
- pdu->u.cmd_submit.number_of_packets > packets) {
+ pdu->u.cmd_submit.number_of_packets >
+ USBIP_MAX_ISO_PACKETS) {
dev_err(&sdev->udev->dev,
"CMD_SUBMIT: isoc invalid num packets %d\n",
pdu->u.cmd_submit.number_of_packets);
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index 58787c49fb68..8b358911563b 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -134,6 +134,13 @@ extern struct device_attribute dev_attr_usbip_debug;
#define USBIP_DIR_OUT 0x00
#define USBIP_DIR_IN 0x01
+/*
+ * Arbitrary limit for the maximum number of isochronous packets in an URB,
+ * compare for example the uhci_submit_isochronous function in
+ * drivers/usb/host/uhci-q.c
+ */
+#define USBIP_MAX_ISO_PACKETS 1024
+
/**
* struct usbip_header_basic - data pertinent to every request
* @command: the usbip request type