Skip to content

Commit a5160af

Browse files
gopi487krishnagregkh
authored andcommitted
usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE
The previous commit removed the PAGE_SIZE limit on transfer length of raw_io buffer in order to avoid any problems with emulating USB devices whose full configuration descriptor exceeds PAGE_SIZE in length. However this also removes the upperbound on user supplied length, allowing very large values to be passed to the allocator. syzbot on fuzzing the transfer length with very large value (1.81GB) results in kmalloc() to fall back to the page allocator, which triggers a kernel warning as the page allocator cannot handle allocations more than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. Since there is no limit imposed on the size of buffer for both control and non control transfers, cap the raw_io transfer length to KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to prevent any warnings from the page allocator. Fixes: 37b9dd0 ("usb: raw-gadget: do not limit transfer length") Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ Signed-off-by: Gopi Krishna Menon <krishnagopi487@gmail.com> Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com> Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a75a5b1 commit a5160af

1 file changed

Lines changed: 3 additions & 0 deletions

File tree

drivers/usb/gadget/legacy/raw_gadget.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL");
4040

4141
static DEFINE_IDA(driver_id_numbers);
4242
#define DRIVER_DRIVER_NAME_LENGTH_MAX 32
43+
#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE
4344

4445
#define RAW_EVENT_QUEUE_SIZE 16
4546

@@ -667,6 +668,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,
667668
return ERR_PTR(-EINVAL);
668669
if (!usb_raw_io_flags_valid(io->flags))
669670
return ERR_PTR(-EINVAL);
671+
if (io->length > USB_RAW_IO_LENGTH_MAX)
672+
return ERR_PTR(-EINVAL);
670673
if (get_from_user)
671674
data = memdup_user(ptr + sizeof(*io), io->length);
672675
else {

0 commit comments

Comments
 (0)