SpiderMonkey ExecutionTracer heap OOB write in TracingBuffer via oversized script URLs / function atoms
Categories
(Core :: JavaScript: Debugger API, defect, P2)
Tracking
()
People
(Reporter: jsw5203, Unassigned)
References
(Blocks 1 open bug, )
Details
(Keywords: reporter-external, Whiteboard: [client-bounty-form])
Attachments
(1 file)
|
28.46 KB,
application/x-zip-compressed
|
Details |
I discovered this while testing SpiderMonkey's ExecutionTracer with ASan builds and oversized script metadata strings.
Root cause:
js::TracingBuffer::writeBytesAtOffset() in js/src/debugger/ExecutionTracer.h treats TracingBuffer as a ring buffer but only handles at most one wrap-around. writeBytes() does not reject a single write larger than the ring-buffer capacity. When a serialized string payload is larger than the 4 MiB outOfLineData_ buffer, the second memcpy() in writeBytesAtOffset() writes past the end of the heap allocation.
Affected code:
js/src/debugger/ExecutionTracer.h:TracingBuffer<BUFFER_SIZE>::writeBytesAtOffset()js/src/debugger/ExecutionTracer.cpp:writeScriptUrl(),writeAtom()
Tested versions:
- Local ASan JS shell: JavaScript-C152.0a1, mozilla-central d3f8663d56e4
- Official ASan Nightly: Mozilla Firefox 150.0a1
- Browser artifact Nightly: Mozilla Firefox 152.0a1
Operating system:
- Ubuntu 24.04.2 LTS x86_64 (WSL2, Linux 6.6.87.2-microsoft-standard-WSL2)
Reproduction summary:
- Enable execution tracing.
- Trigger serialization of an oversized script metadata string.
- ASan reports a heap-buffer-overflow WRITE in
TracingBuffer::writeBytesAtOffset().
Minimal JS shell reproduction for the displayURL path:
js -e 'enableExecutionTracing(); eval("function t(){return 1}t();\n//# sourceURL=" + "B".repeat((1<<22)+4096))'
Additional verified paths:
- Oversized script filename via
data:URI - Oversized function name atom via computed property name
- Browser content-process trigger with profiler startup tracing
- DevTools RDP activation once the DevTools server is available
Actual result:
ASan reports heap-buffer-overflow WRITE at TracingBuffer::writeBytesAtOffset(), writing past a 4,194,304-byte heap allocation.
Expected result:
ExecutionTracer should reject, skip, chunk, or safely truncate oversized out-of-line string entries before writing them to the ring buffer.
Security impact:
This demonstrates a real heap out-of-bounds write in the Firefox content process when ExecutionTracer is compiled in and tracing is activated. I am not claiming Release/ESR exposure or RCE. The demonstrated scope is Nightly / mozilla-central / local developer builds.
Additional source location: https://searchfox.org/firefox-main/source/js/src/debugger/ExecutionTracer.cpp
Attachments:
I attached a report bundle containing the full write-up, PoCs, reproduction commands, version metadata, SHA256 sums, and redacted ASan logs.
Updated•6 months ago
|
Updated•6 months ago
|
Comment 1•5 months ago
|
||
I'm giving all of the open unrated JavaScript: Debugger API security bugs a rating of sec-moderate. I looked through the bugs and it didn't seem like anybody had dug into them, so the rating may not be accurate, but it is a decent starting point.
Comment 2•5 months ago
|
||
Duping forward to bug 2042783 which has a bit more information. Not a security bug.
Comment 3•5 months ago
|
||
"Nightly ony" could still be a security bug if there's a plausible remote attack (on Firefox -- the shell is just a tool). I'm not convinced either way yet, and since this is outside the bounty collision window we should make it depend-on rather than dupe so we don't lose track of it.
Comment 4•5 months ago
|
||
Not a security bug per comment 2, enableExecutionTracing is not --fuzzing-safe.
Description
•