lkml.org 
[lkml]   [2015]   [Mar]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.19 125/175] cdc-acm: add sanity checks
    Date
    3.19-stable review patch.  If anyone has any objections, please let me know.

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

    From: Oliver Neukum <oneukum@suse.de>

    commit 7e860a6e7aa62b337a61110430cd633db5b0d2dd upstream.

    Check the special CDC headers for a plausible minimum length.
    Another big operating systems ignores such garbage.

    Signed-off-by: Oliver Neukum <oneukum@suse.de>
    Reviewed-by: Adam Lee <adam8157@gmail.com>
    Tested-by: Adam Lee <adam8157@gmail.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/class/cdc-acm.c | 21 ++++++++++++++++-----
    1 file changed, 16 insertions(+), 5 deletions(-)

    --- a/drivers/usb/class/cdc-acm.c
    +++ b/drivers/usb/class/cdc-acm.c
    @@ -1091,6 +1091,7 @@ static int acm_probe(struct usb_interfac
    unsigned long quirks;
    int num_rx_buf;
    int i;
    + unsigned int elength = 0;
    int combined_interfaces = 0;
    struct device *tty_dev;
    int rv = -ENOMEM;
    @@ -1136,9 +1137,12 @@ static int acm_probe(struct usb_interfac
    dev_err(&intf->dev, "skipping garbage\n");
    goto next_desc;
    }
    + elength = buffer[0];

    switch (buffer[2]) {
    case USB_CDC_UNION_TYPE: /* we've found it */
    + if (elength < sizeof(struct usb_cdc_union_desc))
    + goto next_desc;
    if (union_header) {
    dev_err(&intf->dev, "More than one "
    "union descriptor, skipping ...\n");
    @@ -1147,29 +1151,36 @@ static int acm_probe(struct usb_interfac
    union_header = (struct usb_cdc_union_desc *)buffer;
    break;
    case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/
    + if (elength < sizeof(struct usb_cdc_country_functional_desc))
    + goto next_desc;
    cfd = (struct usb_cdc_country_functional_desc *)buffer;
    break;
    case USB_CDC_HEADER_TYPE: /* maybe check version */
    break; /* for now we ignore it */
    case USB_CDC_ACM_TYPE:
    + if (elength < 4)
    + goto next_desc;
    ac_management_function = buffer[3];
    break;
    case USB_CDC_CALL_MANAGEMENT_TYPE:
    + if (elength < 5)
    + goto next_desc;
    call_management_function = buffer[3];
    call_interface_num = buffer[4];
    break;
    default:
    - /* there are LOTS more CDC descriptors that
    + /*
    + * there are LOTS more CDC descriptors that
    * could legitimately be found here.
    */
    dev_dbg(&intf->dev, "Ignoring descriptor: "
    - "type %02x, length %d\n",
    - buffer[2], buffer[0]);
    + "type %02x, length %ud\n",
    + buffer[2], elength);
    break;
    }
    next_desc:
    - buflen -= buffer[0];
    - buffer += buffer[0];
    + buflen -= elength;
    + buffer += elength;
    }

    if (!union_header) {



    \
     
     \ /
      Last update: 2015-03-04 08:21    [W:4.606 / U:0.464 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site