ADVANCED TECHNIQUE BRIEF

JIT aliasing and stale map inference

Reason about object identity across compiler effects before turning layout confusion into a memory primitive.

Also known as: CVE-2025-2135 · TurboFan map inference · fakeObj

v8jittype-confusionalias-analysis

A compiler fact is valid only until an operation can invalidate it. In a dynamic language, this includes writes through another reference to the same object. The difficult case is two different intermediate-representation nodes that refer to one heap object at runtime: syntactic inequality does not establish memory independence.

Research anchor and scope

Zellic’s CVE-2025-2135 analysis identifies an aliasing omission in TurboFan’s handling of TransitionElementsKindOrCheckMap. Its demonstrated chain ends at arbitrary read/write inside the V8 sandbox. The reported zero-day submission was March 6, 2025; the article was published March 30, 2026. Use the linked Chromium bug and patch to identify affected revisions rather than assuming every Chrome or Node version shares the behavior.

Build the reasoning before the payload

Represent the sequence as facts and invalidations. Suppose a compiler checks that argument a has layout L, then changes the layout of argument b, then accesses a using L. There are three cases: a and b certainly differ, certainly coincide, or may coincide. Only the first permits retaining L without another check. The second needs an updated fact; the third needs a guard or conservative invalidation.

For a toy model, warm a function with two independent containers, then call it with the same container in both positions. This changes the alias relation without requiring a novel input type. Inspect the generated intermediate representation to confirm that the expected transition and later specialized access survive optimization. A crash in a debug assertion proves a violated invariant, but does not yet prove a controllable read or write.

Characterize the primitive

Record which representation is real and which is assumed, slot widths, pointer compression, tagging, and whether reads or writes cross object boundaries. A float interpreted as a reference is useful only if its bit pattern reaches storage unchanged. NaN canonicalization and garbage collection can invalidate convenient assumptions. Keep any forged object alive and test whether collection moves its backing storage.

Progress through separate milestones: reproducible representation mismatch, stable address disclosure, controllable object reference, bounded memory access, then a useful target. For each milestone, use an innocuous observable field rather than assuming code execution. A successful array-length change establishes a data corruption primitive, not an executable-memory transition.

Limits and recognition clues

Look for newly introduced IR nodes, asymmetric handling of the receiver and other objects, and map inference that walks backward through effects. Compare the patched invariant against the old one. Compiler flags, warm-up history, architecture, and sandbox configuration are part of the reproduction environment. Memory access within an engine cage does not itself escape the renderer, defeat the V8 sandbox, or reach operating-system privileges.

Sources & further reading

  1. Pwning V8CTF: CVE-2025-2135 ↗Sakura · zellic

Content license: CC BY 4.0. Source-derived sections retain their cited licenses and redistribution notices. How this reference is compiled →