diff options
| author | Frédéric Desbiens <[email protected]> | 2026-01-12 16:20:23 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-12 16:20:23 -0500 |
| commit | 9b7a63e2c16292bfae6139b7331eca75ce6c8f6f (patch) | |
| tree | 0521ef1d36fe5774997ac90d47778cfa50be5389 | |
| parent | 95b554ad53b4505ee7629b6677259997b5ed2bf5 (diff) | |
| parent | d562e7a0a6d29db105d5301edc34df6b63a6ba87 (diff) | |
Merge commit from fork
fix (host/storage): prevent stack overflow from infinite partition recursion
21 files changed, 115 insertions, 31 deletions
diff --git a/common/usbx_host_classes/inc/ux_host_class_storage.h b/common/usbx_host_classes/inc/ux_host_class_storage.h index 4c85a2a..c54c8ed 100644 --- a/common/usbx_host_classes/inc/ux_host_class_storage.h +++ b/common/usbx_host_classes/inc/ux_host_class_storage.h @@ -486,6 +486,8 @@ typedef struct UX_HOST_CLASS_STORAGE_STRUCT UINT ux_host_class_storage_lun_types[UX_MAX_HOST_LUN]; #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX) ULONG ux_host_class_storage_last_sector_number; +#else + ULONG ux_host_class_storage_mounted_partitions_count; #endif ULONG ux_host_class_storage_sector_size; ULONG ux_host_class_storage_data_phase_length; diff --git a/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c b/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c index d1aa9c8..373a8a0 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_device_initialize.c @@ -166,6 +166,12 @@ UINT inst_index; case UX_HOST_CLASS_STORAGE_MEDIA_IOMEGA_CLICK: #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) + /* the ux_host_class_storage_mounted_partitions_count is needed to avoid + infinite recursive loops when mounting extended partions. + The value is checked against the UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT + */ + storage -> ux_host_class_storage_mounted_partitions_count = 0; + /* Try to read the device media in search for a partition table or boot sector. We are at the root of the disk, so use sector 0 as the starting point. */ _ux_host_class_storage_media_mount(storage, 0); diff --git a/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c b/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c index d70e3a6..4f86b28 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c @@ -27,8 +27,6 @@ #include "ux_api.h" #include "ux_host_class_storage.h" #include "ux_host_stack.h" - - /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -90,49 +88,55 @@ UINT _ux_host_class_storage_partition_read(UX_HOST_CLASS_STORAGE *storage, UCHA UINT status = UX_ERROR; UINT partition_index; + /* Check recursion/mount count before processing. */ + if (storage -> ux_host_class_storage_mounted_partitions_count > UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT) + { + return UX_HOST_CLASS_STORAGE_ERROR_MEDIA_NOT_READ; + } /* Point the sector buffer to the first partition entry. */ sector_memory += UX_HOST_CLASS_STORAGE_PARTITION_TABLE_START; - + /* There are 4 partitions in a partition table. */ for (partition_index = 0; partition_index < 4; partition_index++) { + /* Increment the mounted partition count for every entry processed. */ + storage -> ux_host_class_storage_mounted_partitions_count++; + + /* Check again after incrementing. */ + if (storage -> ux_host_class_storage_mounted_partitions_count > UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT) + { + /* Too many partition entries processed, abort to prevent stack overflow. */ + return UX_HOST_CLASS_STORAGE_ERROR_MEDIA_NOT_READ; + } /* Check if we recognize this partition entry. */ switch(*(sector_memory + UX_HOST_CLASS_STORAGE_PARTITION_TYPE)) { - - case UX_HOST_CLASS_STORAGE_PARTITION_FAT_12: - case UX_HOST_CLASS_STORAGE_PARTITION_FAT_16: - case UX_HOST_CLASS_STORAGE_PARTITION_FAT_16L: - case UX_HOST_CLASS_STORAGE_PARTITION_FAT_16_LBA_MAPPED: - case UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_1: - case UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_2: - case UX_HOST_CLASS_STORAGE_PARTITION_EXFAT: - - /* We have found a legal partition entry pointing to a potential boot sector. */ - status = _ux_host_class_storage_media_open(storage, sector + _ux_utility_long_get(sector_memory + UX_HOST_CLASS_STORAGE_PARTITION_SECTORS_BEFORE)); - break; - - case UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED: - case UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED_LBA_MAPPED: - - /* We have found an entry to an extended partition. We need to read that partition sector - and recursively mount all partitions found. */ - status = _ux_host_class_storage_media_mount(storage, sector + _ux_utility_long_get(sector_memory + UX_HOST_CLASS_STORAGE_PARTITION_SECTORS_BEFORE)); - break; - - default: - - /* We have found something which is not a DOS recognized partition, or an empty entry. - Ignore it and proceed with the rest. */ - break; + case UX_HOST_CLASS_STORAGE_PARTITION_FAT_12: + case UX_HOST_CLASS_STORAGE_PARTITION_FAT_16: + case UX_HOST_CLASS_STORAGE_PARTITION_FAT_16L: + case UX_HOST_CLASS_STORAGE_PARTITION_FAT_16_LBA_MAPPED: + case UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_1: + case UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_2: + case UX_HOST_CLASS_STORAGE_PARTITION_EXFAT: + /* We have found a legal partition entry pointing to a potential boot sector. */ + status = _ux_host_class_storage_media_open(storage, sector + _ux_utility_long_get(sector_memory + UX_HOST_CLASS_STORAGE_PARTITION_SECTORS_BEFORE)); + break; + case UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED: + case UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED_LBA_MAPPED: + /* We have found an entry to an extended partition. We need to read that partition sector + and recursively mount all partitions found. */ + status = _ux_host_class_storage_media_mount(storage, sector + _ux_utility_long_get(sector_memory + UX_HOST_CLASS_STORAGE_PARTITION_SECTORS_BEFORE)); + break; + default: + /* We have found something which is not a DOS recognized partition, or an empty entry. + Ignore it and proceed with the rest. */ + break; } - /* Move to the next partition entry. */ sector_memory += UX_HOST_CLASS_STORAGE_PARTITION_TABLE_SIZE; } - /* Return completion status. */ return(status); #endif diff --git a/ports/arm9/iar/inc/ux_port.h b/ports/arm9/iar/inc/ux_port.h index 32be4e7..061cede 100644 --- a/ports/arm9/iar/inc/ux_port.h +++ b/ports/arm9/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a5/gnu/inc/ux_port.h b/ports/cortex_a5/gnu/inc/ux_port.h index f5e6296..bf4435c 100644 --- a/ports/cortex_a5/gnu/inc/ux_port.h +++ b/ports/cortex_a5/gnu/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a5/iar/inc/ux_port.h b/ports/cortex_a5/iar/inc/ux_port.h index f760c8a..c03566e 100644 --- a/ports/cortex_a5/iar/inc/ux_port.h +++ b/ports/cortex_a5/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a7/gnu/inc/ux_port.h b/ports/cortex_a7/gnu/inc/ux_port.h index f5094ba..53016d5 100644 --- a/ports/cortex_a7/gnu/inc/ux_port.h +++ b/ports/cortex_a7/gnu/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a7/iar/inc/ux_port.h b/ports/cortex_a7/iar/inc/ux_port.h index c23ce61..98d9089 100644 --- a/ports/cortex_a7/iar/inc/ux_port.h +++ b/ports/cortex_a7/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a8/gnu/inc/ux_port.h b/ports/cortex_a8/gnu/inc/ux_port.h index d9e90b5..de0b53f 100644 --- a/ports/cortex_a8/gnu/inc/ux_port.h +++ b/ports/cortex_a8/gnu/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a8/iar/inc/ux_port.h b/ports/cortex_a8/iar/inc/ux_port.h index dbce55c..5e580f6 100644 --- a/ports/cortex_a8/iar/inc/ux_port.h +++ b/ports/cortex_a8/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a9/gnu/inc/ux_port.h b/ports/cortex_a9/gnu/inc/ux_port.h index 3294109..4515b3b 100644 --- a/ports/cortex_a9/gnu/inc/ux_port.h +++ b/ports/cortex_a9/gnu/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_a9/iar/inc/ux_port.h b/ports/cortex_a9/iar/inc/ux_port.h index 4b5b6e3..5c9e2f2 100644 --- a/ports/cortex_a9/iar/inc/ux_port.h +++ b/ports/cortex_a9/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_m4/gnu/inc/ux_port.h b/ports/cortex_m4/gnu/inc/ux_port.h index 4cdc025..199f01d 100644 --- a/ports/cortex_m4/gnu/inc/ux_port.h +++ b/ports/cortex_m4/gnu/inc/ux_port.h @@ -206,6 +206,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_m4/iar/inc/ux_port.h b/ports/cortex_m4/iar/inc/ux_port.h index b3a7b6f..4554a1b 100644 --- a/ports/cortex_m4/iar/inc/ux_port.h +++ b/ports/cortex_m4/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_m7/gnu/inc/ux_port.h b/ports/cortex_m7/gnu/inc/ux_port.h index b71a219..badf444 100644 --- a/ports/cortex_m7/gnu/inc/ux_port.h +++ b/ports/cortex_m7/gnu/inc/ux_port.h @@ -206,6 +206,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_m7/iar/inc/ux_port.h b/ports/cortex_m7/iar/inc/ux_port.h index d2ac860..6c36c82 100644 --- a/ports/cortex_m7/iar/inc/ux_port.h +++ b/ports/cortex_m7/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_r4/gnu/inc/ux_port.h b/ports/cortex_r4/gnu/inc/ux_port.h index b1497c6..47b999a 100644 --- a/ports/cortex_r4/gnu/inc/ux_port.h +++ b/ports/cortex_r4/gnu/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_r4/iar/inc/ux_port.h b/ports/cortex_r4/iar/inc/ux_port.h index b512ba5..6b18f7b 100644 --- a/ports/cortex_r4/iar/inc/ux_port.h +++ b/ports/cortex_r4/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_r5/gnu/inc/ux_port.h b/ports/cortex_r5/gnu/inc/ux_port.h index 352b191..19385d5 100644 --- a/ports/cortex_r5/gnu/inc/ux_port.h +++ b/ports/cortex_r5/gnu/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/cortex_r5/iar/inc/ux_port.h b/ports/cortex_r5/iar/inc/ux_port.h index 483c745..29b7619 100644 --- a/ports/cortex_r5/iar/inc/ux_port.h +++ b/ports/cortex_r5/iar/inc/ux_port.h @@ -204,6 +204,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif diff --git a/ports/linux/gnu/inc/ux_port.h b/ports/linux/gnu/inc/ux_port.h index 25d3bc3..fe455cf 100644 --- a/ports/linux/gnu/inc/ux_port.h +++ b/ports/linux/gnu/inc/ux_port.h @@ -210,6 +210,10 @@ typedef LONG SLONG; #define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 #endif +#ifndef UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT +#define UX_HOST_CLASS_STORAGE_MAX_PARTITIONS_COUNT 8 +#endif + #ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 #endif |
