mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
110 lines
3.2 KiB
Diff
110 lines
3.2 KiB
Diff
|
From 950336ba3e4a1ffd2ca60d29f6ef386dd2c7351d Mon Sep 17 00:00:00 2001
|
||
|
From: Vladis Dronov <vdronov@redhat.com>
|
||
|
Date: Wed, 23 Mar 2016 11:53:46 -0700
|
||
|
Subject: Input: ati_remote2 - fix crashes on detecting device with invalid
|
||
|
descriptor
|
||
|
|
||
|
The ati_remote2 driver expects at least two interfaces with one
|
||
|
endpoint each. If given malicious descriptor that specify one
|
||
|
interface or no endpoints, it will crash in the probe function.
|
||
|
Ensure there is at least two interfaces and one endpoint for each
|
||
|
interface before using it.
|
||
|
|
||
|
The full disclosure: http://seclists.org/bugtraq/2016/Mar/90
|
||
|
|
||
|
Reported-by: Ralf Spenneberg <ralf@spenneberg.net>
|
||
|
Signed-off-by: Vladis Dronov <vdronov@redhat.com>
|
||
|
Cc: stable@vger.kernel.org
|
||
|
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||
|
---
|
||
|
drivers/input/misc/ati_remote2.c | 36 ++++++++++++++++++++++++++++++------
|
||
|
1 file changed, 30 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
|
||
|
index cfd58e8..1c5914c 100644
|
||
|
--- a/drivers/input/misc/ati_remote2.c
|
||
|
+++ b/drivers/input/misc/ati_remote2.c
|
||
|
@@ -817,26 +817,49 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
|
||
|
|
||
|
ar2->udev = udev;
|
||
|
|
||
|
+ /* Sanity check, first interface must have an endpoint */
|
||
|
+ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) {
|
||
|
+ dev_err(&interface->dev,
|
||
|
+ "%s(): interface 0 must have an endpoint\n", __func__);
|
||
|
+ r = -ENODEV;
|
||
|
+ goto fail1;
|
||
|
+ }
|
||
|
ar2->intf[0] = interface;
|
||
|
ar2->ep[0] = &alt->endpoint[0].desc;
|
||
|
|
||
|
+ /* Sanity check, the device must have two interfaces */
|
||
|
ar2->intf[1] = usb_ifnum_to_if(udev, 1);
|
||
|
+ if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) {
|
||
|
+ dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n",
|
||
|
+ __func__, udev->actconfig->desc.bNumInterfaces);
|
||
|
+ r = -ENODEV;
|
||
|
+ goto fail1;
|
||
|
+ }
|
||
|
+
|
||
|
r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
|
||
|
if (r)
|
||
|
goto fail1;
|
||
|
+
|
||
|
+ /* Sanity check, second interface must have an endpoint */
|
||
|
alt = ar2->intf[1]->cur_altsetting;
|
||
|
+ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) {
|
||
|
+ dev_err(&interface->dev,
|
||
|
+ "%s(): interface 1 must have an endpoint\n", __func__);
|
||
|
+ r = -ENODEV;
|
||
|
+ goto fail2;
|
||
|
+ }
|
||
|
ar2->ep[1] = &alt->endpoint[0].desc;
|
||
|
|
||
|
r = ati_remote2_urb_init(ar2);
|
||
|
if (r)
|
||
|
- goto fail2;
|
||
|
+ goto fail3;
|
||
|
|
||
|
ar2->channel_mask = channel_mask;
|
||
|
ar2->mode_mask = mode_mask;
|
||
|
|
||
|
r = ati_remote2_setup(ar2, ar2->channel_mask);
|
||
|
if (r)
|
||
|
- goto fail2;
|
||
|
+ goto fail3;
|
||
|
|
||
|
usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
|
||
|
strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
|
||
|
@@ -845,11 +868,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
|
||
|
|
||
|
r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group);
|
||
|
if (r)
|
||
|
- goto fail2;
|
||
|
+ goto fail3;
|
||
|
|
||
|
r = ati_remote2_input_init(ar2);
|
||
|
if (r)
|
||
|
- goto fail3;
|
||
|
+ goto fail4;
|
||
|
|
||
|
usb_set_intfdata(interface, ar2);
|
||
|
|
||
|
@@ -857,10 +880,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
- fail3:
|
||
|
+ fail4:
|
||
|
sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group);
|
||
|
- fail2:
|
||
|
+ fail3:
|
||
|
ati_remote2_urb_cleanup(ar2);
|
||
|
+ fail2:
|
||
|
usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
|
||
|
fail1:
|
||
|
kfree(ar2);
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|