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: Vincent Pelletier <plr.vincent@gmail.com> Acked-by: Felipe Balbi <felipe.balbi@linux.intel.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d9b2997e4a
commit
83e526f2a2
@ -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)
|
||||
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) {
|
||||
@ -2277,6 +2279,11 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
|
||||
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",
|
||||
@ -2363,6 +2370,9 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
|
||||
}
|
||||
}
|
||||
if (flags & (1 << i)) {
|
||||
if (len < 4) {
|
||||
goto error;
|
||||
}
|
||||
os_descs_count = get_unaligned_le32(data);
|
||||
data += 4;
|
||||
len -= 4;
|
||||
@ -2435,7 +2445,8 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user