Is there an existing issue for this?
Current Behavior
Using a USB device that has HS capability, a keyboard device, I trigger an issue during the boot sequence when a BIOS wants to use it with the boot interface and thus using something else than idle rate = 0. Digging into this, there seems to be a field that seems to be misused:
Code path used: Components/USB/Source/
In the structure usbd_hid_t, the field ep_int_in_interval is declared as two uint16_t. It is initialized in usbd_config.c with this line (2921):
{ USBD_HID0_EP_INT_IN_BINTERVAL, (2 << ((USBD_HID0_EP_INT_IN_HS_BINTERVAL & 0x0F)-1)) },
USBD_HID0_EP_INT_IN_HS_BINTERVAL comes from the configuration file USBD_Config_HID_0.h, where it is set up (with the Configuration Wizard) as a number between 1-16, meaning number of 125us steps - resulting in 125us up to 4096ms polling rate.
For example, using 16ms polling rate, we end up with the number 7. So the ep_int_in_interval[1] will be setup to a value of 2 << (7-1) = 0x80 = 128. This is in 125us steps, so it means 16ms; nice.
Now this field is used in the file usbd_lib_hid.c on line 501:
polling_interval = INTERVAL_HS[ptr_hid_cfg->ep_int_in_interval[1]-1U];
The INTERVAL_HS arrays is declared in the same file as
extern const uint16_t INTERVAL_HS[16];
const uint16_t INTERVAL_HS[16] = { 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
The problem here is that line 501 uses the 0x80 value (minus one) as an index into the array of size 16.; we get out-of-bounds here.
This works nice if the interval is setup to a low value, for example polling rate 250us gives us the value 2, ending up in ep_int_in_interval[1] as 4. This is and index that can be used in the INTERVAL_HS array.
But it seems the use of ep_int_in_interval is not really consistent between the files:
Is it 125us steps or is it an index that can be converted to a ms value?
Expected Behavior
The INTERVAL_HS array is not used out-of-bounds
Steps To Reproduce
USB device, high speed, endpoint IN uses a polling rate >= 8 (corresponding to 1ms). USB host using something else than idle rate = 0.
Affected components
Version
Pack version 8.0.0 - 8.2.0
Component version 8.0.0
Blocker
Is there an existing issue for this?
Current Behavior
Using a USB device that has HS capability, a keyboard device, I trigger an issue during the boot sequence when a BIOS wants to use it with the boot interface and thus using something else than idle rate = 0. Digging into this, there seems to be a field that seems to be misused:
Code path used: Components/USB/Source/
In the structure usbd_hid_t, the field ep_int_in_interval is declared as two uint16_t. It is initialized in usbd_config.c with this line (2921):
{ USBD_HID0_EP_INT_IN_BINTERVAL, (2 << ((USBD_HID0_EP_INT_IN_HS_BINTERVAL & 0x0F)-1)) },
USBD_HID0_EP_INT_IN_HS_BINTERVAL comes from the configuration file USBD_Config_HID_0.h, where it is set up (with the Configuration Wizard) as a number between 1-16, meaning number of 125us steps - resulting in 125us up to 4096ms polling rate.
For example, using 16ms polling rate, we end up with the number 7. So the ep_int_in_interval[1] will be setup to a value of 2 << (7-1) = 0x80 = 128. This is in 125us steps, so it means 16ms; nice.
Now this field is used in the file usbd_lib_hid.c on line 501:
polling_interval = INTERVAL_HS[ptr_hid_cfg->ep_int_in_interval[1]-1U];
The INTERVAL_HS arrays is declared in the same file as
extern const uint16_t INTERVAL_HS[16];
const uint16_t INTERVAL_HS[16] = { 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
The problem here is that line 501 uses the 0x80 value (minus one) as an index into the array of size 16.; we get out-of-bounds here.
This works nice if the interval is setup to a low value, for example polling rate 250us gives us the value 2, ending up in ep_int_in_interval[1] as 4. This is and index that can be used in the INTERVAL_HS array.
But it seems the use of ep_int_in_interval is not really consistent between the files:
Is it 125us steps or is it an index that can be converted to a ms value?
Expected Behavior
The INTERVAL_HS array is not used out-of-bounds
Steps To Reproduce
USB device, high speed, endpoint IN uses a polling rate >= 8 (corresponding to 1ms). USB host using something else than idle rate = 0.
Affected components
Version
Pack version 8.0.0 - 8.2.0
Component version 8.0.0
Blocker