Closed Bug 1681256 Opened 5 years ago Closed 5 years ago

Assertion failure: isFunctionFrame(), at vm/Stack.h:594 or Assertion failure: CalleeTokenIsFunction(token), at jit/CalleeToken.h:54 or various crashes with Debugger

Categories

(Core :: JavaScript Engine, defect, P1)

x86_64
Linux
defect

Tracking

()

VERIFIED FIXED
85 Branch
Tracking Status
firefox-esr78 --- unaffected
firefox83 --- unaffected
firefox84 --- unaffected
firefox85 --- verified

People

(Reporter: decoder, Assigned: yulia)

Details

(5 keywords, Whiteboard: [bugmon:update,bisected,confirmed][fuzzblocker])

Attachments

(2 files)

The following testcase crashes on mozilla-central revision 20201207-7167ab3f6e8d (debug build, run with --fuzzing-safe --ion-offthread-compile=off --enable-top-level-await --more-compartments):

let lfCode = `
    var g = newGlobal();
    g.debuggeeGlobal = this;
    g.eval("(" + function () {
        dbg = new Debugger(debuggeeGlobal);
        dbg.onExceptionUnwind = function (frame, exc) {};
    } + ")();");
`;
loadFile(lfCode);
loadFile(lfCode + " await ''");
function loadFile(lfVarx) {
    try {
        try { evaluate(lfVarx); } catch(exc) {}
        let lfMod = parseModule(lfVarx);
        lfMod.declarationInstantiation();
        lfMod.evaluation();
    } catch (lfVare) {}
}

Backtrace:

received signal SIGSEGV, Segmentation fault.
#0  0x0000555556ba5815 in js::InterpreterFrame::callee() const ()
#1  0x0000555556b7fb41 in js::AbstractFramePtr::callee() const ()
#2  0x00005555571bf14e in js::Debugger::getFrame(JSContext*, js::FrameIter const&, JS::MutableHandle<js::DebuggerFrame*>) ()
#3  0x00005555571beef4 in js::Debugger::getFrame(JSContext*, js::FrameIter const&, JS::MutableHandle<JS::Value>) ()
#4  0x00005555571cc055 in js::Debugger::fireExceptionUnwind(JSContext*, JS::Handle<JS::Value>, js::ResumeMode&, JS::MutableHandle<JS::Value>) ()
#5  0x00005555571c6e6b in js::DebugAPI::slowPathOnExceptionUnwind(JSContext*, js::AbstractFramePtr) ()
#6  0x0000555556b95997 in Interpret(JSContext*, js::RunState&) ()
#7  0x0000555556b82bf8 in js::RunScript(JSContext*, js::RunState&) ()
#8  0x0000555556b99223 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, JS::Handle<JS::Value>, js::AbstractFramePtr, JS::MutableHandle<JS::Value>) ()
#9  0x0000555556b9993d in js::Execute(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, JS::MutableHandle<JS::Value>) ()
#10 0x0000555556c3bd3f in js::ModuleObject::execute(JSContext*, JS::Handle<js::ModuleObject*>, JS::MutableHandle<JS::Value>) ()
#11 0x0000555556f9c5b8 in intrinsic_ExecuteModule(JSContext*, unsigned int, JS::Value*) ()
#12 0x0000555556b97032 in CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&) ()
[...]
#24 0x00005555569ff658 in main ()
rax	0x55555571700b	93824994078731
rbx	0x7fffffffaa68	140737488333416
rcx	0x555557fd4348	93825036796744
rdx	0x0	0
rsi	0x7ffff7105770	140737338431344
rdi	0x7ffff7104540	140737338426688
rbp	0x7fffffffa980	140737488333184
rsp	0x7fffffffa980	140737488333184
r8	0x7ffff7105770	140737338431344
r9	0x7ffff7f998c0	140737353717952
r10	0x58	88
r11	0x7ffff6dac7a0	140737334921120
r12	0x7fffffffac30	140737488333872
r13	0x7fffffffac30	140737488333872
r14	0x7ffff6024018	140737320730648
r15	0x7ffff6024000	140737320730624
rip	0x555556ba5815 <js::InterpreterFrame::callee() const+213>
=> 0x555556ba5815 <_ZNK2js16InterpreterFrame6calleeEv+213>:	movl   $0x252,0x0
   0x555556ba5820 <_ZNK2js16InterpreterFrame6calleeEv+224>:	callq  0x555556a8e9a2 <abort>

I'm seeing tons of different crashes either through slowPathOnExceptionUnwind or slowPathOnEnterFrame in the Debugger API. I am marking this s-s because some of the crashes are obvious use-after-free crashes. but since exploiting would require Debugger interaction, this will probably sec-moderate.

Attached file Testcase

Fuzzblocker, likely caused by toplevel-await. Yulia can you take a look? Thanks!

Flags: needinfo?(ystartsev)
Assignee: nobody → ystartsev
Flags: needinfo?(ystartsev)

Very exciting. I think I know what is wrong though.

I have a fix for this specific test, but you mentioned that there are other test cases that fail differently. Namely with the error around "Assertion failure: CalleeTokenIsFunction(token), at jit/CalleeToken.h:54" -- Do you have a test case you can share to make sure that the fix covers that as well?

Thanks

Flags: needinfo?(choller)
Severity: -- → S3
Priority: -- → P1

(In reply to Yulia Startsev from comment #4)

I have a fix for this specific test, but you mentioned that there are other test cases that fail differently. Namely with the error around "Assertion failure: CalleeTokenIsFunction(token), at jit/CalleeToken.h:54" -- Do you have a test case you can share to make sure that the fix covers that as well?

Thanks

All of the tests I have for that assert are rather unreduced because they seem to destabilize during reduction. The amount of variations for this is also too large to test all of them ahead of the fix. I suggest you just go ahead and land your fix and we will check if anything remains after the fix landed. These failures are popping up fairly reliably so I assume we would notice an incomplete fix :)

Flags: needinfo?(choller)

Bugmon Analysis:
Verified bug as reproducible on mozilla-central 20201208142416-f3ebdd48906c.
The bug appears to have been introduced in the following build range:

Start: 85d1fafd696aadc3b5f53c79b918c2ebdf48dcb7 (20201204071028)
End: 7d9c82add62dbc4c7ab63f169c2be1a51c611f81 (20201204090051)
Pushlog: https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=85d1fafd696aadc3b5f53c79b918c2ebdf48dcb7&tochange=7d9c82add62dbc4c7ab63f169c2be1a51c611f81

Whiteboard: [bugmon:update,bisect][fuzzblocker] → [bugmon:update,bisected,confirmed][fuzzblocker]

decoder: wrt your test case, i updated it slightly, as otherwise we get an uncaught promise error

(In reply to Yulia Startsev from comment #8)

decoder: wrt your test case, i updated it slightly, as otherwise we get an uncaught promise error

Yes that's the usual procedure. Fuzzing testcases often can't be used as unit tests without some kind of modifications.

It would be even better if we could get rid of the template string and + "await ''" stuff but I couldn't figure out how to make it easier any further.

Group: javascript-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → 85 Branch

Bugmon Analysis:
Verified bug as fixed on rev mozilla-central 20201209213504-7765d979d044.
Removing bugmon keyword as no further action possible.
Please review the bug and re-add the keyword for further analysis.

Status: RESOLVED → VERIFIED
Keywords: bugmon

This should have gotten a sec rating prior to landing, though in this case it doesn't matter too much because it looks like it is sec-moderate due to requiring the debugger.

Keywords: sec-moderate
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: