Skip to content

Commit 83e526f

Browse files
vpelletiergregkh
authored andcommitted
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 <[email protected]> Acked-by: Felipe Balbi <[email protected]> Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d9b2997 commit 83e526f

File tree

1 file changed

+12
-1
lines changed
  • drivers/usb/gadget/function

1 file changed

+12
-1
lines changed

drivers/usb/gadget/function/f_fs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,8 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
22692269
if (len < sizeof(*d) || h->interface >= ffs->interfaces_count)
22702270
return -EINVAL;
22712271
length = le32_to_cpu(d->dwSize);
2272+
if (len < length)
2273+
return -EINVAL;
22722274
type = le32_to_cpu(d->dwPropertyDataType);
22732275
if (type < USB_EXT_PROP_UNICODE ||
22742276
type > USB_EXT_PROP_UNICODE_MULTI) {
@@ -2277,6 +2279,11 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
22772279
return -EINVAL;
22782280
}
22792281
pnl = le16_to_cpu(d->wPropertyNameLength);
2282+
if (length < 14 + pnl) {
2283+
pr_vdebug("invalid os descriptor length: %d pnl:%d (descriptor %d)\n",
2284+
length, pnl, type);
2285+
return -EINVAL;
2286+
}
22802287
pdl = le32_to_cpu(*(u32 *)((u8 *)data + 10 + pnl));
22812288
if (length != 14 + pnl + pdl) {
22822289
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,
23632370
}
23642371
}
23652372
if (flags & (1 << i)) {
2373+
if (len < 4) {
2374+
goto error;
2375+
}
23662376
os_descs_count = get_unaligned_le32(data);
23672377
data += 4;
23682378
len -= 4;
@@ -2435,7 +2445,8 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
24352445

24362446
ENTER();
24372447

2438-
if (unlikely(get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC ||
2448+
if (unlikely(len < 16 ||
2449+
get_unaligned_le32(data) != FUNCTIONFS_STRINGS_MAGIC ||
24392450
get_unaligned_le32(data + 4) != len))
24402451
goto error;
24412452
str_count = get_unaligned_le32(data + 8);

0 commit comments

Comments
 (0)