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) {
                        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",
                }
        }
        if (flags & (1 << i)) {
+               if (len < 4) {
+                       goto error;
+               }
                os_descs_count = get_unaligned_le32(data);
                data += 4;
                len -= 4;
 
        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);