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

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Local
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
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