From: Sultan Khan <sultanqasim@gmail.com>
To: Szymon Heidrich <szymon.heidrich@gmail.com>
Cc: u-boot@lists.denx.de
Subject: Re: USB Device buffer overflow
Date: Wed, 16 Nov 2022 19:43:51 -0500 [thread overview]
Message-ID: <3910ECDA-0F38-4940-B64B-B014BC24C376@gmail.com> (raw)
In-Reply-To: <4bf3de35-6976-2380-df2f-41ab5c0c5f3b@gmail.com>
Hello Szymon,
Looks like a generalization of CVE-2022-2347 I found earlier. While both I and Venkatesh Yadav Abbarapu of AMD made patches for that CVE localized to DFU, given the presence of the same problematic pattern elsewhere, the bounds check aspect of that CVE fix would perhaps be better in a centralized location like what you did here.
Sultan
> On Nov 16, 2022, at 6:56 PM, Szymon Heidrich <szymon.heidrich@gmail.com> wrote:
> Hello,
>
> Similar to CVE-2021-39685 affecting the Linux kernel U-Boot is vulnerable to a buffer overflow
> present in the USB Gadget stack. Handling of a control transfer request with wLength larger than
> USB_BUFSIZ (4096) may result in a buffer overflow.
>
> The buffer for USB control endpoint is allocated in the composite_bind function implemented in
> drivers/usb/gadget/composite.c. The buffer size is set to USB_BUFSIZ (4096) bytes.
>
>> /* preallocate control response and buffer */
>> cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL);
>> if (!cdev->req)
>> goto fail;
>> cdev->req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, USB_BUFSIZ);
>> if (!cdev->req->buf)
>> goto fail;
>> cdev->req->complete = composite_setup_complete;
>> gadget->ep0->driver_data = cdev;
>
> In the composite_setup function data transfer phase is set up to the length of "value" bytes
> which in multiple cases may be controlled by an attacker (is set to wLength).
>
>> if (value >= 0) {
>> req->length = value;
>> req->zero = value < w_length;
>> value = usb_ep_queue(gadget->ep0, req, GFP_KERNEL);
>> if (value < 0) {
>> debug("ep_queue --> %d\n", value);
>> req->status = 0;
>> composite_setup_complete(gadget->ep0, req);
>> }
>> }
>
> In example the OS descriptor handler may be forced to set value to w_length.
>
>> } else {
>> /* "extended compatibility ID"s */
>> count = count_ext_compat(os_desc_cfg);
>> buf[8] = count;
>> count *= 24; /* 24 B/ext compat desc */
>> count += 16; /* header */
>> put_unaligned_le32(count, buf);
>> buf += 16;
>> fill_ext_compat(os_desc_cfg, buf);
>> value = w_length;
>> }
>
> Execution of this code path for wLength set to a value larger then USB_BUFSIZ will result
> in a buffer overflow. Since wLength is a double byte value it may have values up to 0xffff.
>
> Besides the common OS descriptor handler this issue may be exploited for some of the available
> gadgets e.g. f_dfu, f_sdp where "value" is derived from wLength.
>
> drivers/usb/gadget/f_dfu.c
>> static int handle_dnload(struct usb_gadget *gadget, u16 len)
>> {
>> struct usb_composite_dev *cdev = get_gadget_data(gadget);
>> struct usb_request *req = cdev->req;
>> struct f_dfu *f_dfu = req->context;
>>
>> if (len == 0)
>> f_dfu->dfu_state = DFU_STATE_dfuMANIFEST_SYNC;
>>
>> req->complete = dnload_request_complete;
>>
>> return len;
>> }
>
> drivers/usb/gadget/f_sdp.c
>> if (req_type == USB_TYPE_CLASS) {
>> int report = w_value & HID_REPORT_ID_MASK;
>>
>> /* HID (SDP) request */
>> switch (ctrl->bRequest) {
>> case HID_REQ_SET_REPORT:
>> switch (report) {
>> case 1:
>> value = SDP_COMMAND_LEN + 1;
>> req->complete = sdp_rx_command_complete;
>> sdp_func->ep_int_enable = false;
>> break;
>> case 2:
>> value = len;
>> req->complete = sdp_rx_data_complete;
>> sdp_func->state = SDP_STATE_RX_FILE_DATA_BUSY;
>> break;
>> }
>> }
>> }
>
> Please find attached a patch addressing this issue.
> Depending on request direction wLength larger than USB_BUFSIZ will result in either
> endpoint stall or value trim.
>
> Best regards,
> Szymon
> <0001-Prevent-buffer-overflow-on-USB-control-endpoint.patch>
next prev parent reply other threads:[~2022-11-17 0:44 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-16 20:00 USB Device buffer overflow Szymon Heidrich
2022-11-17 0:43 ` Sultan Khan [this message]
2022-11-17 0:56 ` Fabio Estevam
2022-11-17 9:48 ` [PATCH] Prevent buffer overflow on USB control endpoint Szymon Heidrich
2022-11-17 11:50 ` Fabio Estevam
2022-11-20 14:43 ` Marek Vasut
2022-11-20 15:29 ` Szymon Heidrich
2022-11-20 17:25 ` Marek Vasut
2022-11-20 17:42 ` Szymon Heidrich
2022-12-16 3:22 ` Marek Vasut
2022-12-19 18:52 ` Szymon Heidrich
2022-12-19 19:46 ` Marek Vasut
2022-11-28 9:21 ` Szymon Heidrich
2022-11-28 9:27 ` Marek Vasut
2022-12-12 9:55 ` Szymon Heidrich
2022-12-12 13:24 ` Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3910ECDA-0F38-4940-B64B-B014BC24C376@gmail.com \
--to=sultanqasim@gmail.com \
--cc=szymon.heidrich@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.