← ALL ADVISORIES

HIGH Disclosed

OP-TEE OS - Use-After-Free via TA_FLAG_CONCURRENT Accepted from User TAs

TA_FLAG_CONCURRENT is accepted from user TA headers, letting two sessions race on one shared context and free vm_region nodes that are still in use.

CVE
CVE-2026-71968
Vendor
ARM/Trusted Firmware
Product
OP-TEE OS
Affected
OP-TEE OS core prior to 51d1beeb59b7
Fixed in
2026-08-06

Executive Summary

TA_FLAG_CONCURRENT (BIT32(8)) tells the core to skip the per-context busy lock that normally serialises calls into a Trusted Application. It is meant for pseudo-TAs, which are part of the core and are written for it. Nothing rejected it in a user TA header: TA_FLAGS_MASK is GENMASK_32(13, 0), so bit 8 is inside the range that ldelf/ta_elf.c accepts, and the flag was carried into the loaded TA's context unchanged. An attacker-authored TA that sets it gets concurrent execution on a shared context, which the surrounding code was never written to tolerate, and the result is a use-after-free at S-EL1.

Details

Flag validation in ldelf/ta_elf.c only rejects bits outside the mask:

if (elf->head->flags & ~TA_FLAGS_MASK)
    err(TEE_ERROR_BAD_FORMAT, "Invalid TA flags(s) %#"PRIx32,
        elf->head->flags & ~TA_FLAGS_MASK);

With TA_FLAG_CONCURRENT inside TA_FLAGS_MASK, a user TA can declare it and the check passes. The flag then short-circuits serialisation in core/kernel/tee_ta_manager.c:

static bool tee_ta_try_set_busy(struct tee_ta_ctx *ctx)
{
    bool rc = true;

    if (ctx->flags & TA_FLAG_CONCURRENT)
        return true;   /* skip the busy lock entirely */
    ...

For a single-instance, multi-session TA, every session shares one tee_ta_ctx. With the busy lock skipped, two sessions execute against that shared context at the same time. Both map and unmap their memref parameters against the same address-space region list, uctx->vm_info.regions, and that list is manipulated with no lock of its own because the busy lock was the serialisation. Concurrent inserts, removals, and frees on the shared list corrupt its links and free vm_region nodes while the other session still holds and follows them.

Impact

A use-after-free on core heap objects at S-EL1, that can leade to code execution at S-EL1, the highest privilege level in the Secure World.

Remediation

Update to an OP-TEE OS core containing 51d1beeb59b7 ("core: ldelf: reject TA_FLAG_CONCURRENT for user TAs"), merged as 8794043c4065. A user TA that declares the flag is now rejected at load time, leaving it available only to pseudo-TAs, as documented.

Timeline

  • 2026-06-24 — Reported to the OP-TEE project with proof-of-concept code
  • 2026-07-30 — Fix submitted upstream as PR #7900
  • 2026-08-06 — Fix merged upstream as 8794043c4065
  • 2026-08-06 — Public disclosure