Assertion failure: !r.empty() / OOB index into FlowGraphSummary in [@ js::DebuggerScript::GetOffsetLocationMatcher::match] with saturated column numbers
Categories
(Core :: JavaScript: Debugger API, defect, P3)
Tracking
()
People
(Reporter: bugmon, Unassigned)
References
(Blocks 1 open bug)
Details
(Keywords: assertion, testcase)
Attachments
(4 files)
DebuggerScript::GetOffsetLocationMatcher::match (js/src/debugger/Script.cpp:1359-1363) walks the BytecodeRangeWithPosition forward with no !r.empty() guard, assuming the trailing RetRval is always an entry point; that assumption fails when a script is compiled with a start columnNumber within ~14 units of JS::LimitedColumnNumberOneOrigin::Limit, because the return and closing } columns both clamp to the limit so FunctionScriptEmitter::emitEndBody's updateSourceCoordNotes(bodyEnd) emits no ColSpan note for that op. Calling Debugger.Script.prototype.getOffsetLocation() on the trailing RetRval's offset then pops past the end of the bytecode and indexes flowData[script->length()] — MOZ_ASSERT(!r.empty()) in debug, MOZ_CRASH(ElementAt(aIndex = 3, aLength = 3)) from mozilla::Vector::operator[] in opt.
Exploit Chain
- Privileged (shell or chrome) code creates a debuggee global and attaches a
Debuggerto it. - It evaluates
function f(){ return 1 }in the debuggee withcolumnNumber>= 0x3FFFFFF1, so the columns ofreturnand the closing}both clamp to 1073741823 and the emitter emits no source note for the trailingRetRvalat pc 2 (the disassembly shows only abreakpoint-step-sepnote at pc 0, versus acolspan/breakpointnote at pc 2 for ordinary columns). - It calls
Debugger.Script.prototype.getOffsetLocation(2)onf's script. GetOffsetLocationMatcher::matchfinds pc 2 is neither an entry point nor has a single incoming edge, pops past the end of the bytecode, and indexesflowData[script->length()].- Debug build:
Assertion failure: !r.empty(), at js/src/debugger/Script.cpp:1362. Opt build:MOZ_CRASH(ElementAt(aIndex = 3, aLength = 3))frommozilla::Vector::operator[]— process abort.
Affected Code
- js/src/debugger/Script.cpp, line 1356-1363
- js/src/frontend/FunctionEmitter.cpp, line 535-543
- js/src/frontend/BytecodeEmitter.cpp, line 628-630
- js/src/frontend/TokenStream.cpp, line 847-849
- js/src/vm/BytecodeUtil-inl.h, line 224-232
Steps to Reproduce
- Ensure the tree is clean (
git -C /firefox statusshows no changes). - Build the SpiderMonkey debug shell: build_firefox(firefox_dir='/firefox', mozconfig_path='/app/mozconfigs/mozconfig.js.linux.debug').
- Run the testcase with js_shell_evaluator against /firefox/obj-js-debug/dist/bin/js (the evaluator adds --fuzzing-safe; no other flags):
- var g = newGlobal({newCompartment: true});
var dbg = new Debugger(g);
g.evaluate("function f(){ return 1 }", {columnNumber: 0x3FFFFFFE});
for (var s of dbg.findScripts()) {
for (var off = 0; off < 64; off++) {
try { s.getOffsetLocation(off); } catch (e) {}
}
} - Observe
Assertion failure: !r.empty(), at js/src/debugger/Script.cpp:1362injs::DebuggerScript::GetOffsetLocationMatcher::match. - Optionally run the same testcase against the ASAN fuzzing shell (/app/mozconfigs/mozconfig.linux.asan.fuzzing, /firefox/obj-firefox-asan/dist/bin/js) to observe
MOZ_CRASH(ElementAt(aIndex = 3, aLength = 3))frommozilla::Vector::operator[]at Script.cpp:1360.
Security Impact
- Severity: Low
- Attacker capability: Code with access to the
DebuggerAPI can abort the process by asking for the offset location of the trailingRetRvalof a function compiled with a near-limit column number. In debug builds this is aMOZ_ASSERTfailure; in release builds the out-of-boundsVectorindex is caught by the release-mode bounds check and results in a controlledMOZ_CRASH. No memory disclosure or corruption was demonstrated. - Preconditions: Caller must be able to use the SpiderMonkey
DebuggerAPI (JS shell or privileged chrome code); the script must be compiled with a startcolumnNumberwithin about 14 UTF-16 units ofJS::LimitedColumnNumberOneOrigin::Limit(2^30-1), e.g. viaevaluate(..., {columnNumber: 0x3FFFFFF1})or higher.
The full analysis report is attached (analysis.md).
| Reporter | ||
Comment 1•2 months ago
|
||
| Reporter | ||
Comment 2•2 months ago
|
||
| Reporter | ||
Comment 3•2 months ago
|
||
| Reporter | ||
Comment 4•2 months ago
|
||
Comment 5•2 months ago
|
||
This bug was filed automatically by an AI-powered security testing tool. The analysis, testcase, and any suggested patches were generated by an AI model and have NOT been verified by a human.
Please review all details carefully before triaging. The issue was confirmed by an independent verifier, but for non-ASAN issues, the verifier has been made less strict. Additionally, the root cause analysis and suggested fix may contain errors.
Updated•2 months ago
|
Updated•2 months ago
|
Description
•