Message ID | 1532095146-19298-2-git-send-email-paolo.pisati@canonical.com |
---|---|
State | New |
Headers | show |
Series | USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor() | expand |
On 20.07.2018 15:59, Paolo Pisati wrote: > From: Alan Stern <stern@rowland.harvard.edu> > > Andrey used the syzkaller fuzzer to find an out-of-bounds memory > access in usb_get_bos_descriptor(). The code wasn't checking that the > next usb_dev_cap_header structure could fit into the remaining buffer > space. > > This patch fixes the error and also reduces the bNumDeviceCaps field > in the header to match the actual number of capabilities found, in > cases where there are fewer than expected. > > Reported-by: Andrey Konovalov <andreyknvl@google.com> > Signed-off-by: Alan Stern <stern@rowland.harvard.edu> > Tested-by: Andrey Konovalov <andreyknvl@google.com> > CC: <stable@vger.kernel.org> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > (cherry picked from commit 1c0edc3633b56000e18d82fc241e3995ca18a69e) > Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- Needs CVE-2017-16535 added. > drivers/usb/core/config.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c > index 755d82f..4cf67fc 100644 > --- a/drivers/usb/core/config.c > +++ b/drivers/usb/core/config.c > @@ -830,10 +830,12 @@ int usb_get_bos_descriptor(struct usb_device *dev) > for (i = 0; i < num; i++) { > buffer += length; > cap = (struct usb_dev_cap_header *)buffer; > - length = cap->bLength; > > - if (total_len < length) > + if (total_len < sizeof(*cap) || total_len < cap->bLength) { > + dev->bos->desc->bNumDeviceCaps = i; > break; > + } > + length = cap->bLength; > total_len -= length; > > if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { >
On 07/20/18 15:59, Paolo Pisati wrote: > From: Alan Stern <stern@rowland.harvard.edu> > > Andrey used the syzkaller fuzzer to find an out-of-bounds memory > access in usb_get_bos_descriptor(). The code wasn't checking that the > next usb_dev_cap_header structure could fit into the remaining buffer > space. > > This patch fixes the error and also reduces the bNumDeviceCaps field > in the header to match the actual number of capabilities found, in > cases where there are fewer than expected. > > Reported-by: Andrey Konovalov <andreyknvl@google.com> > Signed-off-by: Alan Stern <stern@rowland.harvard.edu> > Tested-by: Andrey Konovalov <andreyknvl@google.com> > CC: <stable@vger.kernel.org> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > (cherry picked from commit 1c0edc3633b56000e18d82fc241e3995ca18a69e) > Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com> Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> > --- > drivers/usb/core/config.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c > index 755d82f..4cf67fc 100644 > --- a/drivers/usb/core/config.c > +++ b/drivers/usb/core/config.c > @@ -830,10 +830,12 @@ int usb_get_bos_descriptor(struct usb_device *dev) > for (i = 0; i < num; i++) { > buffer += length; > cap = (struct usb_dev_cap_header *)buffer; > - length = cap->bLength; > > - if (total_len < length) > + if (total_len < sizeof(*cap) || total_len < cap->bLength) { > + dev->bos->desc->bNumDeviceCaps = i; > break; > + } > + length = cap->bLength; > total_len -= length; > > if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { >
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 755d82f..4cf67fc 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -830,10 +830,12 @@ int usb_get_bos_descriptor(struct usb_device *dev) for (i = 0; i < num; i++) { buffer += length; cap = (struct usb_dev_cap_header *)buffer; - length = cap->bLength; - if (total_len < length) + if (total_len < sizeof(*cap) || total_len < cap->bLength) { + dev->bos->desc->bNumDeviceCaps = i; break; + } + length = cap->bLength; total_len -= length; if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {