Skip to content

[Bug]: High speed USB Device can get array out-of-bound read for polling rate #151

Description

@driverguru

Is there an existing issue for this?

  • I have searched the existing issues

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

  • Filesystem
  • Network
  • USB_Device
  • USB_Host

Version

Pack version 8.0.0 - 8.2.0
Component version 8.0.0

Blocker

  • blocker

Metadata

Metadata

Labels

bugSomething isn't workingtriageLabel indicating that this issue is new and has not been reviewed yet.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions