Introduction
An incomplete pointer validation flaw in Espressif's ESP-TEE secure service wrappers allows an unprivileged application running in the Rich Execution Environment to write attacker controlled data directly into Trusted Execution Environment memory, shattering the hardware enforced isolation that is the entire point of having a TEE. With over 1 billion Espressif wireless connectivity chips shipped globally and the ESP32 module market valued at $1.8 billion in 2025, the potential blast radius of this vulnerability across consumer and industrial IoT deployments is substantial.
Espressif Systems is a publicly listed, fabless semiconductor company headquartered in Shanghai that produces the widely adopted ESP32 family of IoT SoCs. Their ESP-IDF (IoT Development Framework) is the primary SDK for building firmware on these chips. The ESP-TEE framework, supported on RISC-V based ESP32-C6 and ESP32-C5 SoCs, provides hardware enforced isolation between a secure world (TEE) and a non-secure world (REE), protecting cryptographic accelerators, attestation, OTA updates, and secure storage from untrusted application code.
Technical Information
The REE/TEE Trust Boundary
ESP-TEE partitions CPU execution time into two worlds: the secure TEE world and the non-secure REE world. Hardware enforced memory isolation separates them. When a user application in the REE needs to access a TEE protected peripheral (AES, SHA, ECC, HMAC, SPI, MMU, WDT) or a security feature like attestation or secure storage, it invokes a secure service wrapper. These wrappers, implemented in esp_secure_services.c and esp_secure_services_iram.c, transition execution into the TEE world and perform the requested operation on behalf of the caller.
The security of this entire architecture depends on one critical invariant: the TEE must never trust pointers supplied by the REE without thorough validation. CVE-2026-45328 exists because this invariant was violated.
Root Cause: Incomplete Pointer Validation
The TEE secure service wrappers used a function called esp_tee_ptr_in_ree() to validate that caller supplied pointers resided within the REE's memory region. However, this validation was applied inconsistently. Output pointers, pointers embedded within struct contexts (such as cryptographic context structures), and buffer end addresses were not validated at all in many service wrappers. Several functions, including _ss_esp_sha_read_digest_state(), _ss_esp_sha_write_digest_state(), _ss_esp_sha_block(), _ss_esp_ecc_point_verify(), _ss_esp_tee_sec_storage_gen_key(), and _ss_psa_initial_attest_get_token_size(), had zero input validation.
Even where validation was present, the pattern was fundamentally unsafe. The old approach validated start and end pointers independently:
// BEFORE — only checks start/end pointers, no overflow protection bool valid_addr = ((esp_tee_ptr_in_ree((void *)input) && esp_tee_ptr_in_ree((void *)output)) && (esp_tee_ptr_in_ree((void *)(input + length)) && esp_tee_ptr_in_ree((void *)(output + length))));
This is susceptible to integer overflow: if an attacker controls input and length, they can craft values such that input + length wraps around to a value that falls within the REE region, while the actual write extends into TEE memory.
Integer Overflow in OTA Write Bounds Check
A separate but related vulnerability existed in esp_tee_ota_ops.c. The bounds check for OTA writes contained a classic integer overflow:
// BEFORE — rel_offset + size can wrap to a small value, bypassing the check if (rel_offset + size > ota_handle.tee_next.pos.size) { ESP_LOGE(TAG, "Out of region write not allowed!"); return ESP_FAIL; }
An attacker controlling both rel_offset and size could craft values whose sum wraps around via integer overflow, producing a small value that passes the bounds check. This enables writing arbitrary data outside the intended TEE OTA partition, potentially overwriting secure boot code or other TEE firmware.
Disabled Heap Assertions in the TEE
Compounding the above issues, the TEE's internal heap assertion mechanism in multi_heap.c was completely disabled:
// BEFORE — assertion was a no-op inline static void multi_heap_assert(bool condition, const char *format, int line, intptr_t address) { (void)condition; // Explicitly cast to void, effectively ignoring the condition esp_rom_printf(format, line, address); }
Even when heap corruption was detected within the TEE, the system would merely log a message and continue execution. This allowed an attacker to exploit corrupted heap state for further privilege escalation without triggering any defensive halt.
Exploitable Dispatch Table in Writable Memory
The secure service call table (tee_sec_srv_tbl_int_mem[] in esp_secure_service_table.c) held function pointers for all internal trusted services exposed to the normal world. Prior to the fix, this table resided in TEE DRAM with Read/Write permissions. If an attacker achieved an arbitrary write within the TEE via the out of bounds write vulnerability, they could overwrite entries in this dispatch table to redirect secure service calls to attacker controlled code, escalating to arbitrary code execution within the TEE.
Attack Flow
-
An attacker gains local code execution in the REE, either through a malicious application, a compromised firmware update, or by chaining a separate vulnerability such as CVE-2026-45542 (heap buffer overflow in protocomm over Bluetooth) or CVE-2026-45541 (WebSocket Server null pointer dereference).
-
The attacker invokes a TEE secure service wrapper (for example, an AES operation) with a crafted output pointer that targets TEE resident DRAM rather than REE memory. Because the wrapper does not validate the output pointer or uses the overflow susceptible validation pattern, the TEE accepts the request.
-
The TEE hardware peripheral writes its output (ciphertext, hash digest, etc.) to the attacker specified address within TEE memory, corrupting TEE data structures.
-
Optionally, the attacker first uses the companion vulnerability CVE-2026-45329 (out of bounds read in the same wrappers) to leak TEE memory layout, identifying the exact address of the secure service dispatch table.
-
The attacker targets the dispatch table with the out of bounds write, replacing a function pointer with the address of attacker controlled code.
-
On the next secure service call, the TEE dispatches to the attacker's code, achieving arbitrary code execution within the secure world with full access to all TEE protected peripherals, cryptographic keys, attestation credentials, and secure storage.
CVSS Scoring Context
The CVSS v3.1 base score of 9.3 with vector CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H reflects the Scope Changed (S:C) metric: the attack originates in the non-secure REE but impacts the secure TEE environment, crossing a trust boundary. Attack complexity is Low and no privileges are required in the v3.1 assessment, meaning exploitation is straightforward once local access is obtained.
Patch Information
Espressif addressed CVE-2026-45328 through six commits applied across three branches (master, release/v6.0, and release/v5.5), all authored by Laukik Hase. The fixes are included in ESP-IDF versions 5.5.5 and 6.0.1 and tracked under GHSA-mmgp-73p4-92xp. No runtime workaround exists; updating the TEE firmware is the only remediation path.
The patch consists of four logical categories of changes:
1. New Buffer Bounds Validator: esp_tee_buf_in_ree()
The most critical fix introduces a new inline helper function in esp_tee_memory_utils.h that replaces the unsafe pattern of validating start and end pointers independently:
FORCE_INLINE_ATTR bool esp_tee_buf_in_ree(const void *p, size_t len) { uintptr_t start = (uintptr_t)p; /* Reject zero-length and overflow */ if (len == 0 || len > (SIZE_MAX - start)) { return false; } return esp_tee_ptr_in_ree(p) && esp_tee_ptr_in_ree((const char *)p + len - 1); }
This function checks for zero length buffers and arithmetic overflow before performing any pointer arithmetic. By verifying len > (SIZE_MAX - start), it ensures the addition start + len can never wrap. The pointer type was also changed from intptr_t (signed) to uintptr_t (unsigned), eliminating undefined behavior from signed overflow.
Every secure service wrapper was refactored to use this new function. For example, the AES CBC wrapper changed from the old two call pattern to:
// AFTER — validates each buffer with its full size, with overflow guard bool valid_addr = (esp_tee_buf_in_ree(ctx, sizeof(esp_aes_context)) && esp_tee_buf_in_ree(iv, 16) && esp_tee_buf_in_ree(input, length) && esp_tee_buf_in_ree(output, length));
The new pattern validates the ctx struct pointer and the IV buffer, which were not checked at all in the original code. This was applied uniformly across AES (all modes), SHA (with proper per algorithm digest/state/block sizes via new helpers like get_sha_digest_size()), HMAC, Digital Signature, ECC, AEAD encrypt/decrypt, attestation, SPI flash operations, MMU mapping routines, and watchdog functions. ESP_FAULT_ASSERT() is applied immediately after each check; if validation fails, the macro triggers a secure fault (abort).
2. OTA Write Integer Overflow Fix
The bounds check in esp_tee_ota_write() was replaced with an overflow safe two step comparison:
// AFTER — checks size first, then uses subtraction to avoid overflow if (size > ota_handle.tee_next.pos.size || rel_offset > ota_handle.tee_next.pos.size - size) { ESP_LOGE(TAG, "Out of region write not allowed!"); return ESP_FAIL; }
This validates size independently first, then ensures rel_offset does not exceed the safe remainder, preventing the wrap around exploit.
3. Heap Assertion Activation
The disabled multi_heap_assert() was corrected to actually enforce its condition:
// AFTER — actually aborts on heap corruption if (!condition) { esp_rom_printf(format, line, address); abort(); }
Heap corruption within the TEE now halts execution rather than being silently ignored.
4. Service Call Table Made Immutable
The secure service call table (tee_sec_srv_tbl_int_mem[]) was moved from DRAM_ATTR to IRAM_ATTR in esp_secure_service_table.c. Since TEE IRAM is marked read/execute (R/X) via the Physical Memory Attribution (PMA) unit while DRAM is read/write (R/W), placing the function pointer table in IRAM ensures it cannot be tampered with at runtime. This prevents an attacker from redirecting secure service calls even if they achieve an arbitrary write within the TEE.
Commit References
| Commit | Branch | Purpose |
|---|---|---|
| 145ba4c | master | Input validation checks for TEE service calls |
| 764626a | master | Move secure service call table to TEE IRAM |
| 7867f4a | release/v6.0 | Input validation backport |
| 440a5d1 | release/v6.0 | Table relocation backport |
| eebabaf | release/v5.5 | Input validation backport |
| afd14ab | release/v5.5 | Table relocation backport |
The combined patch across all three branches totals approximately 570 additions and 154 deletions per branch, reflecting the scope of the missing validation that needed to be added.
Affected Systems and Versions
The vulnerability affects the esp_tee component within the following ESP-IDF versions:
| Affected Version | Patched Version |
|---|---|
| ESP-IDF 5.5.4 | ESP-IDF 5.5.5 |
| ESP-IDF 6.0 | ESP-IDF 6.0.1 |
The vulnerable code paths are only present when the ESP-TEE framework is enabled. ESP-TEE is supported on RISC-V based Espressif SoCs, specifically the ESP32-C6 and ESP32-C5. Devices using other ESP32 variants (ESP32, ESP32-S2, ESP32-S3, ESP32-C3) are not affected as they do not support the ESP-TEE framework.
If the TEE framework is not enabled in the firmware configuration, the vulnerable secure service wrappers are not compiled into the firmware and the device is not exposed to this vulnerability.
Vendor Security History
Espressif maintains a published security policy and a vulnerabilities page in the ESP-IDF Programming Guide that tracks all CVEs discovered and fixed in each release. The CVE-2026 disclosure period reveals a pattern of security issues across multiple components:
| CVE ID | Vulnerability | Component |
|---|---|---|
| CVE-2026-45328 | Out of Bounds Write | ESP-TEE Secure Service Wrappers |
| CVE-2026-45329 | Out of Bounds Read | ESP-TEE Secure Service Wrappers |
| CVE-2026-46532 | Heap Out of Bounds Read | Bluedroid |
| CVE-2026-45542 | Heap Buffer Overflow | protocomm over Bluetooth |
| CVE-2026-45541 | Remote Null Pointer Dereference | WebSocket Server |
| CVE-2026-25532 | WPS Enrollee Fragment Integer Underflow | WPS |
| CVE-2025-55297 | BluFi Example Memory Overflow | BluFi Reference Application |
The simultaneous disclosure of CVE-2026-45328 and CVE-2026-45329, both affecting the same ESP-TEE boundary layer, indicates systemic input validation gaps in the TEE component rather than an isolated oversight. Independent security firms including NCC Group (via Fox IT) have previously discovered memory corruption and cryptographic weaknesses in Espressif's BluFi reference application, and Nozomi Networks has identified replay vulnerabilities in Espressif's ESP-NOW protocol.
CVE-2026-45328 was reported by security researcher Eun0us from the Espilon Worker team under responsible disclosure. The advisory was published by mahavirj (Espressif) on May 13, 2026, with patches simultaneously available across multiple release branches. This coordinated response demonstrates an effective disclosure process.
References
- GHSA-mmgp-73p4-92xp: Out of Bounds Write in ESP-TEE Secure Service Wrappers
- CVE-2026-45328 Detail (NVD)
- Out of bounds write in ESP-IDF (cybersecurity-help.cz)
- ESP-TEE User Guide (ESP32-C6)
- ESP-IDF Vulnerabilities Page
- ESP-IDF Security Policy
- GHSA-w82j-7q63-7pqm: Out of Bounds Read in ESP-TEE (companion CVE-2026-45329)
- Out of bounds read in ESP-IDF, CVE-2026-45329 (cybersecurity-help.cz)
- Building Hardware Enforced Trust into Matter Devices with ESP-TEE
- Commit 145ba4c: Add missing input validation checks
- Commit 764626a: Move secure service call table to TEE IRAM
- Commit 7867f4a: Input validation backport (v6.0)
- Commit 440a5d1: Table relocation backport (v6.0)
- Commit eebabaf: Input validation backport (v5.5)
- Commit afd14ab: Table relocation backport (v5.5)
- Espressif Leads the IoT Chip Market with Over 1 Billion Chip Sales
- ESP32 Module Market Research Report 2034
- CISA Known Exploited Vulnerabilities Catalog
- Espressif Security Implementation Guide



