diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-10-07 14:07:47 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-10-19 20:20:06 -0400 |
commit | ea04efee7635c9120d015dcdeeeb6988130cb67a (patch) | |
tree | 8f92d81e0afbc1d9106adf455e56365363ab6cf0 | |
parent | 20ac95d52a28f55472a54cc751eeec49fd445cb1 (diff) |
Input: ims-psu - check if CDC union descriptor is sane
Before trying to use CDC union descriptor, try to validate whether that it
is sane by checking that intf->altsetting->extra is big enough and that
descriptor bLength is not too big and not too small.
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r-- | drivers/input/misc/ims-pcu.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 6bf82ea8c918..ae473123583b 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c | |||
@@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf) | |||
1635 | return NULL; | 1635 | return NULL; |
1636 | } | 1636 | } |
1637 | 1637 | ||
1638 | while (buflen > 0) { | 1638 | while (buflen >= sizeof(*union_desc)) { |
1639 | union_desc = (struct usb_cdc_union_desc *)buf; | 1639 | union_desc = (struct usb_cdc_union_desc *)buf; |
1640 | 1640 | ||
1641 | if (union_desc->bLength > buflen) { | ||
1642 | dev_err(&intf->dev, "Too large descriptor\n"); | ||
1643 | return NULL; | ||
1644 | } | ||
1645 | |||
1641 | if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE && | 1646 | if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE && |
1642 | union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) { | 1647 | union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) { |
1643 | dev_dbg(&intf->dev, "Found union header\n"); | 1648 | dev_dbg(&intf->dev, "Found union header\n"); |
1644 | return union_desc; | 1649 | |
1650 | if (union_desc->bLength >= sizeof(*union_desc)) | ||
1651 | return union_desc; | ||
1652 | |||
1653 | dev_err(&intf->dev, | ||
1654 | "Union descriptor to short (%d vs %zd\n)", | ||
1655 | union_desc->bLength, sizeof(*union_desc)); | ||
1656 | return NULL; | ||
1645 | } | 1657 | } |
1646 | 1658 | ||
1647 | buflen -= union_desc->bLength; | 1659 | buflen -= union_desc->bLength; |