|
@@ -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);
|