diff options
| author | sakumisu <[email protected]> | 2026-03-30 22:31:48 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2026-03-30 22:33:37 +0800 |
| commit | 9205d533608c84f5f6e586bb27d963fd72e89b16 (patch) | |
| tree | 136a734c973a24d7aa5624a2520d355491eee32c | |
| parent | a45525f6f82f6b32aa9ddc72da5fde09e5ad5f36 (diff) | |
fix(security): add check for audio driver and video driver
Signed-off-by: sakumisu <[email protected]>
| -rw-r--r-- | class/audio/usb_audio.h | 8 | ||||
| -rw-r--r-- | class/audio/usbd_audio.c | 8 | ||||
| -rw-r--r-- | class/audio/usbh_audio.c | 13 | ||||
| -rw-r--r-- | class/video/usbh_video.c | 16 | ||||
| -rw-r--r-- | class/video/usbh_video.h | 12 |
5 files changed, 47 insertions, 10 deletions
diff --git a/class/audio/usb_audio.h b/class/audio/usb_audio.h index 6c25c3de..68334044 100644 --- a/class/audio/usb_audio.h +++ b/class/audio/usb_audio.h @@ -642,7 +642,7 @@ struct audio_cs_if_ac_feature_unit_descriptor { uint8_t bUnitID; uint8_t bSourceID; uint8_t bControlSize; - uint8_t bmaControls[1]; + uint8_t bmaControls[33]; // variable uint8_t iFeature; } __PACKED; @@ -1318,10 +1318,10 @@ struct audio_v2_control_range3_param_block { // clang-format on -#define AUDIO_V2_AS_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) +#define AUDIO_V2_AS_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08) #define AUDIO_V2_AS_ALTSETTING0_DESCRIPTOR_LEN (0x09) -#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08) -#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) +#define AUDIO_V2_AS_ALTSETTING_DESCRIPTOR_LEN (0x09 + 0x10 + 0x06 + 0x07 + 0x08) +#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07) #define AUDIO_SAMPLE_FREQ_NUM(num) (uint8_t)(num), (uint8_t)((num >> 8)) #define AUDIO_SAMPLE_FREQ_3B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) diff --git a/class/audio/usbd_audio.c b/class/audio/usbd_audio.c index 67d375b4..9e4e2ac0 100644 --- a/class/audio/usbd_audio.c +++ b/class/audio/usbd_audio.c @@ -32,7 +32,7 @@ static int audio_class_endpoint_request_handler(uint8_t busid, struct usb_setup_ case AUDIO_EP_CONTROL_SAMPLING_FEQ: switch (setup->bRequest) { case AUDIO_REQUEST_SET_CUR: - memcpy((uint8_t *)&sampling_freq, *data, *len); + memcpy((uint8_t *)&sampling_freq, *data, 3); USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); usbd_audio_set_sampling_freq(busid, ep, sampling_freq); break; @@ -130,7 +130,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup if (g_usbd_audio[busid].uac_version < 0x0200) { switch (setup->bRequest) { case AUDIO_REQUEST_SET_CUR: - memcpy(&volume, *data, *len); + memcpy(&volume, *data, 2); if (volume < 0x8000) { volume_db = volume / 256; } else { @@ -182,7 +182,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup memcpy(*data, &volume, 2); *len = 2; } else { - memcpy(&volume, *data, *len); + memcpy(&volume, *data, 2); if (volume < 0x8000) { volume_db = volume / 256; } else { @@ -223,7 +223,7 @@ static int audio_class_interface_request_handler(uint8_t busid, struct usb_setup USB_LOG_DBG("Get ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); *len = 4; } else { - memcpy(&sampling_freq, *data, setup->wLength); + memcpy(&sampling_freq, *data, 4); USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq); usbd_audio_set_sampling_freq(busid, ep, sampling_freq); } diff --git a/class/audio/usbh_audio.c b/class/audio/usbh_audio.c index 4aed30fe..3913dc5b 100644 --- a/class/audio/usbh_audio.c +++ b/class/audio/usbh_audio.c @@ -404,6 +404,7 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) switch (p[DESC_bDescriptorType]) { case USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION: cur_iface_count = p[3]; + USB_ASSERT(cur_iface_count <= CONFIG_USBHOST_AUDIO_MAX_STREAMS); break; case USB_DESCRIPTOR_TYPE_INTERFACE: cur_iface = p[INTF_DESC_bInterfaceNumber]; @@ -422,18 +423,26 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) case AUDIO_CONTROL_INPUT_TERMINAL: { struct audio_cs_if_ac_input_terminal_descriptor *desc = (struct audio_cs_if_ac_input_terminal_descriptor *)p; + USB_ASSERT(input_offset < CONFIG_USBHOST_AUDIO_MAX_STREAMS); + memcpy(&ac_msg_table[input_offset].ac_input, desc, sizeof(struct audio_cs_if_ac_input_terminal_descriptor)); input_offset++; } break; case AUDIO_CONTROL_OUTPUT_TERMINAL: { struct audio_cs_if_ac_output_terminal_descriptor *desc = (struct audio_cs_if_ac_output_terminal_descriptor *)p; + USB_ASSERT(output_offset < CONFIG_USBHOST_AUDIO_MAX_STREAMS); + memcpy(&ac_msg_table[output_offset].ac_output, desc, sizeof(struct audio_cs_if_ac_output_terminal_descriptor)); output_offset++; } break; case AUDIO_CONTROL_FEATURE_UNIT: { struct audio_cs_if_ac_feature_unit_descriptor *desc = (struct audio_cs_if_ac_feature_unit_descriptor *)p; + USB_ASSERT(feature_unit_offset < CONFIG_USBHOST_AUDIO_MAX_STREAMS); + USB_ASSERT(desc->bControlSize == 1); + USB_ASSERT(desc->bLength <= sizeof(struct audio_cs_if_ac_feature_unit_descriptor)); + memcpy(&ac_msg_table[feature_unit_offset].ac_feature_unit, desc, desc->bLength); feature_unit_offset++; } break; @@ -452,6 +461,9 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) } break; case AUDIO_STREAMING_FORMAT_TYPE: { struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p; + + USB_ASSERT(desc->bFormatType == 1); + audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].num_of_altsetting = (cur_alt_setting + 1); memcpy(&audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].as_format[cur_alt_setting], desc, desc->bLength); } break; @@ -464,6 +476,7 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) if ((cur_iface > audio_class->ctrl_intf) && (cur_iface < (audio_class->ctrl_intf + cur_iface_count))) { if (p[DESC_bDescriptorSubType] == AUDIO_ENDPOINT_GENERAL) { struct audio_cs_ep_ep_general_descriptor *desc = (struct audio_cs_ep_ep_general_descriptor *)p; + audio_class->as_msg_table[cur_iface - audio_class->ctrl_intf - 1].ep_attr = desc->bmAttributes; } } diff --git a/class/video/usbh_video.c b/class/video/usbh_video.c index 18acbda3..2e06e973 100644 --- a/class/video/usbh_video.c +++ b/class/video/usbh_video.c @@ -437,6 +437,9 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) format_index = p[DESC_bFormatIndex]; num_of_frames = p[DESC_bNumFrameDescriptors]; + USB_ASSERT(format_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + video_class->format[format_index - 1].num_of_frames = num_of_frames; video_class->format[format_index - 1].format_type = USBH_VIDEO_FORMAT_UNCOMPRESSED; break; @@ -444,12 +447,20 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) format_index = p[DESC_bFormatIndex]; num_of_frames = p[DESC_bNumFrameDescriptors]; + USB_ASSERT(format_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + video_class->format[format_index - 1].num_of_frames = num_of_frames; video_class->format[format_index - 1].format_type = USBH_VIDEO_FORMAT_MJPEG; break; case VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_SUBTYPE: frame_index = p[DESC_bFrameIndex]; + USB_ASSERT(format_index != 0); + USB_ASSERT(frame_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + USB_ASSERT(frame_index <= CONFIG_USBHOST_VIDEO_MAX_FRAMES); + video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wWidth; video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wHeight; video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->dwDefaultFrameInterval; @@ -457,6 +468,11 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) case VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE: frame_index = p[DESC_bFrameIndex]; + USB_ASSERT(format_index != 0); + USB_ASSERT(frame_index != 0); + USB_ASSERT(format_index <= CONFIG_USBHOST_VIDEO_MAX_FORMATS); + USB_ASSERT(frame_index <= CONFIG_USBHOST_VIDEO_MAX_FRAMES); + video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wWidth; video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wHeight; video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->dwDefaultFrameInterval; diff --git a/class/video/usbh_video.h b/class/video/usbh_video.h index 9edce49b..b1ae438a 100644 --- a/class/video/usbh_video.h +++ b/class/video/usbh_video.h @@ -11,6 +11,14 @@ #define USBH_VIDEO_FORMAT_UNCOMPRESSED 0 #define USBH_VIDEO_FORMAT_MJPEG 1 +#ifndef CONFIG_USBHOST_VIDEO_MAX_FRAMES +#define CONFIG_USBHOST_VIDEO_MAX_FRAMES 12 +#endif + +#ifndef CONFIG_USBHOST_VIDEO_MAX_FORMATS +#define CONFIG_USBHOST_VIDEO_MAX_FORMATS 3 +#endif + struct usbh_video_resolution { uint16_t wWidth; uint16_t wHeight; @@ -18,7 +26,7 @@ struct usbh_video_resolution { }; struct usbh_video_format { - struct usbh_video_resolution frame[12]; + struct usbh_video_resolution frame[CONFIG_USBHOST_VIDEO_MAX_FRAMES]; uint8_t format_type; uint8_t num_of_frames; }; @@ -55,7 +63,7 @@ struct usbh_video { uint16_t bcdVDC; uint8_t num_of_intf_altsettings; uint8_t num_of_formats; - struct usbh_video_format format[3]; + struct usbh_video_format format[CONFIG_USBHOST_VIDEO_MAX_FORMATS]; void *user_data; }; |
