CVE-2025-24264
Overview
Background
- JIT operation call-frame tracer
- JITOperationPrologueCallFrameTracer sets the VM’s current top call frame for the duration of a runtime operation invoked from JIT code.
- Direct eval operations
- JIT helpers that execute a direct eval(); the callee frame is untrusted, so VM is taken from the caller frame.
- Top call frame
- The VM’s record of the currently executing frame, consulted during stack walks and GC; a stale value causes crashes.
Root Cause Analysis
This fixes a crash / potential corruption in JavaScriptCore’s JIT direct-eval operations that failed to update the VM’s top call frame. operationCallDirectEvalSloppy/Strict (and the …TaintedByWithScope variants) run when a direct eval() is invoked from JIT code. They derive the VM from the caller frame because the callee frame may be garbage at entry. Pre-patch they computed VM& vm = calleeFrame->callerFrame()->deprecatedVM() but did NOT install a JITOperationPrologueCallFrameTracer, so the VM’s current top call frame was left pointing at the untrusted callee/garbage frame during the operation. If the operation subsequently allocates or throws — for example eval of an enormous string that triggers an out-of-memory or exception, as the regression test does — the engine walks the stack or runs GC using that stale/garbage top frame, causing a crash (and potentially memory corruption).
The fix captures CallFrame* callFrame = calleeFrame->callerFrame() and constructs JITOperationPrologueCallFrameTracer tracer(vm, callFrame), setting the VM’s top call frame to the trusted caller for the duration of the operation.
The restored invariant is that JIT runtime operations that can allocate or throw set the correct top call frame via the tracer. The test evals huge strings in a loop to force the allocation/throw path.
Attack Path
- Call eval from JIT code Run hot JS that reaches operationCallDirectEval* for a direct eval().
- Force allocation/throw eval an enormous string so the operation triggers OOM/exception handling.
- Walk a stale top frame Because no call-frame tracer was installed, stack walking / GC uses the garbage callee frame as the top frame.
- Crash or corrupt The stale-frame walk crashes (or corrupts state) in the WebContent process.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
operationCallDirectEvalSloppy / Strict / SloppyTaintedByWithScope / StrictTaintedByWithScopeSource/JavaScriptCore/jit/JITOperations.cpp |
modified | Capture the caller frame and install JITOperationPrologueCallFrameTracer(vm, callFrame) so the VM's top call frame is correct when the eval operation allocates or throws. |
Audit Directions
- Same file: tracer coverageGrep JITOperations.cpp for JSC_DEFINE_JIT_OPERATION handlers that can allocate/throw but omit a JITOperationPrologue*CallFrameTracer.
- Caller-frame VM derivationAudit operations that take VM from callerFrame()->deprecatedVM() to confirm they also set the top call frame.