The function _ux_host_class_audio_streaming_sampling_get() parses a USB audio streaming interface descriptor to extract supported audio sampling characteristics. It iterates through descriptors in the configuration buffer and attempts to read specific frequency values when bSamFreqType is non-zero.
When bSamFreqType is non-zero, the descriptor includes an array of bSamFreqType 3-byte values starting at a fixed offset. However, the function does not validate that the buffer contains at least 3 × bSamFreqType bytes before performing the read. This leads to a possible out-of-bounds read if the descriptor is malformed or shorter than claimed.
A malicious USB device could exploit this by setting a large bSamFreqType value while providing an insufficient descriptor length, causing the host to read beyond valid memory. This could lead to crashes or memory disclosure.
code:
UINT _ux_host_class_audio_streaming_sampling_get(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS *audio_sampling)
{
...
descriptor = audio -> ux_host_class_audio_configuration_descriptor;
total_descriptor_length = audio -> ux_host_class_audio_configuration_descriptor_length;
...
while (total_descriptor_length)
{
/* Gather the length, type and subtype of the descriptor. */
descriptor_length = *descriptor;
descriptor_type = *(descriptor + 1);
descriptor_subtype = *(descriptor + 2);
...
switch(descriptor_type)
{
...
case UX_HOST_CLASS_AUDIO_CS_INTERFACE:
...
if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_channels == 0) &&
(audio_sampling -> ux_host_class_audio_sampling_characteristics_resolution == 0))
{
...
else
{
/* This is not the second time we ask for the characteristics, we need
to find 1st where we left off and look at the next characteristics. */
if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_channels == audio_interface_descriptor.bNrChannels) &&
(audio_sampling -> ux_host_class_audio_sampling_characteristics_resolution == audio_interface_descriptor.bBitResolution))
{
...
if (audio_interface_descriptor.bSamFreqType == 0)
{
...
}
else
{
/* The declaration of the frequency is declared as an array of specific values. */
for (specific_frequency_count = 0; specific_frequency_count < audio_interface_descriptor.bSamFreqType; specific_frequency_count++) <-- this for look can go out of bound
{
lower_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (specific_frequency_count * 3)) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 1 + (specific_frequency_count * 3))) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 2 + (specific_frequency_count * 3))) << 16;
...
The function
_ux_host_class_audio_streaming_sampling_get()parses a USB audio streaming interface descriptor to extract supported audio sampling characteristics. It iterates through descriptors in the configuration buffer and attempts to read specific frequency values whenbSamFreqTypeis non-zero.When
bSamFreqTypeis non-zero, the descriptor includes an array ofbSamFreqType3-byte values starting at a fixed offset. However, the function does not validate that the buffer contains at least 3 ×bSamFreqType bytes before performing the read. This leads to a possible out-of-bounds read if the descriptor is malformed or shorter than claimed.A malicious USB device could exploit this by setting a large
bSamFreqTypevalue while providing an insufficient descriptor length, causing the host to read beyond valid memory. This could lead to crashes or memory disclosure.code: