GHSA-v9jj-7qjg-h6g6: Integer wraparounds, under-allocations, and heap buffer overflows in Eclipse ThreadX xQueueCreate() and xQueueCreateSet()
GHSA ID |
|
|---|---|
CVE ID |
CVE‑2024‑2212 |
Severity |
High |
CVSS score |
7.3 ( |
CWE |
|
Published |
2024‑03‑26 |
Last updated |
2024‑03‑26 |
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.