summaryrefslogtreecommitdiff
path: root/class/video
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2026-10-22 12:41:45 +0800
committersakumisu <[email protected]>2026-10-23 18:29:36 +0800
commit2397226c48fea88bdb742651f9280f47eef3197a (patch)
tree333db0904d5d3591a93a79f564c4a859f9957ae0 /class/video
parent26b0feb09bb58ebb7a3161b5605f8e186b96db1f (diff)
fix(security): check array overflowdev
Signed-off-by: sakumisu <[email protected]>
Diffstat (limited to 'class/video')
-rw-r--r--class/video/usbh_video.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/class/video/usbh_video.c b/class/video/usbh_video.c
index 8e782e20..3e16d6d9 100644
--- a/class/video/usbh_video.c
+++ b/class/video/usbh_video.c
@@ -66,6 +66,11 @@ int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf
if (!video_class || !video_class->hport) {
return -USB_ERR_INVAL;
}
+
+ if (len > sizeof(g_video_buf)) {
+ return -USB_ERR_INVAL;
+ }
+
setup = video_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -77,7 +82,7 @@ int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf
retry = 0;
while (1) {
ret = usbh_control_transfer(video_class->hport, setup, g_video_buf);
- if (ret >= len) {
+ if (ret == len) {
break;
}
retry++;
@@ -102,6 +107,11 @@ int usbh_video_set(struct usbh_video *video_class, uint8_t request, uint8_t intf
if (!video_class || !video_class->hport) {
return -USB_ERR_INVAL;
}
+
+ if (len > sizeof(g_video_buf)) {
+ return -USB_ERR_INVAL;
+ }
+
setup = video_class->hport->setup;
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
@@ -367,7 +377,9 @@ void usbh_video_list_info(struct usbh_video *video_class)
USB_LOG_RAW(" wWidth: %d, wHeight: %d, fps: %d\r\n",
video_class->format[i].frame[j].wWidth,
video_class->format[i].frame[j].wHeight,
- (1000 / (video_class->format[i].frame[j].dwDefaultFrameInterval / 10000)));
+ (video_class->format[i].frame[j].dwDefaultFrameInterval ?
+ 10000000U / video_class->format[i].frame[j].dwDefaultFrameInterval :
+ 0U));
}
}
@@ -405,7 +417,7 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
}
p = hport->raw_config_desc;
- while (p[DESC_bLength]) {
+ while (desc_len < hport->config.config_desc.wTotalLength) {
switch (p[DESC_bDescriptorType]) {
case USB_DESCRIPTOR_TYPE_INTERFACE:
cur_iface = p[INTF_DESC_bInterfaceNumber];
@@ -418,6 +430,9 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
if (cur_iface == video_class->ctrl_intf) {
switch (p[DESC_bDescriptorSubType]) {
case VIDEO_VC_HEADER_DESCRIPTOR_SUBTYPE:
+ if (p[DESC_bLength] < 5) {
+ return -USB_ERR_INVAL;
+ }
video_class->bcdVDC = ((uint16_t)p[4] << 8) | (uint16_t)p[3];
break;
case VIDEO_VC_INPUT_TERMINAL_DESCRIPTOR_SUBTYPE:
@@ -433,11 +448,22 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
} else if (cur_iface == video_class->data_intf) {
switch (p[DESC_bDescriptorSubType]) {
case VIDEO_VS_INPUT_HEADER_DESCRIPTOR_SUBTYPE:
+ if (p[DESC_bLength] < 4 || p[DESC_bNumFormats] == 0 ||
+ p[DESC_bNumFormats] > CONFIG_USBHOST_VIDEO_MAX_FORMATS) {
+ return -USB_ERR_INVAL;
+ }
video_class->num_of_formats = p[DESC_bNumFormats];
break;
case VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_SUBTYPE:
+ if (p[DESC_bLength] < 5) {
+ return -USB_ERR_INVAL;
+ }
format_index = p[DESC_bFormatIndex];
num_of_frames = p[DESC_bNumFrameDescriptors];
+ if (format_index == 0 || format_index > CONFIG_USBHOST_VIDEO_MAX_FORMATS ||
+ num_of_frames == 0 || num_of_frames > CONFIG_USBHOST_VIDEO_MAX_FRAMES) {
+ return -USB_ERR_INVAL;
+ }
USB_ASSERT(format_index != 0);
USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS);
@@ -446,8 +472,15 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
video_class->format[format_index - 1].format_type = USBH_VIDEO_FORMAT_UNCOMPRESSED;
break;
case VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_SUBTYPE:
+ if (p[DESC_bLength] < 5) {
+ return -USB_ERR_INVAL;
+ }
format_index = p[DESC_bFormatIndex];
num_of_frames = p[DESC_bNumFrameDescriptors];
+ if (format_index == 0 || format_index > CONFIG_USBHOST_VIDEO_MAX_FORMATS ||
+ num_of_frames == 0 || num_of_frames > CONFIG_USBHOST_VIDEO_MAX_FRAMES) {
+ return -USB_ERR_INVAL;
+ }
USB_ASSERT(format_index != 0);
USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS);
@@ -456,7 +489,16 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
video_class->format[format_index - 1].format_type = USBH_VIDEO_FORMAT_MJPEG;
break;
case VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_SUBTYPE:
+ if (p[DESC_bLength] < sizeof(struct video_cs_if_vs_frame_uncompressed_descriptor)) {
+ return -USB_ERR_INVAL;
+ }
frame_index = p[DESC_bFrameIndex];
+ if (format_index == 0 || format_index > CONFIG_USBHOST_VIDEO_MAX_FORMATS ||
+ frame_index == 0 || frame_index > CONFIG_USBHOST_VIDEO_MAX_FRAMES ||
+ frame_index > video_class->format[format_index - 1].num_of_frames ||
+ ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->dwDefaultFrameInterval == 0) {
+ return -USB_ERR_INVAL;
+ }
USB_ASSERT(format_index != 0);
USB_ASSERT(frame_index != 0);
@@ -468,7 +510,16 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->dwDefaultFrameInterval;
break;
case VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE:
+ if (p[DESC_bLength] < sizeof(struct video_cs_if_vs_frame_mjpeg_descriptor)) {
+ return -USB_ERR_INVAL;
+ }
frame_index = p[DESC_bFrameIndex];
+ if (format_index == 0 || format_index > CONFIG_USBHOST_VIDEO_MAX_FORMATS ||
+ frame_index == 0 || frame_index > CONFIG_USBHOST_VIDEO_MAX_FRAMES ||
+ frame_index > video_class->format[format_index - 1].num_of_frames ||
+ ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->dwDefaultFrameInterval == 0) {
+ return -USB_ERR_INVAL;
+ }
USB_ASSERT(format_index != 0);
USB_ASSERT(frame_index != 0);
@@ -492,10 +543,6 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
/* skip to next descriptor */
desc_len += p[DESC_bLength];
p += p[DESC_bLength];
-
- if (desc_len > hport->config.config_desc.wTotalLength) {
- return -USB_ERR_INVAL;
- }
}
usbh_video_list_info(video_class);