lkml.org 
[lkml]   [2017]   [Oct]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.13 067/160] USB: devio: Prevent integer overflow in proc_do_submiturb()
    Date
    4.13-stable review patch.  If anyone has any objections, please let me know.

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

    From: Dan Carpenter <dan.carpenter@oracle.com>

    commit 57999d1107c1e60c2ca7088f2ac0f819e2f554b3 upstream.

    There used to be an integer overflow check in proc_do_submiturb() but
    we removed it. It turns out that it's still required. The
    uurb->buffer_length variable is a signed integer and it's controlled by
    the user. It can lead to an integer overflow when we do:

    num_sgs = DIV_ROUND_UP(uurb->buffer_length, USB_SG_SIZE);

    If we strip away the macro then that line looks like this:

    num_sgs = (uurb->buffer_length + USB_SG_SIZE - 1) / USB_SG_SIZE;
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    It's the first addition which can overflow.

    Fixes: 1129d270cbfb ("USB: Increase usbfs transfer limit")
    Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
    Acked-by: Alan Stern <stern@rowland.harvard.edu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/core/devio.c | 5 +++++
    1 file changed, 5 insertions(+)

    --- a/drivers/usb/core/devio.c
    +++ b/drivers/usb/core/devio.c
    @@ -140,6 +140,9 @@ module_param(usbfs_memory_mb, uint, 0644
    MODULE_PARM_DESC(usbfs_memory_mb,
    "maximum MB allowed for usbfs buffers (0 = no limit)");

    +/* Hard limit, necessary to avoid arithmetic overflow */
    +#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000)
    +
    static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */

    /* Check whether it's okay to allocate more memory for a transfer */
    @@ -1460,6 +1463,8 @@ static int proc_do_submiturb(struct usb_
    USBDEVFS_URB_ZERO_PACKET |
    USBDEVFS_URB_NO_INTERRUPT))
    return -EINVAL;
    + if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX)
    + return -EINVAL;
    if (uurb->buffer_length > 0 && !uurb->buffer)
    return -EINVAL;
    if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&

    \
     
     \ /
      Last update: 2017-10-10 22:30    [W:9.217 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site