GHSA-qfmp-wch9-rpv2: Unbounded recursion in _ux_host_class_storage_media_mount() via extended partition chains

GHSA ID

GHSA‑qfmp‑wch9‑rpv2

CVE ID

CVE‑2025‑55095

Severity

Medium

CVSS score

4.2 (CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:L)

CWE

CWE-121, CWE-674

Published

2026‑01‑23

Last updated

2026‑01‑23

Affected packages

Package Vulnerable versions Patched versions

USBX

⇐ 6.4.2

6.4.5

Description

The function _ux_host_class_storage_media_mount() is responsible for mounting partitions on a USB mass storage device. When it encounters an extended partition entry in the partition table, it recursively calls itself to mount the next logical partition.

This recursion occurs in _ux_host_class_storage_partition_read(), which parses up to four partition entries. If an extended partition is found (with type UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED or EXTENDED_LBA_MAPPED), the code invokes:

_ux_host_class_storage_media_mount(storage, sector + _ux_utility_long_get(...));

There is no limit on the recursion depth or tracking of visited sectors. As a result, a malicious or malformed disk image can include cyclic or excessively deep chains of extended partitions, causing the function to recurse until stack overflow occurs.

Code:

UINT  _ux_host_class_storage_media_mount(UX_HOST_CLASS_STORAGE *storage, ULONG sector)

{

...

    sector_memory =  _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, storage -> ux_host_class_storage_sector_size);

...

        status =  _ux_host_class_storage_media_read(storage, sector, 1, sector_memory);

...

    if (_ux_utility_short_get(sector_memory + 510) == UX_HOST_CLASS_STORAGE_PARTITION_SIGNATURE)

    {

...

        _ux_host_class_storage_partition_read(storage, sector_memory, sector);

...

    }

}



UINT  _ux_host_class_storage_partition_read(UX_HOST_CLASS_STORAGE *storage, UCHAR *sector_memory, ULONG sector)

{

...

    sector_memory +=  UX_HOST_CLASS_STORAGE_PARTITION_TABLE_START;

...

    for (partition_index = 0; partition_index < 4; partition_index++)

    {

...

        switch(*(sector_memory + UX_HOST_CLASS_STORAGE_PARTITION_TYPE))

        {

...

        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;

...

        }



        /* Move to the next partition entry.  */

        sector_memory +=  UX_HOST_CLASS_STORAGE_PARTITION_TABLE_SIZE;

    }

...

}