aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/class
diff options
context:
space:
mode:
authorMarissa Wall <marissaw@google.com>2017-11-16 14:32:40 -0800
committerMoyster <oysterized@gmail.com>2018-05-16 13:09:07 +0200
commit67d144f83962dd0094fe022d45e4913c611658b7 (patch)
treef2177c3e189f768614cc199aea8057d2da163c3e /drivers/usb/class
parentc8ef0fa630d3ad30d75fc03f850ad5a0c345ef69 (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.c5
-rw-r--r--drivers/usb/class/cdc-wdm.c7
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;