summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2026-03-30 22:31:48 +0800
committersakumisu <[email protected]>2026-03-30 22:33:37 +0800
commit9205d533608c84f5f6e586bb27d963fd72e89b16 (patch)
tree136a734c973a24d7aa5624a2520d355491eee32c
parenta45525f6f82f6b32aa9ddc72da5fde09e5ad5f36 (diff)
fix(security): add check for audio driver and video driver
Signed-off-by: sakumisu <[email protected]>
-rw-r--r--class/audio/usb_audio.h8
-rw-r--r--class/audio/usbd_audio.c8
-rw-r--r--class/audio/usbh_audio.c13
-rw-r--r--class/video/usbh_video.c16
-rw-r--r--class/video/usbh_video.h12
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;
};