6ba2a2c
From 2ea39fc263c6a7589e15edb7d2d1c89fa569be53 Mon Sep 17 00:00:00 2001
6ba2a2c
From: Vladis Dronov <vdronov@redhat.com>
6ba2a2c
Date: Mon, 16 Nov 2015 15:55:11 -0200
6ba2a2c
Subject: [PATCH] usbvision: fix crash on detecting device with invalid
6ba2a2c
 configuration
6ba2a2c
6ba2a2c
The usbvision driver crashes when a specially crafted usb device with invalid
6ba2a2c
number of interfaces or endpoints is detected. This fix adds checks that the
6ba2a2c
device has proper configuration expected by the driver.
6ba2a2c
6ba2a2c
Reported-by: Ralf Spenneberg <ralf@spenneberg.net>
6ba2a2c
Signed-off-by: Vladis Dronov <vdronov@redhat.com>
6ba2a2c
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
6ba2a2c
---
6ba2a2c
 drivers/media/usb/usbvision/usbvision-video.c | 16 +++++++++++++++-
6ba2a2c
 1 file changed, 15 insertions(+), 1 deletion(-)
6ba2a2c
6ba2a2c
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
6ba2a2c
index b693206f66dd..d1dc1a198e3e 100644
6ba2a2c
--- a/drivers/media/usb/usbvision/usbvision-video.c
6ba2a2c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
6ba2a2c
@@ -1463,9 +1463,23 @@ static int usbvision_probe(struct usb_interface *intf,
6ba2a2c
 
6ba2a2c
 	if (usbvision_device_data[model].interface >= 0)
6ba2a2c
 		interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
6ba2a2c
-	else
6ba2a2c
+	else if (ifnum < dev->actconfig->desc.bNumInterfaces)
6ba2a2c
 		interface = &dev->actconfig->interface[ifnum]->altsetting[0];
6ba2a2c
+	else {
6ba2a2c
+		dev_err(&intf->dev, "interface %d is invalid, max is %d\n",
6ba2a2c
+		    ifnum, dev->actconfig->desc.bNumInterfaces - 1);
6ba2a2c
+		ret = -ENODEV;
6ba2a2c
+		goto err_usb;
6ba2a2c
+	}
6ba2a2c
+
6ba2a2c
+	if (interface->desc.bNumEndpoints < 2) {
6ba2a2c
+		dev_err(&intf->dev, "interface %d has %d endpoints, but must"
6ba2a2c
+		    " have minimum 2\n", ifnum, interface->desc.bNumEndpoints);
6ba2a2c
+		ret = -ENODEV;
6ba2a2c
+		goto err_usb;
6ba2a2c
+	}
6ba2a2c
 	endpoint = &interface->endpoint[1].desc;
6ba2a2c
+
6ba2a2c
 	if (!usb_endpoint_xfer_isoc(endpoint)) {
6ba2a2c
 		dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
6ba2a2c
 		    __func__, ifnum);
6ba2a2c
-- 
6ba2a2c
2.5.0
6ba2a2c