-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
RT-Thread Version
master (verified on commit 6a635e32d9f39ea015824927cee492620a05212f)
Hardware Type/Architectures
Any BSP enabling CherryUSB host video/UVC support
Develop Toolchain
GCC
Describe the bug
Affected Components
| Field | Detail |
|---|---|
| File 1 | components/drivers/usb/cherryusb/class/video/usbh_video.c |
| File 2 | components/drivers/usb/cherryusb/class/video/usbh_video.h |
| Path | USB Host UVC device enumeration / descriptor parsing |
Vulnerability Description
An out-of-bounds write/read vulnerability exists in the CherryUSB UVC host parser. Format and frame information are stored in fixed-size arrays:
struct usbh_video_format {
struct usbh_video_resolution frame[12];
uint8_t format_type;
uint8_t num_of_frames;
};
struct usbh_video {
...
uint8_t num_of_formats;
struct usbh_video_format format[3];
...
};During UVC descriptor parsing, the implementation directly trusts device-controlled descriptor fields such as bNumFormats, bFormatIndex, bNumFrameDescriptors, and bFrameIndex — with no bounds validation:
case VIDEO_VS_INPUT_HEADER_DESCRIPTOR_SUBTYPE:
video_class->num_of_formats = p[DESC_bNumFormats];
break;
case VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_SUBTYPE:
format_index = p[DESC_bFormatIndex];
num_of_frames = p[DESC_bNumFrameDescriptors];
video_class->format[format_index - 1].num_of_frames = num_of_frames; // ← no bounds check
video_class->format[format_index - 1].format_type = USBH_VIDEO_FORMAT_UNCOMPRESSED;
break;
case VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_SUBTYPE:
frame_index = p[DESC_bFrameIndex];
video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ...; // ← no bounds check
video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ...;
video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ...;
break;The missing validations are:
bNumFormats <= 3bFormatIndexis within1..3bNumFrameDescriptors <= 12bFrameIndexis within1..12
As a result:
- Malformed descriptors can trigger immediate out-of-bounds writes into
video_class->format[]orframe[]. - Corrupted counts are later reused in iteration loops, causing additional out-of-bounds reads:
for (uint8_t i = 0; i < video_class->num_of_formats; i++) { ... }
for (uint8_t j = 0; j < video_class->format[i].num_of_frames; j++) { ... }Trigger Condition
This parser runs automatically during UVC device enumeration:
static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
{
...
p = hport->raw_config_desc;
while (p[DESC_bLength]) {
...
/* parse video descriptors */
p += p[DESC_bLength];
}
usbh_video_list_info(video_class);
usbh_video_run(video_class);
}Note: The memory corruption occurs before
usbh_video_run(), so it is reachable even though the default weakusbh_video_run()implementation is empty. A malicious USB video/UVC device can trigger the bug immediately upon connection.
Proof of Concept
A PoC can be implemented with a programmable USB gadget/emulator such as Facedancer, LUNA, GreatFET, a Linux USB gadget setup, or any custom UVC firmware.
Trigger options:
- Set
bNumFormats = 4in the VideoStreaming input header descriptor (array capacity isformat[3]). - Provide a format descriptor with
bFormatIndex = 4. - Provide a frame descriptor with
bFrameIndex = 13. - Provide
bNumFrameDescriptors > 12and let later iteration walk beyondframe[12].
Expected result:
- Enumeration reaches
usbh_video_ctrl_connect(). - Malformed descriptor indexes are written directly into fixed arrays.
- Subsequent info-printing / selection logic may further read out-of-bounds memory.
- The target may crash or show corrupted state during or immediately after enumeration.
Impact Analysis
Upstream
- The vulnerable parser logic is present in current
master. - The path is automatically reachable during stock USB host enumeration when CherryUSB UVC/video host support is enabled.
- This is not a network-remote issue; it requires a malicious directly-connected USB video device.
Downstream
- Any downstream RT-Thread product enabling CherryUSB host UVC/video support is affected when connected to an untrusted USB camera or USB video gadget.
- Especially relevant for embedded hosts, kiosks, industrial panels, robotics devices, and edge gateways that accept third-party USB cameras.
- No extra debug command or local user interaction is required once the malicious device is plugged in.
Suggested Fix
Add strict bounds checks before every write into video_class->format[] or frame[]:
if (format_index == 0 || format_index > RT_ARRAY_SIZE(video_class->format)) {
return -USB_ERR_INVAL;
}Apply the same pattern for frame_index and stored counts. The later iteration logic should also use validated bounded counts instead of raw descriptor values.
Please let us know if you intend to request a CVE ID upon confirmation of this vulnerability.
Other additional context
No response