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>

+14 -2
+14 -2
drivers/input/misc/ims-pcu.c
··· 1635 1635 return NULL; 1636 1636 } 1637 1637 1638 - while (buflen > 0) { 1638 + while (buflen >= sizeof(*union_desc)) { 1639 1639 union_desc = (struct usb_cdc_union_desc *)buf; 1640 + 1641 + if (union_desc->bLength > buflen) { 1642 + dev_err(&intf->dev, "Too large descriptor\n"); 1643 + return NULL; 1644 + } 1640 1645 1641 1646 if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE && 1642 1647 union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) { 1643 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 1659 buflen -= union_desc->bLength;