Commit 83e526f2 authored by Vincent Pelletier's avatar Vincent Pelletier Committed by Greg Kroah-Hartman

usb: gadget: f_fs: Assorted buffer overflow checks.

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: default avatarVincent Pelletier <plr.vincent@gmail.com>
Acked-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d9b2997e
...@@ -2269,6 +2269,8 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, ...@@ -2269,6 +2269,8 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
if (len < sizeof(*d) || h->interface >= ffs->interfaces_count) if (len < sizeof(*d) || h->interface >= ffs->interfaces_count)
return -EINVAL; return -EINVAL;
length = le32_to_cpu(d->dwSize); length = le32_to_cpu(d->dwSize);
if (len < length)
return -EINVAL;
type = le32_to_cpu(d->dwPropertyDataType); type = le32_to_cpu(d->dwPropertyDataType);
if (type < USB_EXT_PROP_UNICODE || if (type < USB_EXT_PROP_UNICODE ||
type > USB_EXT_PROP_UNICODE_MULTI) { type > USB_EXT_PROP_UNICODE_MULTI) {
...@@ -2277,6 +2279,11 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, ...@@ -2277,6 +2279,11 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
return -EINVAL; return -EINVAL;
} }
pnl = le16_to_cpu(d->wPropertyNameLength); 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)); pdl = le32_to_cpu(*(u32 *)((u8 *)data + 10 + pnl));
if (length != 14 + pnl + pdl) { if (length != 14 + pnl + pdl) {
pr_vdebug("invalid os descriptor length: %d pnl:%d pdl:%d (descriptor %d)\n", pr_vdebug("invalid os descriptor length: %d pnl:%d pdl:%d (descriptor %d)\n",
...@@ -2363,6 +2370,9 @@ static int __ffs_data_got_descs(struct ffs_data *ffs, ...@@ -2363,6 +2370,9 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
} }
} }
if (flags & (1 << i)) { if (flags & (1 << i)) {
if (len < 4) {
goto error;
}
os_descs_count = get_unaligned_le32(data); os_descs_count = get_unaligned_le32(data);
data += 4; data += 4;
len -= 4; len -= 4;
...@@ -2435,7 +2445,8 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, ...@@ -2435,7 +2445,8 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
ENTER(); 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)) get_unaligned_le32(data + 4) != len))
goto error; goto error;
str_count = get_unaligned_le32(data + 8); str_count = get_unaligned_le32(data + 8);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment