lkml.org 
[lkml]   [2017]   [Feb]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 26/29] usb: gadget: f_fs: Assorted buffer overflow checks.
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

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

    From: Vincent Pelletier <plr.vincent@gmail.com>

    commit 83e526f2a2fa4b2e82b6bd3ddbb26b70acfa8947 upstream.

    OS descriptor head, when flagged as provided, is accessed without
    checking if it fits in provided buffer. Verify length before access.
    Also, there are other places where buffer length it checked
    after accessing offsets which are potentially past the end. Check
    buffer length before as well to fail cleanly.

    Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
    Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/gadget/function/f_fs.c | 13 ++++++++++++-
    1 file changed, 12 insertions(+), 1 deletion(-)

    --- a/drivers/usb/gadget/function/f_fs.c
    +++ b/drivers/usb/gadget/function/f_fs.c
    @@ -2079,6 +2079,8 @@ static int __ffs_data_do_os_desc(enum ff
    if (len < sizeof(*d) || h->interface >= ffs->interfaces_count)
    return -EINVAL;
    length = le32_to_cpu(d->dwSize);
    + if (len < length)
    + return -EINVAL;
    type = le32_to_cpu(d->dwPropertyDataType);
    if (type < USB_EXT_PROP_UNICODE ||
    type > USB_EXT_PROP_UNICODE_MULTI) {
    @@ -2087,6 +2089,11 @@ static int __ffs_data_do_os_desc(enum ff
    return -EINVAL;
    }
    pnl = le16_to_cpu(d->wPropertyNameLength);
    + if (length < 14 + pnl) {
    + pr_vdebug("invalid os descriptor length: %d pnl:%d (descriptor %d)\n",
    + length, pnl, type);
    + return -EINVAL;
    + }
    pdl = le32_to_cpu(*(u32 *)((u8 *)data + 10 + pnl));
    if (length != 14 + pnl + pdl) {
    pr_vdebug("invalid os descriptor length: %d pnl:%d pdl:%d (descriptor %d)\n",
    @@ -2171,6 +2178,9 @@ static int __ffs_data_got_descs(struct f
    }
    }
    if (flags & (1 << i)) {
    + if (len < 4) {
    + goto error;
    + }
    os_descs_count = get_unaligned_le32(data);
    data += 4;
    len -= 4;
    @@ -2243,7 +2253,8 @@ static int __ffs_data_got_strings(struct

    ENTER();

    - if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC ||
    + if (unlikely(len < 16 ||
    + get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC ||
    get_unaligned_le32(data + 4) != len))
    goto error;
    str_count = get_unaligned_le32(data + 8);

    \
     
     \ /
      Last update: 2017-02-07 13:49    [W:4.028 / U:0.372 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site