Skip to content

Integer wraparounds, under-allocations, and heap buffer overflows in Eclipse ThreadX xQueueCreate() and xQueueCreateSet()

High
mrybczyn published GHSA-v9jj-7qjg-h6g6 Mar 26, 2024

Package

Eclipse ThreadX (custom)

Affected versions

< 6.4.0

Patched versions

6.4.0

Description

Short description

In Eclipse ThreadX before 6.4.0, xQueueCreate() and xQueueCreateSet() functions from the FreeRTOS compatibility API (utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c) were missing parameter checks. This could lead to integer wraparound, under-allocations and heap buffer overflows.

Impact

A researcher spotted the following in https://github.com/azure-rtos/threadx/blob/master/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c#L1534-L1536 and
https://github.com/azure-rtos/threadx/blob/master/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c#L2700-L2701

If an attacker can control uxQueueLength or uxItemSize, they can cause an integer wraparound thus causing txfr_malloc() to allocate a small amount of memory, exposing to subsequent heap buffer overflows:

QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize)
{
    txfr_queue_t *p_queue;
    void *p_mem;
    size_t mem_size;
    UINT ret;

    configASSERT(uxQueueLength != 0u);
    configASSERT(uxItemSize >= sizeof(UINT));

#if (TX_FREERTOS_AUTO_INIT == 1)
    if(txfr_initialized != 1u) {
        tx_freertos_auto_init();
    }
#endif

    p_queue = txfr_malloc(sizeof(txfr_queue_t));
    if(p_queue == NULL) {
        return NULL;
    }

    mem_size = uxQueueLength*(uxItemSize);

    p_mem = txfr_malloc(mem_size); // VULN: integer wraparound and under-allocation
    if(p_mem == NULL) {
        txfr_free(p_queue);
        return NULL;
    }

    TX_MEMSET(p_mem, 0, mem_size);
    TX_MEMSET(p_queue, 0, sizeof(*p_queue));
    p_queue->allocated = 1u;
    p_queue->p_mem = p_mem;
    p_queue->id = TX_QUEUE_ID;

    p_queue->p_write = (uint8_t *)p_mem;
    p_queue->p_read = (uint8_t *)p_mem;
    p_queue->msg_size = uxItemSize;
    p_queue->queue_length = uxQueueLength;

    ret = tx_semaphore_create(&p_queue->read_sem, "", 0u);
    if(ret != TX_SUCCESS) {
        return NULL;
    }

    ret = tx_semaphore_create(&p_queue->write_sem, "", uxQueueLength);
    if(ret != TX_SUCCESS) {
        return NULL;
    }

    return p_queue;
}

If an attacker can control uxEventQueueLength, they can cause an integer wraparound thus causing txfr_malloc() to allocate a small amount of memory, exposing to subsequent heap buffer overflows:

QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength)
{
    txfr_queueset_t *p_set;
    void *p_mem;
    ULONG queue_size;
    UINT ret;

    configASSERT(uxEventQueueLength != 0u);

#if (TX_FREERTOS_AUTO_INIT == 1)
    if(txfr_initialized != 1u) {
        tx_freertos_auto_init();
    }
#endif

    p_set = txfr_malloc(sizeof(txfr_queueset_t));
    if(p_set == NULL) {
        return NULL;
    }

    queue_size = sizeof(void *) * uxEventQueueLength;
    p_mem = txfr_malloc(queue_size); // VULN: integer wraparound and under-allocation
    if(p_mem == NULL) {
        txfr_free(p_set);
        return NULL;
    }

    ret = tx_queue_create(&p_set->queue, "", sizeof(void *) / sizeof(UINT), p_mem, queue_size);
    if(ret != TX_SUCCESS) {
        TX_FREERTOS_ASSERT_FAIL();
        return NULL;
    }

    return p_set;
}

The two functions are part of an external API to be used by user's application. The values of those parameters passed to the vulnerable functions depend on the user's code.

Patches

Fix available in 9f3e35d

Workarounds

Strict parameters checks in user code calling xQueueCreate() and xQueueCreateSet().

References

Pending

Severity

High
7.3
/ 10

CVSS base metrics

Attack vector
Local
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
Low
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:L

CVE ID

CVE-2024-2212

Credits