summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-03-09 14:15:20 +0700
committerhathach <[email protected]>2026-03-09 14:15:20 +0700
commit0d4feff0eb01511d413e79109656dd76bf42e77a (patch)
treef412cf9874704315d27bebb62f1cd07bcb3a8301
parent7fac2cda29a14e963c469a146f18ea294f955171 (diff)
usbh device descriptor validation, also check ep size > 0
-rw-r--r--src/common/tusb_private.h3
-rw-r--r--src/host/usbh.c30
-rw-r--r--src/tusb.c3
3 files changed, 23 insertions, 13 deletions
diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h
index 5a51dfc37..17ab267c3 100644
--- a/src/common/tusb_private.h
+++ b/src/common/tusb_private.h
@@ -81,9 +81,8 @@ typedef struct {
bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed);
#else
TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
- (void)desc_ep;
(void)speed;
- return true;
+ return tu_edpt_packet_size(desc_ep) > 0;
}
#endif
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 33d74862f..0fa9b6646 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -1150,7 +1150,7 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) {
}
bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) {
- // HACK: some device incorrectly always report 512 bulk regardless of link speed, overwrite descriptor to force 64
+ // HACK: some device incorrectly always reports 512 bulk regardless of link speed, overwrite descriptor to force 64
if (desc_ep->bmAttributes.xfer == TUSB_XFER_BULK && tu_edpt_packet_size(desc_ep) > 64 &&
tuh_speed_get(dev_addr) == TUSB_SPEED_FULL) {
TU_LOG1(" WARN: EP max packet size is 512 in fullspeed, force to 64\r\n");
@@ -1655,6 +1655,7 @@ static void process_enumeration(tuh_xfer_t *xfer) {
TU_ASSERT(dev != NULL,);
}
uint16_t langid = 0x0409; // default is English
+ bool is_enum_failed = false;
switch (state) {
#if CFG_TUH_HUB
@@ -1664,11 +1665,11 @@ static void process_enumeration(tuh_xfer_t *xfer) {
if (0 == port_status.status.connection) {
TU_LOG_USBH("Device unplugged from hub while debouncing\r\n");
- enum_full_complete(false);
- return;
+ is_enum_failed = true;
+ } else {
+ TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration,
+ ENUM_HUB_RESET_COMPLETE), );
}
-
- TU_ASSERT(hub_port_reset(dev0_bus->hub_addr, dev0_bus->hub_port, process_enumeration, ENUM_HUB_RESET_COMPLETE), );
break;
}
@@ -1691,7 +1692,7 @@ static void process_enumeration(tuh_xfer_t *xfer) {
usbh_defer_func_ms_async(ENUM_RESET_HUB_DELAY_MS, enum_delay_async, ENUM_AFTER_RESET_HUB_DELAY_RETRY);
} else {
// retry but still not set --> failed
- enum_full_complete(false);
+ is_enum_failed = true;
}
break;
}
@@ -1702,14 +1703,13 @@ static void process_enumeration(tuh_xfer_t *xfer) {
if (0 == port_status.status.connection) {
TU_LOG_USBH("Device unplugged from hub (not addressed yet)\r\n");
- enum_full_complete(false);
- return;
+ is_enum_failed = true;
+ break;
}
dev0_bus->speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH
: (port_status.status.low_speed) ? TUSB_SPEED_LOW
: TUSB_SPEED_FULL;
-
TU_ATTR_FALLTHROUGH;
}
#endif
@@ -1720,6 +1720,12 @@ static void process_enumeration(tuh_xfer_t *xfer) {
case ENUM_SET_ADDR: {
const tusb_desc_device_t *desc_device = (const tusb_desc_device_t *) _usbh_epbuf.ctrl;
+ if (!(desc_device->bDescriptorType == TUSB_DESC_DEVICE && desc_device->bMaxPacketSize0 >= 8)) {
+ TU_LOG_USBH("Invalid Device descriptor\r\n");
+ is_enum_failed = true;
+ break;
+ }
+
const uint8_t new_addr = enum_get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB);
TU_ASSERT(new_addr != 0,);
@@ -1910,9 +1916,13 @@ static void process_enumeration(tuh_xfer_t *xfer) {
}
default:
- enum_full_complete(false); // stop enumeration if unknown state
+ is_enum_failed = true;
break;
}
+
+ if (is_enum_failed) {
+ enum_full_complete(false);
+ }
}
static uint8_t enum_get_new_address(bool is_hub) {
diff --git a/src/tusb.c b/src/tusb.c
index 5241fcf3d..4ea396715 100644
--- a/src/tusb.c
+++ b/src/tusb.c
@@ -260,6 +260,7 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) {
bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
const uint16_t max_packet_size = tu_edpt_packet_size(desc_ep);
TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size);
+ TU_ASSERT(max_packet_size > 0);
switch (desc_ep->bmAttributes.xfer) {
case TUSB_XFER_ISOCHRONOUS: {
@@ -279,7 +280,7 @@ bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
break;
case TUSB_XFER_INTERRUPT: {
- uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64);
+ const uint16_t spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64);
TU_ASSERT(max_packet_size <= spec_size);
break;
}