OP-TEE Memory Isolation Failed on i.MX 8M, and the Failure Was Architectural
#Vulnerabilities

OP-TEE Memory Isolation Failed on i.MX 8M, and the Failure Was Architectural

Tech Essays Reporter
9 min read

Sigma Star’s June 11, 2026 analysis shows that some i.MX 8M systems running OP-TEE could expose secure-world memory to Linux, not because TrustZone vanished, but because boot firmware, address aliases, and controller defaults disagreed about where security begins.

Featured image

Thesis

Sigma Star’s report, TrustZone Intermezzo: Broken OP-TEE Memory Isolation on i.MX 8M, is not merely a story about one missing configuration bit in an embedded security stack. It is a reminder that trusted execution is not a property bestowed by a processor marketing name, but an agreement between hardware address decoders, boot firmware, secure operating systems, kernel policy, and the assumptions engineers carry from one layer to the next.

The issue affects systems built around NXP’s i.MX 8M Mini and related i.MX 8M SoCs when they run vulnerable combinations of OP-TEE OS, Trusted Firmware-A, and U-Boot. According to Sigma Star’s analysis, systems are at risk if they run upstream OP-TEE older than v4.10.0 without CFG_TZASC_REGION0_SECURE=y, or i.MX downstream OP-TEE older than lf-6.12.49_2.2.0. The practical result is severe: Linux, running in the normal world, can read memory that should belong only to OP-TEE in the secure world.

That matters because OP-TEE is not ornamental. It is often where embedded systems put software TPM functions, private keys, attestation material, secure storage logic, and trusted applications. If normal-world Linux can read or alter that memory, then the conceptual wall between an ordinary system compromise and a trusted execution compromise becomes much thinner than the architecture promises.

Key Arguments

The first layer of the story is deceptively simple. Arm TrustZone splits execution into two worlds: a secure world, where OP-TEE runs, and a normal world, where Linux usually runs. The secure world is supposed to hold secrets that remain protected even if the normal-world kernel is hostile. In the i.MX 8M design discussed by Sigma Star, that split depends on the TrustZone Address Space Controller, or TZASC, which applies access permissions to memory ranges. If the normal world tries to access a secure range, the access should fail in hardware.

The failure began with an observation in the OP-TEE source tree: a 2024-era fix made sure the TZASC was enabled on all i.MX 8M SoCs. That prompted the uncomfortable question behind the entire investigation. If this fix was necessary, were earlier systems actually leaving OP-TEE’s own memory insufficiently protected, or was the patch only defensive cleanup around rare misconfiguration?

Sigma Star tested an NXP i.MX 8M Mini EVK running OP-TEE 4.1.0, where OP-TEE placed its core memory at 0xbe000000. The first attempt to dump that memory from Linux failed, which could have suggested that the system was safe. It was not. The failure came from CONFIG_STRICT_DEVMEM, a Linux kernel configuration that limits access through /dev/mem. That is a Linux policy barrier, not a TrustZone barrier.

After rebuilding the kernel without CONFIG_STRICT_DEVMEM, the read still failed. Again, the system appeared safe for the wrong reason. OP-TEE had added a reserved-memory node to the device tree, and the region was marked nomap, causing Linux to avoid mapping it. This is useful system hygiene, but it is not a security proof. A compromised kernel, or a kernel module loaded by an attacker with kernel control, can ignore such conventions.

Once Sigma Star modified Linux to ignore the nomap hint, the real test finally occurred. Reading from 0xbe000000 produced OP-TEE memory, including recognizable strings from the OP-TEE core image. The implication is stark: the secure-world memory was not being protected by the hardware boundary that the design depended on. It was being spared by normal-world cooperation.

The second layer is more subtle and more interesting. Even after updating OP-TEE and TF-A so that direct access to 0xbe000000 was blocked, Sigma Star found that the system could still be vulnerable through memory aliases. The TZASC checks addresses, but it is not alias aware. If two different physical addresses are interpreted by the DDR controller as the same underlying memory, then the TZASC and the memory controller can disagree about what is being protected.

This is where region0 becomes central. In the TZASC, configured regions can assign permissions to specific address ranges. Requests that do not match those ranges fall back to region0, the default region. In a safe reset state, region0 is secure-only. If no explicit TZASC rule covers an alias, the fallback should still deny normal-world access. But if some earlier boot component changes region0 to permit non-secure access, the alias becomes a tunnel around the explicit secure-region rule.

Sigma Star found exactly that behavior in U-Boot’s i.MX 8M code. A function named enable_tzc380() wrote a value that allowed secure and non-secure read/write access to region0, apparently to accommodate certain bus masters such as USB controllers. From one firmware perspective, that write may have looked like a compatibility fix. From the whole-system security perspective, it changed the default answer to a dangerous question: what happens when an address falls outside the carefully described map?

The alias test made the danger concrete. With fixes applied but U-Boot still opening region0, direct reads from 0xbe000000 failed, while reads from 0x1be000000 succeeded and revealed OP-TEE memory. The DDR controller treated the alias as the same memory, while the TZASC treated it as a different address that did not match the protected region. The access fell through to the permissive default.

This is the philosophical center of the bug. Security mechanisms often appear as walls, but in real systems they are negotiations among components that may not share the same model of space. The TZASC saw addresses. The DDR controller saw memory. U-Boot saw device compatibility. Linux saw a reserved region. OP-TEE saw a secure core. The vulnerability lived in the gaps between those interpretations.

Implications

For vendors shipping i.MX 8M devices, the immediate lesson is operational. Update OP-TEE, TF-A, and bootloader components together. Treat the secure boot chain as a chain in the literal sense, where one permissive firmware decision can undo later secure-world assumptions. Sigma Star’s guidance is to use OP-TEE v4.10.0 or newer with CFG_TZASC_REGION0_SECURE=y, or the relevant newer i.MX downstream OP-TEE release containing the platform TZASC configuration update. Systems using U-Boot should examine the i.MX 8M region0 configuration and follow upstream fixes as they land.

For security teams, the more durable lesson is methodological. The first two failures in Sigma Star’s test were false negatives. CONFIG_STRICT_DEVMEM blocked access. The device tree nomap property blocked mapping. Both behaviors were good, but neither proved that TrustZone isolation was working. A test that stops at the first access denial can accidentally validate the wrong mechanism.

This is a common pattern in embedded security. There are often several overlapping barriers, including kernel configuration, device tree reservations, MMU mappings, bus firewalls, controller permissions, secure monitor policy, and boot-time locks. A denial from any one of them may look like success. The auditor’s task is to identify which barrier answered the request, then ask whether the intended barrier would still answer correctly if the weaker or more cooperative barriers were removed.

The alias issue also widens the threat model. A design that says the secure region is protected at 0xbe000000 is incomplete if the same memory can be reached through 0x1be000000. Any security rule tied to an address decoder has to account for all addresses that hardware may collapse into the same target. This is especially important on SoCs, where address maps are shaped by bus fabrics, memory controllers, legacy windows, peripheral constraints, and boot ROM assumptions.

There is also a disclosure and maintenance lesson. Sigma Star notes that no CVE identifiers had been assigned at publication time, despite the seriousness of the failure. That creates a visibility problem for downstream users. Many embedded product teams track CVEs more reliably than they track every OP-TEE, TF-A, or bootloader commit message. When a serious isolation failure arrives as a quiet platform fix, it may not reach the teams that need to rebuild firmware images for deployed devices.

The article also reinforces why the official OP-TEE documentation should be read as part of a platform integration process, not as a substitute for platform validation. OP-TEE provides the trusted OS, but the platform decides whether memory controllers, firewalls, and firmware defaults actually preserve the trusted boundary. On a modern embedded board, a trusted execution environment is a distributed property.

Counter-Perspectives

One counter-perspective is that this vulnerability requires powerful normal-world control. Reading /dev/mem, disabling kernel protections, or loading custom kernel code is not the same as compromising an unprivileged process. That is true, but it misses the central promise of TrustZone. The secure world exists precisely because the normal world may become untrusted. If a kernel compromise can directly read secure-world memory, then OP-TEE is no longer serving as the last line of defense for the secrets it holds.

Another fair objection is that Linux’s own safeguards did stop the initial reads. CONFIG_STRICT_DEVMEM and device tree reservations reduce accidental exposure and raise the effort required for simple attacks. They are useful. But they are normal-world conventions, and an attacker who owns the normal-world kernel is no longer bound by them. Treating those safeguards as equivalent to TZASC enforcement would confuse cooperative software policy with adversarial isolation.

A third counter-perspective is that downstream firmware sometimes opens region0 for practical reasons, such as making device masters work. Embedded systems are full of such trade-offs. Hardware blocks may assume access patterns that clash with strict security defaults, and vendors are under pressure to make boards boot, enumerate devices, and pass validation. Yet this case shows why broad fallback permissions are so dangerous. A workaround that seems local to one controller can silently alter the security meaning of every unmapped or aliased address.

There is also a tension between upstream strictness and downstream repair. Sigma Star criticizes the downstream i.MX OP-TEE approach for reconfiguring region0 itself, because that can hide the fact that another component changed the default region for the wrong reason. The downstream approach may reduce immediate exposure, but it risks normalizing a boot sequence in which components repair one another’s security state rather than preserving clear ownership. In secure firmware, that distinction matters, because late repair is often less trustworthy than preventing the unsafe state in the first place.

The strongest reading of this episode is not that TrustZone is broken, nor that OP-TEE is uniquely fragile. It is that trusted computing depends on boring precision. Address bits, fallback regions, firmware writes, and kernel mapping rules become moral commitments in silicon form: this world may read, that world may not. When those commitments are split across projects and boot stages, every assumption needs a test that reaches beneath polite software behavior and asks what the hardware will actually allow.

For teams building on i.MX 8M, the practical path is clear enough: update the secure stack, enable the region0 verification available in newer OP-TEE, audit U-Boot and TF-A behavior, and test aliases rather than only documented base addresses. The broader lesson is less comfortable. A trusted execution environment is not a box where secrets automatically become safe. It is a carefully maintained boundary, and a boundary that only works when every layer agrees on where it is.

Comments

Loading comments...