diff options
| author | Marissa Wall <marissaw@google.com> | 2017-11-16 14:32:40 -0800 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2018-05-16 13:09:07 +0200 |
| commit | 67d144f83962dd0094fe022d45e4913c611658b7 (patch) | |
| tree | f2177c3e189f768614cc199aea8057d2da163c3e /drivers/usb/class | |
| parent | c8ef0fa630d3ad30d75fc03f850ad5a0c345ef69 (diff) | |
BACKPORT: USB: core: harden cdc_parse_cdc_header
Andrey Konovalov reported a possible out-of-bounds problem for the
cdc_parse_cdc_header function. He writes:
It looks like cdc_parse_cdc_header() doesn't validate buflen
before accessing buffer[1], buffer[2] and so on. The only check
present is while (buflen > 0).
So fix this issue up by properly validating the buffer length matches
what the descriptor says it is.
(cherry picked from commit 2e1c42391ff2556387b3cb6308b24f6f65619feb)
(The original patch fixed the generic cdc_parser_cdc_header function.
That generic function did not exist in 3.10 but there are a couple
cdc parsers that suffer from the same underlying problem.)
Bug: 69052594
Change-Id: Ib251469de39e51b0ed7c1a1b88873270afccd90f
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Tested-by: Andrey Konovalov <andreyknvl@google.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Marissa Wall <marissaw@google.com>
Diffstat (limited to 'drivers/usb/class')
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 5 | ||||
| -rw-r--r-- | drivers/usb/class/cdc-wdm.c | 7 |
2 files changed, 11 insertions, 1 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d98a0249a..7468d454e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1338,6 +1338,11 @@ static int acm_probe(struct usb_interface *intf, } while (buflen > 0) { + if ((buflen < buffer[0]) || (buffer[0] < 3)) { + dev_err(&intf->dev, "invalid descriptor buffer length\n"); + break; + } + if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 07133d0c9..e5b24e519 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -841,7 +841,12 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!buffer) goto err; - while (buflen > 2) { + while (buflen > 0) { + if ((buflen < buffer[0]) || (buffer[0] < 3)) { + dev_err(&intf->dev, "invalid descriptor buffer length\n"); + goto err; + } + if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; |
