lkml.org 
[lkml]   [2019]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 266/305] USB: check usb_get_extra_descriptor for proper size
    3.16.63-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Mathias Payer <mathias.payer@nebelwelt.net>

    commit 704620afc70cf47abb9d6a1a57f3825d2bca49cf upstream.

    When reading an extra descriptor, we need to properly check the minimum
    and maximum size allowed, to prevent from invalid data being sent by a
    device.

    Reported-by: Hui Peng <benquike@gmail.com>
    Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
    Co-developed-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Hui Peng <benquike@gmail.com>
    Signed-off-by: Mathias Payer <mathias.payer@nebelwelt.net>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    [bwh: Backported to 3.16: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/usb/core/hub.c | 2 +-
    drivers/usb/core/usb.c | 6 +++---
    drivers/usb/host/hwa-hc.c | 2 +-
    include/linux/usb.h | 4 ++--
    4 files changed, 7 insertions(+), 7 deletions(-)

    --- a/drivers/usb/core/hub.c
    +++ b/drivers/usb/core/hub.c
    @@ -2211,7 +2211,7 @@ static int usb_enumerate_device_otg(stru
    /* descriptor may appear anywhere in config */
    if (__usb_get_extra_descriptor (udev->rawdescriptors[0],
    le16_to_cpu(udev->config[0].desc.wTotalLength),
    - USB_DT_OTG, (void **) &desc) == 0) {
    + USB_DT_OTG, (void **) &desc, sizeof(*desc)) == 0) {
    if (desc->bmAttributes & USB_OTG_HNP) {
    unsigned port1 = udev->portnum;

    --- a/drivers/usb/core/usb.c
    +++ b/drivers/usb/core/usb.c
    @@ -663,14 +663,14 @@ EXPORT_SYMBOL_GPL(usb_get_current_frame_
    */

    int __usb_get_extra_descriptor(char *buffer, unsigned size,
    - unsigned char type, void **ptr)
    + unsigned char type, void **ptr, size_t minsize)
    {
    struct usb_descriptor_header *header;

    while (size >= sizeof(struct usb_descriptor_header)) {
    header = (struct usb_descriptor_header *)buffer;

    - if (header->bLength < 2) {
    + if (header->bLength < 2 || header->bLength > size) {
    printk(KERN_ERR
    "%s: bogus descriptor, type %d length %d\n",
    usbcore_name,
    @@ -679,7 +679,7 @@ int __usb_get_extra_descriptor(char *buf
    return -1;
    }

    - if (header->bDescriptorType == type) {
    + if (header->bDescriptorType == type && header->bLength >= minsize) {
    *ptr = header;
    return 0;
    }
    --- a/drivers/usb/host/hwa-hc.c
    +++ b/drivers/usb/host/hwa-hc.c
    @@ -654,7 +654,7 @@ static int hwahc_security_create(struct
    top = itr + itr_size;
    result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
    le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
    - USB_DT_SECURITY, (void **) &secd);
    + USB_DT_SECURITY, (void **) &secd, sizeof(*secd));
    if (result == -1) {
    dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
    return 0;
    --- a/include/linux/usb.h
    +++ b/include/linux/usb.h
    @@ -334,11 +334,11 @@ struct usb_host_bos {
    };

    int __usb_get_extra_descriptor(char *buffer, unsigned size,
    - unsigned char type, void **ptr);
    + unsigned char type, void **ptr, size_t min);
    #define usb_get_extra_descriptor(ifpoint, type, ptr) \
    __usb_get_extra_descriptor((ifpoint)->extra, \
    (ifpoint)->extralen, \
    - type, (void **)ptr)
    + type, (void **)ptr, sizeof(**(ptr)))

    /* ----------------------------------------------------------------------- */

    \
     
     \ /
      Last update: 2019-02-03 14:55    [W:4.074 / U:0.888 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site