The function _ux_host_class_audio_alternate_setting_locate() walks through a USB audio configuration descriptor, parsing each section to identify alternate interface settings and extract sampling frequency information.
A vulnerability exists in how this function accesses fields in the descriptor when bSamFreqType indicates either a range of frequencies (type 0) or a list of specific frequencies (non-zero). In both cases, the function blindly reads additional bytes from the descriptor without verifying that enough data remains.
For example, if the descriptor is truncated but reports a valid bSamFreqType, the function may read six bytes for min/max frequency in type 0, or 3 × N bytes for N specific frequency values. Without bounds checks, a malformed or malicious USB device could craft a short descriptor that causes the host to read past the buffer—potentially leading to crashes or information leakage.
code:
UINT _ux_host_class_audio_alternate_setting_locate(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_SAMPLING *audio_sampling,
UINT *alternate_setting)
{
...
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_INTERFACE_DESCRIPTOR_ITEM:
/* Parse the interface descriptor and make it machine independent. */
_ux_utility_descriptor_parse(descriptor, _ux_system_interface_descriptor_structure,
UX_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &interface_descriptor);
...
case UX_HOST_CLASS_AUDIO_CS_INTERFACE:
...
_ux_utility_descriptor_parse(descriptor, _ux_system_class_audio_interface_descriptor_structure,
UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &audio_interface_descriptor);
...
if (audio_interface_descriptor.bSamFreqType == 0)
{
/* The declaration of frequency is contiguous, so get the minimum and maximum */
lower_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 1)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 2)) << 16;
higher_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 3) |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 4)) << 8 |
((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16;
...
}
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++)
{
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_alternate_setting_locate()walks through a USB audio configuration descriptor, parsing each section to identify alternate interface settings and extract sampling frequency information.A vulnerability exists in how this function accesses fields in the descriptor when
bSamFreqTypeindicates either a range of frequencies (type 0) or a list of specific frequencies (non-zero). In both cases, the function blindly reads additional bytes from the descriptor without verifying that enough data remains.For example, if the descriptor is truncated but reports a valid
bSamFreqType, the function may read six bytes for min/max frequency in type 0, or 3 × N bytes for N specific frequency values. Without bounds checks, a malformed or malicious USB device could craft a short descriptor that causes the host to read past the buffer—potentially leading to crashes or information leakage.code: