DFG Spread(SetObjectUse) side-effect modeling
fb8bfea
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
- if (node->child1().useKind() == SetObjectUse)
- didFoldClobberWorld();
- else
+ if (node->child1().useKind() == SetObjectUse) {
+ bool canFold = false;
+ JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
+ if (Structure* originalSetStructure = globalObject->setStructureConcurrently()) {
+ if (forNode(node->child1()).m_structure.isSubsetOf(RegisteredStructureSet(m_graph.registerStructure(originalSetStructure))))
+ canFold = true;
+ }
+ if (canFold)
+ didFoldClobberWorld();
+ else
+ clobberWorld();
+ } else
clobberWorld();
The DFG abstract interpreter assigns abstract states to values during JIT compilation, including "structure proofs" that let it eliminate CheckStructure guards. didFoldClobberWorld() signals an operation is side-effect-free and proofs survive; clobberWorld() invalidates all structure proofs. When 313031@main allowed Set spreads to invoke user-defined Symbol.iterator functions via operationSpreadSet (which can run arbitrary JS), the unconditional didFoldClobberWorld() became unsound: a user iterator executing during [...set] can redefine properties on other live objects.
This patch gates the fold on whether the operand is proven to carry the original Set structure. If yes, the fast path (no iterator) preserves proofs; otherwise clobberWorld() fires.
Significance
Incorrect side-effect attribution caused CheckStructure nodes to be folded away, allowing GetByOffset to read stale property slots after an iterator-induced structure transition — producing a type confusion primitive in JIT-compiled code.
Warmup: compiler infers set has originalSetStructure
CheckStructure(o, S_double)
Spread(set, SetObjectUse) → AI: didFoldClobberWorld() // proof for o survives
GetByOffset(o, slot 0, Double) // CheckStructure folded away
Exploit:
iterator: Object.defineProperty(obj, 'a', {get(){return 1}})
→ obj transitions S_double → S_accessor
GetByOffset reads slot 0 as Double on S_accessor → type confusion
Audit directions
a Aaaaaaaaaaaaaaaaaaa Aaaaaaaa Aaaaaaa Aaa Aaaa Aaaaaaa Aaa Aaaa Aaaa Aaaaaaaaaaaa Aaaaaaa a Aaaaaaaaa Aaaa Aa Aaa Aaaaaaaa Aaaaaaa Aaaaaaaaa Aaa Aa Aaaaa Aaaaaaaa Aaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaa Aaaaaaaaa Aaaaaaa Aaaaa Aaaaaaa Aaaaaaaaaaaaaaa Aaaaaa Aaaaaaa a Aaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aaa Aaaaa Aaaa Aaaaa
a Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aaa Aaaaaaaaa Aaaaaa Aaaaaaa Aaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aa Aaaaaaaaaaa Aaaaaaaaa Aa Aaaaaaa Aaaaa Aaaaa Aaaaaaa Aaaaa Aaaaaaaaaaa Aaa Aaaaaaaa Aaaaaaa Aaa Aaaaa Aaa Aaaaa Aaa Aaaaaaaaaaaa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaa Aaaaaaaaaa a Aaaaa Aaaaaaaaaaaa Aaa Aaaaaaaa
a Aaaaaaa Aaaaaaaaaa Aaaaaaaa Aaaa Aaa Aaaa Aaaaaaaa Aaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaa Aa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaa Aaaa Aaaaaaaaa Aaaaaaaaaaaaa Aaaa Aaaaa Aaaaaaaaaa Aaaaa Aaaaa Aa Aaaaaaaa Aaa Aaaaaaaa
a Aaaaaaaaaaaa Aaa Aaaaaaaaaaaaaa Aaa Aaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaaaaa Aaaaaaaaaa Aaaa Aa Aaaa Aaaaa Aaa Aaaaaaa Aa Aaaaaaaa Aaa Aaaaaa Aaaaaaa a Aaaaaaaaa Aaaaaaaa Aaaaa Aa a Aaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaa
🔒Edge cases in the new structure-proof guard and related collection use-kind modeling are worth security investigation.
Subscribe to read more