Re: [PATCH] usb: gadget: f_printer: prevent OOB write in GET_DEVICE_ID
Greg Kroah-Hartman <[email protected]>
| Newsgroups | gmane.linux.kernel,gmane.linux.usb.general |
|---|---|
| Message-ID | <2026082154-estrogen-spoon-0a9e@gregkh> |
On Fri, Aug 21, 2026 at 04:34:28PM +0800, Haofeng Li wrote: > printer_func_setup() services the Printer Class GET_DEVICE_ID request > by echoing the PnP string previously stored in the gadget's configfs > pnp_string attribute: > > value = strlen(*dev->pnp_string); > buf[0] = (value >> 8) & 0xFF; > buf[1] = value & 0xFF; > memcpy(buf + 2, *dev->pnp_string, value); > > The EP0 response buffer is exactly USB_COMP_EP0_BUFSIZ (4096) bytes, > allocated once by composite_dev_prepare(): > > cdev->req->buf = kzalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL); > > The two-byte length prefix plus the string body must therefore fit > into 4096 bytes. pnp_string is stored via kstrndup(page, len, > GFP_KERNEL) in f_printer_opts_pnp_string_store(); configfs passes at > most PAGE_SIZE - 1 (4095) bytes down to the store callback, so a > 4095-byte string combined with the 2-byte length field makes the > memcpy() write buf[2..4096], one byte past the end of the allocation. > > Attack chain (USB Printer gadget on the victim device): > > 1. pnp_string is set to a 4095-byte value through the gadget's > configfs attribute > (~/config/usb_gadget/<gadget>/functions/printer.usb0/pnp_string); > configfs accepts up to PAGE_SIZE - 1 bytes (fs/configfs/file.c). > 2. The printer function is enabled and the gadget is bound to its > UDC. An attacker in control of the connecting USB host sends a > Printer Class GET_DEVICE_ID request (bmRequestType=0xA1, > bRequest=0x00, wIndex pointing at the printer interface); the > usblp host driver also issues this request on enumeration. > 3. composite_setup() -> printer_func_setup() -> memcpy(buf + 2, > pnp_string, 4095) performs a 4097-byte write into the 4096-byte > EP0 response buffer, overflowing the heap object by one byte and > potentially corrupting adjacent slab objects or allocator > metadata (CWE-787). > > With KASAN enabled the overflow is reliably reported (this is > reproducible end to end with a configfs gadget + dummy_hcd): > > BUG: KASAN: slab-out-of-bounds in printer_func_setup+0x2ec/0x3c0 > Write of size 4095 at addr ffff88818e461002 > > Fix it at both ends: > > - clamp the string length to USB_COMP_EP0_BUFSIZ - 2 in > printer_func_setup() so the copy can never exceed the EP0 buffer, > and > - reject pnp_string values longer than USB_COMP_EP0_BUFSIZ - 2 in > f_printer_opts_pnp_string_store() so an oversized string is never > stored in the first place. > > Signed-off-by: Haofeng Li <[email protected]> > --- > drivers/usb/gadget/function/f_printer.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) Did you forget an Assisted-by: tag here?