From 85047e1777f5c20b7a936aa905c746125d3ed066 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Fri, 12 Jun 2026 11:14:18 +0530 Subject: bound item size to remaining length in hid report descriptor parser --- src/class/hid/hid_host.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index fc7704258..bd419c72d 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -704,6 +704,10 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, size = 4; // HID 1.11 6.2.2.2 3 is 4 bytes } + // item data must fit in the remaining descriptor; a truncated item would + // read past the buffer and underflow desc_len below + if (size > desc_len) break; + uint8_t const data8 = (size > 0) ? desc_report[0] : 0; TU_LOG(3, "tag = %d, type = %d, size = %d, data = ", tag, type, size); @@ -738,7 +742,7 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, switch (tag) { case RI_GLOBAL_USAGE_PAGE: // only take in account the "usage page" before REPORT ID - if (ri_collection_depth == 0) memcpy(&info->usage_page, desc_report, size); + if (ri_collection_depth == 0) memcpy(&info->usage_page, desc_report, TU_MIN(size, sizeof(info->usage_page))); break; case RI_GLOBAL_LOGICAL_MIN: break; -- cgit v1.3.1 From 9f8812f81bdd323399abd6e18c2567fed3efebc5 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Mon, 15 Jun 2026 10:25:51 +0530 Subject: zero-extend usage page before copying shorter payload --- src/class/hid/hid_host.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index bd419c72d..29bcae99f 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -742,7 +742,12 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, switch (tag) { case RI_GLOBAL_USAGE_PAGE: // only take in account the "usage page" before REPORT ID - if (ri_collection_depth == 0) memcpy(&info->usage_page, desc_report, TU_MIN(size, sizeof(info->usage_page))); + if (ri_collection_depth == 0) { + // zero-extend: a shorter payload must not leave a stale high byte + // from a previous usage page item in the same report + info->usage_page = 0; + memcpy(&info->usage_page, desc_report, TU_MIN(size, sizeof(info->usage_page))); + } break; case RI_GLOBAL_LOGICAL_MIN: break; -- cgit v1.3.1