From 2a1acfd3333d7b6f90c3b24e177ca9c19131271d Mon Sep 17 00:00:00 2001 From: Nicola Jaggi Date: Tue, 4 Feb 2025 14:42:48 +0100 Subject: [PATCH 01/19] Terminate the hid interrupt out endpoint on deactivate --- .../usbx_device_classes/src/ux_device_class_hid_deactivate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c index c83e1bd3..cf414049 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c @@ -86,6 +86,10 @@ UX_SLAVE_CLASS *class_ptr; /* Terminate the transactions pending on the endpoints. */ _ux_device_stack_transfer_all_request_abort(hid -> ux_device_class_hid_interrupt_endpoint, UX_TRANSFER_BUS_RESET); +#if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) + _ux_device_stack_transfer_all_request_abort(hid -> ux_device_class_hid_read_endpoint, UX_TRANSFER_BUS_RESET); +#endif + /* If there is a deactivate function call it. */ if (hid -> ux_slave_class_hid_instance_deactivate != UX_NULL) { From c49990d3642cd741ebe9ed15a6f17cb07b746a22 Mon Sep 17 00:00:00 2001 From: Christer Ekholm Date: Wed, 16 Apr 2025 20:28:33 +0800 Subject: [PATCH 02/19] Fix copy paste errors --- .../src/ux_device_class_pima_interrupt_thread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c b/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c index 08db3f2f..290bea15 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_interrupt_thread.c @@ -169,10 +169,10 @@ UCHAR *buffer; _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_1, pima_event.ux_device_class_pima_event_parameter_1); /* Put the value of parameter 2. */ - _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_2, pima_event.ux_device_class_pima_event_parameter_3); + _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_2, pima_event.ux_device_class_pima_event_parameter_2); /* Put the value of parameter 3. */ - _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_2, pima_event.ux_device_class_pima_event_parameter_3); + _ux_utility_long_put(buffer + UX_DEVICE_CLASS_PIMA_AEI_PARAMETER_3, pima_event.ux_device_class_pima_event_parameter_3); /* Send the request to the device controller. */ status = _ux_device_stack_transfer_request(transfer_request_in, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH, UX_DEVICE_CLASS_PIMA_AEI_MAX_LENGTH); From 0f32d34ad7c1476af02d7e04a53efb3dbe4d3ef1 Mon Sep 17 00:00:00 2001 From: Christer Ekholm Date: Wed, 16 Apr 2025 20:59:31 +0800 Subject: [PATCH 03/19] _ux_device_class_pima_object_references_set and _ux_device_class_pima_object_info_send will return failure even if success because UX_DEVICE_CLASS_PIMA_RC_OK was handeled as error and reported to app --- .../src/ux_device_class_pima_object_info_send.c | 14 +++++++++++--- .../ux_device_class_pima_object_references_set.c | 14 ++++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c b/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c index 4d64c6ae..557c386e 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_object_info_send.c @@ -223,10 +223,18 @@ ULONG object_handle; /* Send the object to the application. */ status = pima -> ux_device_class_pima_object_info_send(pima, object, storage_id, parent_object_handle, &object_handle); - /* Now we return a response with success. */ - status = (status == UX_SUCCESS) ? UX_DEVICE_CLASS_PIMA_RC_OK : status; - _ux_device_class_pima_response_send(pima, status, 3, pima -> ux_device_class_pima_storage_id, + if (status != UX_SUCCESS) + { + /* Now we return a response with error. */ + _ux_device_class_pima_response_send(pima, status, 3, pima -> ux_device_class_pima_storage_id, object -> ux_device_class_pima_object_parent_object, object_handle); + } + else + { + /* Now we return a response with success. */ + _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_OK, 3, pima -> ux_device_class_pima_storage_id, + object -> ux_device_class_pima_object_parent_object, object_handle); + } /* Store the object handle. It will be used for the OBJECT_SEND command. */ pima -> ux_device_class_pima_current_object_handle = object_handle; diff --git a/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c b/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c index d9c704da..5197f06a 100644 --- a/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c +++ b/common/usbx_device_classes/src/ux_device_class_pima_object_references_set.c @@ -128,10 +128,16 @@ ULONG object_references_length; /* Send the object references to the application. */ status = pima -> ux_device_class_pima_object_references_set(pima, object_handle, object_references, object_references_length); - - /* Now we return a response with success. */ - status = (status == UX_SUCCESS) ? UX_DEVICE_CLASS_PIMA_RC_OK : status; - _ux_device_class_pima_response_send(pima, status, 0, 0, 0, 0); + + /* Check error code from application. */ + if (status == UX_SUCCESS) + + /* Now we return a response with success. */ + _ux_device_class_pima_response_send(pima, UX_DEVICE_CLASS_PIMA_RC_OK, 0, 0, 0, 0); + else + + /* We return an error. The code is passed by the application. */ + _ux_device_class_pima_response_send(pima, status, 0, 0, 0, 0); } else From ec41ddf41b8b5949bdf1c93949519427afdc7291 Mon Sep 17 00:00:00 2001 From: Huan Nguyen Date: Mon, 12 May 2025 10:13:56 -0600 Subject: [PATCH 04/19] Remove unused time elapsed define, ensure tests still pass --- test/regression/ux_test.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/regression/ux_test.c b/test/regression/ux_test.c index aaf845aa..b2eeb8e6 100644 --- a/test/regression/ux_test.c +++ b/test/regression/ux_test.c @@ -2,10 +2,6 @@ #include "ux_test_hcd_sim_host.h" #include "ux_test_dcd_sim_slave.h" -#ifndef _ux_utility_time_elapsed -#define _ux_utility_time_elapsed(t0,t1) ((t1)>=(t0) ? ((t1)-(t0)) : (0xFFFFFFFF - (t0) + (t1))) -#endif - #define UX_TEST_TIMEOUT_MS 3000 static UX_TEST_ACTION ux_test_action_handler_check(UX_TEST_ACTION *action, UX_TEST_FUNCTION usbx_function, void *params, UCHAR advance); From 1f66e3c13da212d2c2db2ea215bc84d42727f4ab Mon Sep 17 00:00:00 2001 From: Huan Nguyen Date: Mon, 12 May 2025 11:06:39 -0600 Subject: [PATCH 05/19] Create failing test for time elapsed utility --- test/cmake/usbx/regression/CMakeLists.txt | 1 + .../usbx_ux_utility_time_elapsed_test.c | 366 ++++++++++++++++++ 2 files changed, 367 insertions(+) create mode 100644 test/regression/usbx_ux_utility_time_elapsed_test.c diff --git a/test/cmake/usbx/regression/CMakeLists.txt b/test/cmake/usbx/regression/CMakeLists.txt index 372f235c..8d29d436 100644 --- a/test/cmake/usbx/regression/CMakeLists.txt +++ b/test/cmake/usbx/regression/CMakeLists.txt @@ -512,6 +512,7 @@ set(ux_utility_test_cases ${SOURCE_DIR}/usbx_ux_utility_pci_class_scan_test.c ${SOURCE_DIR}/usbx_ux_utility_physical_address_test.c ${SOURCE_DIR}/usbx_ux_utility_string_length_check_test.c + ${SOURCE_DIR}/usbx_ux_utility_time_elapsed_test.c ${SOURCE_DIR}/usbx_ux_utility_unicode_to_string_test.c ) set(ux_utility_os_test_cases diff --git a/test/regression/usbx_ux_utility_time_elapsed_test.c b/test/regression/usbx_ux_utility_time_elapsed_test.c new file mode 100644 index 00000000..550e8280 --- /dev/null +++ b/test/regression/usbx_ux_utility_time_elapsed_test.c @@ -0,0 +1,366 @@ +/* This test is designed to test the ux_utility_timer_.... */ + +#include +#include "tx_api.h" +#include "ux_api.h" +#include "ux_system.h" +#include "ux_utility.h" + +#include "ux_host_stack.h" +#include "ux_device_stack.h" + +#include "ux_device_class_cdc_acm.h" +#include "ux_host_class_cdc_acm.h" + +#include "ux_host_class_dpump.h" +#include "ux_device_class_dpump.h" + +#include "ux_host_class_hid.h" +#include "ux_device_class_hid.h" + +#include "ux_host_class_storage.h" +#include "ux_device_class_storage.h" + +#include "ux_test_dcd_sim_slave.h" +#include "ux_test_hcd_sim_host.h" +#include "ux_test_utility_sim.h" + + +/* Define USBX test constants. */ + +#define UX_TEST_STACK_SIZE 4096 +#define UX_TEST_BUFFER_SIZE 2048 +#define UX_TEST_RUN 1 +#define UX_TEST_MEMORY_SIZE (64*1024) + +#define LSB(x) ( (x) & 0x00ff) +#define MSB(x) (((x) & 0xff00) >> 8) + +/* Configuration descriptor 9 bytes */ +#define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\ + /* Configuration 1 descriptor 9 bytes */\ + 0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\ + (bNumInterfaces), (bConfigurationValue), 0x00,\ + 0x40, 0x00, +#define CFG_DESC_LEN 9 + +/* DPUMP interface descriptors. */ +#define DPUMP_IFC_DESC(ifc, alt, nb_ep) \ + /* Interface descriptor */\ + 0x09, 0x04, (ifc), (alt), (nb_ep), 0x99, 0x99, 0x99, 0x00, + +#define DPUMP_IFC_EP_DESC(epaddr, eptype, epsize) \ + /* Endpoint descriptor */\ + 0x07, 0x05, (epaddr), (eptype), LSB(epsize), MSB(epsize), 0x01, + +#define DPUMP_IFC_DESC_ALL_LEN(nb_ep) (9 + (nb_ep) * 7) + +#define CFG_DESC_ALL_LEN (CFG_DESC_LEN + DPUMP_IFC_DESC_ALL_LEN(4)) + +#define CFG_DESC_ALL \ + CFG_DESC(CFG_DESC_ALL_LEN, 1, 1)\ + DPUMP_IFC_DESC(0, 0, 4)\ + DPUMP_IFC_EP_DESC(0x81, 2, 64)\ + DPUMP_IFC_EP_DESC(0x02, 2, 64)\ + DPUMP_IFC_EP_DESC(0x83, 1, 64)\ + DPUMP_IFC_EP_DESC(0x84, 3, 64)\ + +/* Define the counters used in the test application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; + +static UCHAR error_callback_ignore = UX_FALSE; +static ULONG error_callback_counter; + +static UCHAR buffer[UX_TEST_BUFFER_SIZE]; + +static TX_TIMER test_timer; + +/* Define USBX test global variables. */ + +static UX_HOST_CLASS *class_driver; +static UX_HOST_CLASS_DPUMP *dpump; +static UX_SLAVE_CLASS_DPUMP *dpump_slave = UX_NULL; + +static UCHAR device_framework_full_speed[] = { + + /* Device descriptor 18 bytes */ + 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, + 0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + + CFG_DESC_ALL +}; +#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed) + +static UCHAR device_framework_high_speed[] = { + + /* Device descriptor */ + 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02, + 0x03, 0x01, + + /* Device qualifier descriptor */ + 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x01, 0x00, + + CFG_DESC_ALL +}; +#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed) + +/* String Device Framework : + Byte 0 and 1 : Word containing the language ID : 0x0904 for US + Byte 2 : Byte containing the index of the descriptor + Byte 3 : Byte containing the length of the descriptor string +*/ + +#define NUM_TEST_VALUES 2 +#define TEST_VALUES_LENGTH 3 + +static UINT test_values[NUM_TEST_VALUES][TEST_VALUES_LENGTH] = +{ + {0xFU, 0x1U, 0xFFFFFFF2U}, + {0xFFFFFFF0, 0x1U, 0x11U} +}; + +static UCHAR string_framework[] = { + + /* Manufacturer string descriptor : Index 1 */ + 0x09, 0x04, 0x01, 0x0c, + 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c, + 0x6f, 0x67, 0x69, 0x63, + + /* Product string descriptor : Index 2 */ + 0x09, 0x04, 0x02, 0x0c, + 0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70, + 0x44, 0x65, 0x6d, 0x6f, + + /* Serial Number string descriptor : Index 3 */ + 0x09, 0x04, 0x03, 0x04, + 0x30, 0x30, 0x30, 0x31 +}; +#define STRING_FRAMEWORK_LENGTH sizeof(string_framework) + + /* Multiple languages are supported on the device, to add + a language besides English, the unicode language code must + be appended to the language_id_framework array and the length + adjusted accordingly. */ +static UCHAR language_id_framework[] = { + +/* English. */ + 0x09, 0x04 +}; +#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework) + +/* Define prototypes for external Host Controller's (HCDs), classes and clients. */ + +static VOID ux_test_instance_activate(VOID *dpump_instance); +static VOID ux_test_instance_deactivate(VOID *dpump_instance); + +UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command); +UINT ux_hcd_sim_initialize(UX_HCD *hcd); +UINT _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer, + ULONG requested_length, ULONG *actual_length); +UINT _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer, + ULONG requested_length, ULONG *actual_length); + +static TX_THREAD ux_test_thread_simulation_0; +static TX_THREAD ux_test_thread_simulation_1; +static void ux_test_thread_simulation_0_entry(ULONG); +static void ux_test_thread_simulation_1_entry(ULONG); + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + +/* Simulator actions. */ + +static UX_TEST_HCD_SIM_ACTION endpoint0x83_create_del_skip[] = { +/* function, request to match, + port action, port status, + request action, request EP, request data, request actual length, request status, + status, additional callback, + no_return */ +{ UX_HCD_CREATE_ENDPOINT, NULL, + UX_FALSE, 0, + UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0, + UX_SUCCESS}, +{ UX_HCD_CREATE_ENDPOINT, NULL, + UX_FALSE, 0, + UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0, + UX_SUCCESS}, +{ 0 } +}; + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* For further expansion of interrupt-level testing. */ +} + + +static VOID error_callback(UINT system_level, UINT system_context, UINT error_code) +{ + + error_callback_counter ++; + + if (!error_callback_ignore) + { + { + /* Failed test. */ + printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code); + // test_control_return(1); + } + } +} + +static UINT break_on_dpump_ready(VOID) +{ + +UINT status; +UX_HOST_CLASS *class; + + /* Find the main data pump container. */ + status = ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class); + if (status != UX_SUCCESS) + /* Do not break. */ + return UX_SUCCESS; + + /* Find the instance. */ + status = ux_host_stack_class_instance_get(class, 0, (VOID **) &dpump); + if (status != UX_SUCCESS) + /* Do not break. */ + return UX_SUCCESS; + + if (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE) + /* Do not break. */ + return UX_SUCCESS; + + return 1; +} + +static UINT break_on_removal(VOID) +{ + +UINT status; +UX_DEVICE *device; + + status = ux_host_stack_device_get(0, &device); + if (status == UX_SUCCESS) + /* Do not break. */ + return UX_SUCCESS; + + return 1; +} + + +static UINT test_ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND *command) +{ + switch(command->ux_slave_class_command_request) + { + case UX_SLAVE_CLASS_COMMAND_INITIALIZE: + case UX_SLAVE_CLASS_COMMAND_QUERY: + case UX_SLAVE_CLASS_COMMAND_CHANGE: + return UX_SUCCESS; + + default: + return UX_NO_CLASS_MATCH; + } +} + +static UINT test_ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command) +{ + switch (command -> ux_host_class_command_request) + { + case UX_HOST_CLASS_COMMAND_QUERY: + default: + return _ux_host_class_dpump_entry(command); + } +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void usbx_ux_utility_timer_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *stack_pointer; +CHAR *memory_pointer; +CHAR *rpool_start; +CHAR *cpool_start; +const CHAR flags[] = { + UX_REGULAR_MEMORY, UX_CACHE_SAFE_MEMORY, 0xFF +}; +const CHAR expect_error[] = { + UX_FALSE, UX_FALSE, UX_TRUE +}; + + /* Inform user. */ + printf("Running ux_utility_time_elapsed... Test................................... "); + + /* Initialize the free memory pointer. */ + stack_pointer = (CHAR *) first_unused_memory; + memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2); + + rpool_start = memory_pointer; + cpool_start = memory_pointer + UX_TEST_MEMORY_SIZE; + + /* Initialize USBX Memory. */ + status = ux_system_initialize(rpool_start, UX_TEST_MEMORY_SIZE, cpool_start, UX_TEST_MEMORY_SIZE); + + /* Check for error. */ + if (status != UX_SUCCESS) + { + + printf("ERROR #%d\n", __LINE__); + test_control_return(1); + } + + /* Register the error callback. */ + _ux_utility_error_callback_register(error_callback); + + /* Create the simulation thread. */ + status = tx_thread_create(&ux_test_thread_simulation_0, "test simulation", ux_test_thread_simulation_0_entry, 0, + stack_pointer, UX_TEST_STACK_SIZE, + 20, 20, 1, TX_AUTO_START); + + /* Check for error. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #%d\n", __LINE__); + test_control_return(1); + } +} + +static void ux_test_thread_simulation_0_entry(ULONG arg) +{ + + + for (UINT i = 0; i < NUM_TEST_VALUES; ++i) + { + if (ux_utility_time_elapsed(test_values[i][0], test_values[i][1]) != test_values[i][2]) + { + printf("ERROR #%d: time elapsed incorrect\n", __LINE__); + test_control_return(1); + } + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} \ No newline at end of file From ca06d3421df0a5ce07925abae17d2ef712399150 Mon Sep 17 00:00:00 2001 From: Huan Nguyen Date: Mon, 12 May 2025 11:09:46 -0600 Subject: [PATCH 06/19] Fix _ux_utility_time_elapsed define and pass tests --- common/core/inc/ux_utility.h | 2 +- test/regression/usbx_ux_utility_time_elapsed_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/core/inc/ux_utility.h b/common/core/inc/ux_utility.h index 8a8ea986..c2fd8f4b 100644 --- a/common/core/inc/ux_utility.h +++ b/common/core/inc/ux_utility.h @@ -172,7 +172,7 @@ extern ULONG _ux_utility_time_get(VOID); #endif #ifndef _ux_utility_time_elapsed -#define _ux_utility_time_elapsed(a,b) (((b)>=(a)) ? ((b)-(a)) : (0xFFFFFFFFul-(b)+(a)+1)) +#define _ux_utility_time_elapsed(a,b) (((b)>=(a)) ? ((b)-(a)) : (0xFFFFFFFFul-(a)+(b)+1)) #else extern ALIGN_TYPE _ux_utility_time_elapsed(ALIGN_TYPE, ALIGN_TYPE); #endif diff --git a/test/regression/usbx_ux_utility_time_elapsed_test.c b/test/regression/usbx_ux_utility_time_elapsed_test.c index 550e8280..f651867b 100644 --- a/test/regression/usbx_ux_utility_time_elapsed_test.c +++ b/test/regression/usbx_ux_utility_time_elapsed_test.c @@ -1,4 +1,4 @@ -/* This test is designed to test the ux_utility_timer_.... */ +/* This test is designed to test the ux_utility_time_elapsed macro.... */ #include #include "tx_api.h" From be18a17c5d3bca5a0c70721531ba24e82ebc7b9c Mon Sep 17 00:00:00 2001 From: MAY Date: Fri, 30 May 2025 00:23:38 +0200 Subject: [PATCH 07/19] Fix host cdc ecm packet pool instance wait --- .../src/ux_host_class_cdc_ecm_thread.c | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c index 8c24bc1c..88d0a4c4 100644 --- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c +++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c @@ -1,18 +1,18 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * Copyright (c) 2024 Microsoft Corporation + * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. - * + * * SPDX-License-Identifier: MIT **************************************************************************/ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** CDC_ECM Class */ /** */ @@ -30,32 +30,32 @@ #if !defined(UX_HOST_STANDALONE) -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_cdc_ecm_thread PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_cdc_ecm_thread PORTABLE C */ /* 6.2.0 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This is the CDC ECM thread that monitors the link change flag, */ /* receives data from the device, and passes the data to the NetX-USB */ -/* broker. */ -/* */ -/* INPUT */ -/* */ -/* cdc_ecm CDC ECM instance */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* broker. */ +/* */ +/* INPUT */ +/* */ +/* cdc_ecm CDC ECM instance */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_host_class_cdc_ecm_transmit_queue_clean */ /* Clean transmit queue */ /* _ux_host_stack_transfer_request Transfer request */ @@ -67,15 +67,15 @@ /* _ux_network_driver_packet_received Process received packet */ /* nx_packet_allocate Allocate NetX packet */ /* nx_packet_release Free NetX packet */ -/* */ -/* CALLED BY */ -/* */ -/* CDC ECM class initialization */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* CALLED BY */ +/* */ +/* CDC ECM class initialization */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* prefixed UX to MS_TO_TICK, */ @@ -114,9 +114,9 @@ ULONG packet_buffer_size; /* Cast the parameter passed in the thread into the cdc_ecm pointer. */ UX_THREAD_EXTENSION_PTR_GET(cdc_ecm, UX_HOST_CLASS_CDC_ECM, parameter) - /* Loop forever waiting for changes signaled through the semaphore. */ + /* Loop forever waiting for changes signaled through the semaphore. */ while (1) - { + { /* Wait for the semaphore to be put by the cdc_ecm interrupt event. */ _ux_host_semaphore_get_norc(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore, UX_WAIT_FOREVER); @@ -130,10 +130,10 @@ ULONG packet_buffer_size; /* Communicate the state with the network driver. */ _ux_network_driver_link_up(cdc_ecm -> ux_host_class_cdc_ecm_network_handle); - + /* As long as we are connected, configured and link up ... do some work.... */ while ((cdc_ecm -> ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP) && - (cdc_ecm -> ux_host_class_cdc_ecm_device -> ux_device_state == UX_DEVICE_CONFIGURED)) + (cdc_ecm -> ux_host_class_cdc_ecm_device -> ux_device_state == UX_DEVICE_CONFIGURED)) { /* Check if we have packet pool available. */ @@ -154,7 +154,7 @@ ULONG packet_buffer_size; { /* IP instance is not available, wait for application to attach the interface. */ - _ux_utility_delay_ms(UX_MS_TO_TICK(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT)); + _ux_utility_delay_ms(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT); } continue; } @@ -168,7 +168,7 @@ ULONG packet_buffer_size; /* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */ packet -> nx_packet_prepend_ptr += sizeof(USHORT); - + /* We have a packet. Link this packet to the reception transfer request on the bulk in endpoint. */ transfer_request = &cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_endpoint -> ux_endpoint_transfer_request; @@ -206,18 +206,18 @@ ULONG packet_buffer_size; #endif { - /* Set the data pointer. */ + /* Set the data pointer. */ transfer_request -> ux_transfer_request_data_pointer = packet -> nx_packet_prepend_ptr; - + } /* And length. */ transfer_request -> ux_transfer_request_requested_length = UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE; transfer_request -> ux_transfer_request_actual_length = 0; - + /* Store the packet that owns this transaction. */ transfer_request -> ux_transfer_request_user_specific = packet; - + /* Reset the queue pointer of this packet. */ packet -> nx_packet_queue_next = UX_NULL; @@ -235,7 +235,7 @@ ULONG packet_buffer_size; cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_check_and_arm_in_process = UX_FALSE; if (cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish == UX_TRUE) _ux_host_semaphore_put(&cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore); - + /* Check if the transaction was armed successfully. */ if (status == UX_SUCCESS) { @@ -280,13 +280,13 @@ ULONG packet_buffer_size; { /* Get the packet length. */ - packet -> nx_packet_length = transfer_request -> ux_transfer_request_actual_length; - - /* Adjust the prepend, length, and append fields. */ + packet -> nx_packet_length = transfer_request -> ux_transfer_request_actual_length; + + /* Adjust the prepend, length, and append fields. */ packet -> nx_packet_append_ptr = packet->nx_packet_prepend_ptr + transfer_request -> ux_transfer_request_actual_length; } - + /* Send that packet to the NetX USB broker. */ _ux_network_driver_packet_received(cdc_ecm -> ux_host_class_cdc_ecm_network_handle, packet); } @@ -345,6 +345,6 @@ ULONG packet_buffer_size; /* Set the link state. */ cdc_ecm -> ux_host_class_cdc_ecm_link_state = UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN; } - } + } } #endif From 13e773f3a37e0ee9a545ee7547213cb3ca440db4 Mon Sep 17 00:00:00 2001 From: MAY Date: Thu, 5 Jun 2025 01:14:41 +0200 Subject: [PATCH 08/19] Add check length for inquiry page code --- .../src/ux_device_class_storage_initialize.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c index 0ec29d8d..be1bb69e 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c @@ -1,10 +1,10 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * Copyright (c) 2024 Microsoft Corporation + * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. - * + * * SPDX-License-Identifier: MIT **************************************************************************/ @@ -290,8 +290,17 @@ UINT i; storage_parameter = command -> ux_slave_class_command_parameter; /* Sanity checks. */ - if (storage_parameter -> ux_slave_class_storage_parameter_number_lun > UX_MAX_SLAVE_LUN) + if ((storage_parameter -> ux_slave_class_storage_parameter_number_lun > UX_MAX_SLAVE_LUN) || + ((storage_parameter -> ux_slave_class_storage_parameter_vendor_id != UX_NULL) && + ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_vendor_id) != 8)) || + ((storage_parameter -> ux_slave_class_storage_parameter_product_id != UX_NULL) && + ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_product_id) != 16)) || + ((storage_parameter -> ux_slave_class_storage_parameter_product_rev != UX_NULL) && + ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_product_rev) != 4)) || + ((storage_parameter -> ux_slave_class_storage_parameter_product_serial != UX_NULL) && + ( _ux_utility_string_length_get(storage_parameter -> ux_slave_class_storage_parameter_product_serial) != 20))) return(UX_INVALID_PARAMETER); + for (i = 0; i < storage_parameter -> ux_slave_class_storage_parameter_number_lun; i ++) { if ((storage_parameter -> ux_slave_class_storage_parameter_lun[i]. From 6d351e0f09514e29fe0eae28203ebdd1c713b0e2 Mon Sep 17 00:00:00 2001 From: MAY Date: Thu, 5 Jun 2025 01:35:07 +0200 Subject: [PATCH 09/19] update vendor id from "AzureRTO" to "Eclipse " --- .../src/ux_device_class_storage_initialize.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c index 0ec29d8d..456e15c3 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c @@ -1,10 +1,10 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * Copyright (c) 2024 Microsoft Corporation + * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. - * + * * SPDX-License-Identifier: MIT **************************************************************************/ @@ -30,7 +30,7 @@ /* Define the Slave Storage Class Inquiry data : DO NOT CHANGE THE LENGTH OF THESE ITEMS */ -UCHAR _ux_system_slave_class_storage_vendor_id[] = "AzureRTO"; +UCHAR _ux_system_slave_class_storage_vendor_id[] = "Eclipse "; UCHAR _ux_system_slave_class_storage_product_id[] = "USBX storage dev"; UCHAR _ux_system_slave_class_storage_product_rev[] = "2000"; UCHAR _ux_system_slave_class_storage_product_serial[] = "12345678901234567890"; From ba88b318ff69a844f498c455cf259fe67f476590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Thu, 5 Jun 2025 11:45:52 -0400 Subject: [PATCH 10/19] Update ux_device_class_storage_initialize.c Tweaked the proposed new vendor id. --- .../src/ux_device_class_storage_initialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c index 456e15c3..5a77e1f7 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c @@ -30,7 +30,7 @@ /* Define the Slave Storage Class Inquiry data : DO NOT CHANGE THE LENGTH OF THESE ITEMS */ -UCHAR _ux_system_slave_class_storage_vendor_id[] = "Eclipse "; +UCHAR _ux_system_slave_class_storage_vendor_id[] = "Eclipse ThreadX"; UCHAR _ux_system_slave_class_storage_product_id[] = "USBX storage dev"; UCHAR _ux_system_slave_class_storage_product_rev[] = "2000"; UCHAR _ux_system_slave_class_storage_product_serial[] = "12345678901234567890"; From 655f1179483f3536e555652c164b06b2a4c48bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Tue, 10 Jun 2025 10:13:53 -0400 Subject: [PATCH 11/19] Reversed change to _ux_system_slave_class_storage_vendor_id The _ux_system_slave_class_storage_vendor_id in ux_device_class_storage_initialize.c had been changed to a value too large to fit given the constant's type. This commit reverts to a vendor_id with the appropriate length. --- .../src/ux_device_class_storage_initialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c index 7ad4a003..c6f393e0 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_initialize.c @@ -30,7 +30,7 @@ /* Define the Slave Storage Class Inquiry data : DO NOT CHANGE THE LENGTH OF THESE ITEMS */ -UCHAR _ux_system_slave_class_storage_vendor_id[] = "Eclipse ThreadX"; +UCHAR _ux_system_slave_class_storage_vendor_id[] = "Eclipse "; UCHAR _ux_system_slave_class_storage_product_id[] = "USBX storage dev"; UCHAR _ux_system_slave_class_storage_product_rev[] = "2000"; UCHAR _ux_system_slave_class_storage_product_serial[] = "12345678901234567890"; From e9ef4054f74158e9e4ad734e4f34b48b21b6b6de Mon Sep 17 00:00:00 2001 From: Haithem Rahmani Date: Tue, 2 Sep 2025 14:18:24 +0100 Subject: [PATCH 12/19] add bounds check for frequency array in audio streaming interface descriptor --- ..._host_class_audio_streaming_sampling_get.c | 183 ++++++++++++------ 1 file changed, 120 insertions(+), 63 deletions(-) diff --git a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c index bb3aefbb..04de8b3c 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c @@ -11,8 +11,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Audio Class */ /** */ @@ -29,48 +29,48 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_audio_streaming_sampling_get PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_streaming_sampling_get PORTABLE C */ /* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function obtains successive sampling characteristics for the */ -/* audio streaming channel. */ +/* */ +/* This function obtains successive sampling characteristics for the */ +/* audio streaming channel. */ /* */ /* Note only Audio 1.0 and RAW (PCM like) format is supported. */ -/* */ -/* INPUT */ -/* */ -/* audio Pointer to audio class */ -/* audio_sampling Pointer to audio sampling */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ -/* _ux_host_stack_class_instance_verify Verify instance is valid */ -/* _ux_utility_descriptor_parse Parse the descriptor */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* audio_sampling Pointer to audio sampling */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_stack_class_instance_verify Verify instance is valid */ +/* _ux_utility_descriptor_parse Parse the descriptor */ /* _ux_host_mutex_on Get mutex */ /* _ux_host_mutex_off Put mutex */ -/* */ -/* CALLED BY */ -/* */ -/* Application */ -/* Audio Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ @@ -101,13 +101,13 @@ ULONG lower_frequency; ULONG higher_frequency; UINT specific_frequency_count; UINT previous_match_found; - + /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_STREAMING_SAMPLING_GET, audio, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) /* Ensure the instance is valid. */ if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) - { + { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); @@ -127,18 +127,16 @@ UINT previous_match_found; /* Get the descriptor to the entire configuration. */ descriptor = audio -> ux_host_class_audio_configuration_descriptor; total_descriptor_length = audio -> ux_host_class_audio_configuration_descriptor_length; - - /* Default is Interface descriptor not yet found. */ + + /* Default is Interface descriptor not yet found. */ interface_found = UX_FALSE; - + /* Scan the descriptor for the Audio Streaming interface. */ while (total_descriptor_length) { /* Gather the length, type and subtype of the descriptor. */ descriptor_length = *descriptor; - descriptor_type = *(descriptor + 1); - descriptor_subtype = *(descriptor + 2); /* Make sure this descriptor has at least the minimum length. */ if (descriptor_length < 3) @@ -156,6 +154,9 @@ UINT previous_match_found; return(UX_DESCRIPTOR_CORRUPTED); } + descriptor_type = *(descriptor + 1); + descriptor_subtype = *(descriptor + 2); + /* Process relative to descriptor type. */ switch(descriptor_type) { @@ -180,7 +181,7 @@ UINT previous_match_found; interface_found = UX_FALSE; } break; - + case UX_HOST_CLASS_AUDIO_CS_INTERFACE: @@ -193,12 +194,12 @@ UINT previous_match_found; UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &audio_interface_descriptor); /* This descriptor must refer to a PCM audio type. */ - if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I) + if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I) break; /* If this is the first time we ask for a streaming interface characteristics we return the first we find. */ - if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_channels == 0) && + if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_channels == 0) && (audio_sampling -> ux_host_class_audio_sampling_characteristics_resolution == 0)) { @@ -207,24 +208,52 @@ UINT previous_match_found; if (audio_interface_descriptor.bSamFreqType == 0) { - + + if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 6)) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + return(UX_DESCRIPTOR_CORRUPTED); + } + /* The declaration of frequency is contiguous, so get the minimum and maximum */ - audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low = + audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low = (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; - audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high = + audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_high = (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 + 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. + if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (3 * audio_interface_descriptor.bSamFreqType))) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + return(UX_DESCRIPTOR_CORRUPTED); + } + + /* The declaration of the frequency is declared as an array of specific values. We take the first one here. */ - audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low = + audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low = (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; @@ -248,16 +277,30 @@ UINT previous_match_found; (audio_sampling -> ux_host_class_audio_sampling_characteristics_resolution == audio_interface_descriptor.bBitResolution)) { - if (audio_interface_descriptor.bSamFreqType == 0) - { - + if (audio_interface_descriptor.bSamFreqType == 0) + { + + if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 6)) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + return(UX_DESCRIPTOR_CORRUPTED); + } + /* 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 + 4)) << 8 | ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16; if ((audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low == lower_frequency) && @@ -272,6 +315,20 @@ UINT previous_match_found; else { + if (descriptor_length < UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (3 * audio_interface_descriptor.bSamFreqType)) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* Unprotect thread reentry to this instance. */ + _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); + + return(UX_DESCRIPTOR_CORRUPTED); + } + /* 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++) { @@ -283,7 +340,7 @@ UINT previous_match_found; /* Compare the frequency. */ if (audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low == lower_frequency) { - + previous_match_found = UX_TRUE; } else @@ -306,7 +363,7 @@ UINT previous_match_found; /* Return successful completion. */ return(UX_SUCCESS); } - } + } } } } @@ -325,14 +382,14 @@ UINT previous_match_found; 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 + 4)) << 8 | ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16; audio_sampling -> ux_host_class_audio_sampling_characteristics_frequency_low = lower_frequency; @@ -344,7 +401,7 @@ UINT previous_match_found; /* Return successful completion. */ return(UX_SUCCESS); } - else + else { lower_frequency = (ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH) | @@ -362,9 +419,9 @@ UINT previous_match_found; } } } - } + } } - } + } /* Verify the descriptor is still valid. */ if (descriptor_length > total_descriptor_length) @@ -421,8 +478,8 @@ UINT previous_match_found; /* */ /* INPUT */ /* */ -/* audio Pointer to audio class */ -/* audio_sampling Pointer to audio sampling */ +/* audio Pointer to audio class */ +/* audio_sampling Pointer to audio sampling */ /* */ /* OUTPUT */ /* */ From 28ca9dd60086d00ae5d4c1bc7aadb0ea8db2ff08 Mon Sep 17 00:00:00 2001 From: Haithem Rahmani Date: Tue, 2 Sep 2025 14:42:58 +0100 Subject: [PATCH 13/19] add bounds checks for sampling frequency type to identify the right alternate setting --- ...ost_class_audio_alternate_setting_locate.c | 117 ++++++++++-------- 1 file changed, 68 insertions(+), 49 deletions(-) diff --git a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c index eb9cc4bb..5b4e4946 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c @@ -11,8 +11,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Audio Class */ /** */ @@ -37,44 +37,44 @@ static inline UINT _ux_host_class_audio_alternate_setting_locate_2( #endif -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_audio_alternate_setting_locate PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_audio_alternate_setting_locate PORTABLE C */ /* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This function finds the right alternate setting according to the */ -/* sampling desired. */ -/* */ -/* INPUT */ -/* */ -/* audio Pointer to audio class */ -/* audio_sampling Pointer to audio sampling */ -/* alternate_setting Pointer to located alternate */ -/* setting */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ -/* _ux_utility_descriptor_parse Parse descriptor */ -/* */ -/* CALLED BY */ -/* */ -/* Audio Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* sampling desired. */ +/* */ +/* INPUT */ +/* */ +/* audio Pointer to audio class */ +/* audio_sampling Pointer to audio sampling */ +/* alternate_setting Pointer to located alternate */ +/* setting */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_utility_descriptor_parse Parse descriptor */ +/* */ +/* CALLED BY */ +/* */ +/* Audio Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ @@ -101,23 +101,21 @@ UINT interface_found; ULONG lower_frequency; ULONG higher_frequency; UINT specific_frequency_count; - + /* Get the descriptor to the entire configuration. */ descriptor = audio -> ux_host_class_audio_configuration_descriptor; total_descriptor_length = audio -> ux_host_class_audio_configuration_descriptor_length; - - /* Default is Interface descriptor not yet found. */ + + /* Default is Interface descriptor not yet found. */ interface_found = UX_FALSE; - + /* Scan the descriptor for the Audio Streaming interface. */ while (total_descriptor_length) { /* Gather the length, type and subtype of the descriptor. */ descriptor_length = *descriptor; - descriptor_type = *(descriptor + 1); - descriptor_subtype = *(descriptor + 2); /* Make sure this descriptor has at least the minimum length. */ if (descriptor_length < 3) @@ -131,6 +129,10 @@ UINT specific_frequency_count; return(UX_DESCRIPTOR_CORRUPTED); } + + descriptor_type = *(descriptor + 1); + descriptor_subtype = *(descriptor + 2); + /* Process relative to descriptor type. */ switch (descriptor_type) { @@ -149,7 +151,7 @@ UINT specific_frequency_count; /* Mark we have found it. */ interface_found = UX_TRUE; - + /* And memorize the alternate setting. */ *alternate_setting = interface_descriptor.bAlternateSetting; } @@ -160,8 +162,8 @@ UINT specific_frequency_count; interface_found = UX_FALSE; } break; - - + + case UX_HOST_CLASS_AUDIO_CS_INTERFACE: /* First make sure we have found the correct generic interface descriptor. */ @@ -173,7 +175,7 @@ UINT specific_frequency_count; UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &audio_interface_descriptor); /* This descriptor must refer to a PCM audio type. */ - if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I) + if (audio_interface_descriptor.bFormatType != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I) break; /* The number of channels demanded by the application must match. */ @@ -188,18 +190,30 @@ UINT specific_frequency_count; as a min and max frequency or an array of specified values. */ if (audio_interface_descriptor.bSamFreqType == 0) { - + + if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 6)) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_DESCRIPTOR_CORRUPTED); + } + /* 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 + 4)) << 8 | ((ULONG) *(descriptor + UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + 5)) << 16; /* Now compare with what is required. */ - if ((audio_sampling -> ux_host_class_audio_sampling_frequency >= lower_frequency) && + if ((audio_sampling -> ux_host_class_audio_sampling_frequency >= lower_frequency) && (audio_sampling -> ux_host_class_audio_sampling_frequency <= higher_frequency)) { @@ -211,6 +225,11 @@ UINT specific_frequency_count; else { + if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (3 * audio_interface_descriptor.bSamFreqType))) + { + return(UX_DESCRIPTOR_CORRUPTED); + } + /* 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++) @@ -229,10 +248,10 @@ UINT specific_frequency_count; return(UX_SUCCESS); } } - } + } } break; - } + } /* Verify if the descriptor is still valid. */ if (descriptor_length > total_descriptor_length) @@ -243,7 +262,7 @@ UINT specific_frequency_count; return(UX_DESCRIPTOR_CORRUPTED); } - + /* Jump to the next descriptor if we have not reached the end. */ descriptor += descriptor_length; From c2d43622da907936d918ce2efb3046bc550ff240 Mon Sep 17 00:00:00 2001 From: MAY Date: Thu, 11 Sep 2025 22:35:25 +0200 Subject: [PATCH 14/19] fix ux_system_initialize error checking flag --- common/core/inc/ux_api.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h index 5f5feba5..fdb12065 100644 --- a/common/core/inc/ux_api.h +++ b/common/core/inc/ux_api.h @@ -2747,9 +2747,9 @@ typedef struct UX_HOST_CLASS_DPUMP_STRUCT /* Define USBX Services. */ #if defined(UX_SYSTEM_ENABLE_ERROR_CHECKING) -#define ux_system_initialize _ux_system_initialize -#else #define ux_system_initialize _uxe_system_initialize +#else +#define ux_system_initialize _ux_system_initialize #endif #define ux_system_uninitialize _ux_system_uninitialize From 0b246ac82490441daa615aa90ab88a4456219c58 Mon Sep 17 00:00:00 2001 From: Haithem Rahmani Date: Mon, 15 Sep 2025 17:54:05 +0100 Subject: [PATCH 15/19] Add bounds check for HID report item parsing --- .../ux_host_class_hid_report_descriptor_get.c | 104 +++++++++++------- 1 file changed, 62 insertions(+), 42 deletions(-) diff --git a/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c b/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c index d112510a..2e52ba24 100644 --- a/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c +++ b/common/usbx_host_classes/src/ux_host_class_hid_report_descriptor_get.c @@ -11,8 +11,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** HID Class */ /** */ @@ -29,47 +29,47 @@ #include "ux_host_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_host_class_hid_report_descriptor_get PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_hid_report_descriptor_get PORTABLE C */ /* 6.1 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function gets the report descriptor and analyzes it. */ -/* */ -/* INPUT */ -/* */ -/* hid Pointer to HID class */ -/* length Length of descriptor */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ -/* _ux_host_class_hid_global_item_parse Parse global item */ -/* _ux_host_class_hid_local_item_parse Parse local item */ -/* _ux_host_class_hid_report_item_analyse Analyze report */ -/* _ux_host_class_hid_resources_free Free HID resources */ -/* _ux_host_stack_transfer_request Process transfer request */ -/* _ux_utility_memory_allocate Allocate memory block */ -/* _ux_utility_memory_free Release memory block */ -/* */ -/* CALLED BY */ -/* */ -/* HID Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* This function gets the report descriptor and analyzes it. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* length Length of descriptor */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_host_class_hid_global_item_parse Parse global item */ +/* _ux_host_class_hid_local_item_parse Parse local item */ +/* _ux_host_class_hid_report_item_analyse Analyze report */ +/* _ux_host_class_hid_resources_free Free HID resources */ +/* _ux_host_stack_transfer_request Process transfer request */ +/* _ux_utility_memory_allocate Allocate memory block */ +/* _ux_utility_memory_free Release memory block */ +/* */ +/* CALLED BY */ +/* */ +/* HID Class */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ @@ -117,6 +117,20 @@ UINT status; while (length) { + /* Make sure this descriptor has at least the minimum length. */ + if(length < 3) + { + + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + /* Return error status. */ + status = (UX_DESCRIPTOR_CORRUPTED); + } + /* Get one item from the report and analyze it. */ _ux_host_class_hid_report_item_analyse(descriptor, &item); @@ -133,7 +147,7 @@ UINT status; status = _ux_host_class_hid_global_item_parse(hid, &item, descriptor); break; - + case UX_HOST_CLASS_HID_TYPE_MAIN: /* This is a main item. */ @@ -145,13 +159,13 @@ UINT status; /* This is a local item. */ status = _ux_host_class_hid_local_item_parse(hid, &item, descriptor); - break; + break; default: /* This is a reserved item, meaning it shouldn't be used! */ - /* Set status to error. The check after this switch statement + /* Set status to error. The check after this switch statement will handle the rest. */ status = UX_DESCRIPTOR_CORRUPTED; break; @@ -165,11 +179,17 @@ UINT status; /* Jump to the next item. */ descriptor += item.ux_host_class_hid_item_report_length; - + /* Verify that the report descriptor is not corrupted. */ - if (length < item.ux_host_class_hid_item_report_length) + if (length < (item.ux_host_class_hid_item_report_length + item.ux_host_class_hid_item_report_format)) { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + /* Return error status. */ status = (UX_DESCRIPTOR_CORRUPTED); break; From 50882b4f71a581ffd611048708ee24997f572acf Mon Sep 17 00:00:00 2001 From: Haithem Rahmani Date: Mon, 15 Sep 2025 17:58:55 +0100 Subject: [PATCH 16/19] Add bounds check for sampling frequency in audio descriptor parsing --- .../ux_host_class_audio_descriptors_parse.c | 8 +- .../ux_host_class_audio_raw_sampling_parse.c | 73 ++++++++++++++++++- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c b/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c index 6db04dc3..3b4aebdb 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_descriptors_parse.c @@ -102,7 +102,7 @@ UINT status; /* Ensure the instance is valid. */ if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) - { + { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); @@ -134,12 +134,13 @@ UINT status; /* Gather the length, type and subtype of the descriptor. */ descriptor_length = *descriptor; - descriptor_type = *(descriptor + 1); - /* Make sure this descriptor has at least the minimum length. */ + /* Make sure this descriptor has at least the minimum length. */ if (descriptor_length < 3) return(UX_DESCRIPTOR_CORRUPTED); + descriptor_type = *(descriptor + 1); + /* Process relative to descriptor type. */ switch (descriptor_type) { @@ -173,7 +174,6 @@ UINT status; /* Have we found the audio interface yet? */ if (interface_descriptor != UX_NULL) { - /* Yes, parse the audio specific descriptor. */ status = parse_function(arg, interface_descriptor, endpoint_descriptor, descriptor); diff --git a/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c index ff0fd9a7..73a83fd9 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c @@ -161,6 +161,7 @@ struct UX_HOST_CLASS_AUDIO10_SAM_PARSER *parser = (struct UX_HOST_CLAS UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr; ULONG n, offset; UINT status; +UINT descriptor_length = packed_audio_descriptor[0]; UX_PARAMETER_NOT_USED(packed_endpoint_descriptor); @@ -178,10 +179,32 @@ UINT status; if (packed_audio_descriptor[2] != UX_HOST_CLASS_AUDIO_CS_FORMAT_TYPE) return(0); + if (descriptor_length < 4) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_DESCRIPTOR_CORRUPTED); + } + /* Check bFormatType @ 3. */ if (packed_audio_descriptor[3] != UX_HOST_CLASS_AUDIO_FORMAT_TYPE_I) return(0); + if (descriptor_length < 8) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_DESCRIPTOR_CORRUPTED); + } + /* Get bNrChannels @ 4. */ sam_attr.ux_host_class_audio_sampling_characteristics_channels = packed_audio_descriptor[4]; @@ -196,6 +219,16 @@ UINT status; /* Check bSamFreqType @ 7. */ if (packed_audio_descriptor[7] == 0) { + if (descriptor_length < 14) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_DESCRIPTOR_CORRUPTED); + } /* Continuous, get dLowSamFreq and dHighSamFreq. */ sam_attr.ux_host_class_audio_sampling_characteristics_frequency_low = @@ -213,6 +246,16 @@ UINT status; } else { + if (descriptor_length < (8 + (3 * packed_audio_descriptor[7]))) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(UX_DESCRIPTOR_CORRUPTED); + } /* Parse list of sampling characteristics. */ for (n = 0, offset = 8; @@ -271,6 +314,7 @@ static UINT _ux_host_class_audio_ac_find_parse(VOID *arg, UCHAR *packed_audio_descriptor) { struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *finder = (struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *)arg; +UINT descriptor_length = packed_audio_descriptor[0]; UX_PARAMETER_NOT_USED(packed_endpoint_descriptor); @@ -289,6 +333,17 @@ struct UX_HOST_CLASS_AUDIO_AC_DESCR_FINDER_STRUCT *finder = (struct UX_HOST_CLAS if (packed_audio_descriptor[2] != finder -> subtype) return(0); + if (descriptor_length < 4) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + return(0); + } + /* Check bEntityID @ 3. */ if (packed_audio_descriptor[3] != finder -> id) return(0); @@ -332,7 +387,7 @@ UINT status; if (audio -> ux_host_class_audio_type == UX_HOST_CLASS_AUDIO_INPUT) { - + /* If audio input, streaming is from output terminal (OT). */ descriptor = _ux_host_class_audio_ac_find(audio, UX_CLASS_AUDIO20_AC_OUTPUT_TERMINAL, @@ -546,6 +601,7 @@ UX_TRANSFER *transfer; UCHAR *buffer; ULONG n_sub, param_len, offset; UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr; +UINT descriptor_length = packed_audio_descriptor[0]; UX_PARAMETER_NOT_USED(packed_endpoint_descriptor); @@ -571,6 +627,19 @@ UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr; /* Check bDescriptorSubType@2, bFormatType@3 to confirm FORMAT_TYPE_I. */ if (packed_audio_descriptor[2] != UX_CLASS_AUDIO20_AS_FORMAT_TYPE) return(0); + + if (descriptor_length < 6) + { + /* Error trap. */ + _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0) + + parser -> status = UX_DESCRIPTOR_CORRUPTED; + return(1); + } + if (packed_audio_descriptor[3] != UX_CLASS_AUDIO20_FORMAT_TYPE_I) return(0); @@ -654,7 +723,7 @@ UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS sam_attr; parser -> status = UX_MATH_OVERFLOW; return(1); } - + /* Allocate buffer for GET_RANGE. */ buffer = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, param_len); if (buffer == UX_NULL) From 6feddf9b35ba57441bda4e0b2baaf2d68edbf8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Mon, 29 Sep 2025 19:56:14 +0100 Subject: [PATCH 17/19] Updated version number and added build number and hotfix. --- common/core/inc/ux_api.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h index 5f5feba5..635acea1 100644 --- a/common/core/inc/ux_api.h +++ b/common/core/inc/ux_api.h @@ -348,7 +348,9 @@ typedef signed char SCHAR; #define AZURE_RTOS_USBX #define USBX_MAJOR_VERSION 6 #define USBX_MINOR_VERSION 4 -#define USBX_PATCH_VERSION 2 +#define USBX_PATCH_VERSION 3 +#define USBX_BUILD_VERSION 202503 +#define USBX_HOTFIX_VERSION '' /* Macros for concatenating tokens, where UX_CONCATn concatenates n tokens. */ From 3770e71f132b0537ecc9ea8f5303006a74bc0ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Mon, 29 Sep 2025 23:08:42 +0100 Subject: [PATCH 18/19] Fixed integer comparisons of different signedness. --- .../src/ux_host_class_audio_alternate_setting_locate.c | 2 +- .../src/ux_host_class_audio_raw_sampling_parse.c | 2 +- .../src/ux_host_class_audio_streaming_sampling_get.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c index 5b4e4946..f93505dc 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_alternate_setting_locate.c @@ -225,7 +225,7 @@ UINT specific_frequency_count; else { - if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (3 * audio_interface_descriptor.bSamFreqType))) + if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (UINT)(3 * audio_interface_descriptor.bSamFreqType))) { return(UX_DESCRIPTOR_CORRUPTED); } diff --git a/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c index 73a83fd9..0a850bd3 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_raw_sampling_parse.c @@ -246,7 +246,7 @@ UINT descriptor_length = packed_audio_descriptor[0]; } else { - if (descriptor_length < (8 + (3 * packed_audio_descriptor[7]))) + if (descriptor_length < (UINT)(8 + (3 * packed_audio_descriptor[7]))) { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); diff --git a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c index 04de8b3c..9cd2025e 100644 --- a/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c +++ b/common/usbx_host_classes/src/ux_host_class_audio_streaming_sampling_get.c @@ -237,7 +237,7 @@ UINT previous_match_found; else { - if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (3 * audio_interface_descriptor.bSamFreqType))) + if (descriptor_length < (UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (UINT)(3 * audio_interface_descriptor.bSamFreqType))) { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); @@ -315,7 +315,7 @@ UINT previous_match_found; else { - if (descriptor_length < UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (3 * audio_interface_descriptor.bSamFreqType)) + if (descriptor_length < UX_HOST_CLASS_AUDIO_INTERFACE_DESCRIPTOR_LENGTH + (UINT)(3 * audio_interface_descriptor.bSamFreqType)) { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED); From d7dc572bceb01c03ce1fb78a0d4aab887940cde8 Mon Sep 17 00:00:00 2001 From: MAY Date: Wed, 1 Oct 2025 01:10:20 +0200 Subject: [PATCH 19/19] add an additional safeguard for optional out endpoint --- .../src/ux_device_class_hid_deactivate.c | 83 +++++++++++-------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c index cf414049..0313d847 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_deactivate.c @@ -1,17 +1,17 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * Copyright (c) 2024 Microsoft Corporation + * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. - * + * * SPDX-License-Identifier: MIT **************************************************************************/ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -28,40 +28,40 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_deactivate PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_deactivate PORTABLE C */ /* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function deactivate an instance of the hid class. */ -/* */ -/* INPUT */ -/* */ -/* command Pointer to a class command */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ -/* _ux_device_stack_transfer_all_request_abort Abort all transfers */ -/* */ -/* CALLED BY */ -/* */ +/* */ +/* This function deactivate an instance of the hid class. */ +/* */ +/* INPUT */ +/* */ +/* command Pointer to a class command */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ +/* _ux_device_stack_transfer_all_request_abort Abort all transfers */ +/* */ +/* CALLED BY */ +/* */ /* HID Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ @@ -73,9 +73,10 @@ /**************************************************************************/ UINT _ux_device_class_hid_deactivate(UX_SLAVE_CLASS_COMMAND *command) { - + UX_SLAVE_CLASS_HID *hid; UX_SLAVE_CLASS *class_ptr; +UX_SLAVE_ENDPOINT *endpoint; /* Get the class container. */ class_ptr = command -> ux_slave_class_command_class_ptr; @@ -83,11 +84,21 @@ UX_SLAVE_CLASS *class_ptr; /* Get the class instance in the container. */ hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; - /* Terminate the transactions pending on the endpoints. */ - _ux_device_stack_transfer_all_request_abort(hid -> ux_device_class_hid_interrupt_endpoint, UX_TRANSFER_BUS_RESET); + /* Locate the interrupt in endpoint. */ + endpoint = hid -> ux_device_class_hid_interrupt_endpoint; + + /* Terminate the transactions pending on the endpoint. */ + if (endpoint) + _ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET); #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT) - _ux_device_stack_transfer_all_request_abort(hid -> ux_device_class_hid_read_endpoint, UX_TRANSFER_BUS_RESET); + + /* Locate the interrupt out endpoint. */ + endpoint = hid -> ux_device_class_hid_interrupt_endpoint; + + /* Terminate the transactions pending on the endpoint. */ + if (endpoint) + _ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET); #endif /* If there is a deactivate function call it. */