Closed Bug 1765249 Opened 3 years ago Closed 3 years ago

Assertion failure: this->is<MIRType>(), at js/src/jit/MIR.h:789

Categories

(Core :: JavaScript Engine: JIT, defect, P1)

defect

Tracking

()

RESOLVED FIXED
101 Branch
Tracking Status
firefox101 --- fixed

People

(Reporter: lukas.bernhard, Assigned: anba)

References

(Blocks 2 open bugs)

Details

Attachments

(1 file)

Steps to reproduce:

The attached samples triggers the following assertion in SM:
Assertion failure: this->is<MIRType>(), at js/src/jit/MIR.h:789
Bisecting the issue identifies git commit 0ce05dd4eaabfcb8274e0bf41cdfb0201104147b related to bug 1131996.

command line:

obj-x86_64-pc-linux-gnu/dist/bin/js --fast-warmup --no-threads --cpu-count=1 --ion-offthread-compile=off --fuzzing-safe sample.js

sample.js

function main() {
    let v0 = 0;
    for (let v4 = 1; v4 < 30; v4++) {
        with ({}) {}
        function v8() {
            for (let v12 = v0; v12 < 5; v12++) {
                arguments[v12];
                v0 = undefined;
                for (const v19 of "aaa") { } 

                function v20() {
                    let v23 = arguments[0];
                    v23.__proto__ = {}; 
                    for (let v27 = 0; v27 < 100; v27 = v27 + 0) {
                        v27 *= undefined;
                    }   
                }   
                const v29 = v20(arguments);
            }   
        }   
        v8();
    }   
}
main();

Out of curiosity, how is the with({}) {} changing the behavior of SM as this seems a prerequisite to trigger the issue (or at least makes it more likely)?

Group: firefox-core-security → core-security
Component: Untriaged → JavaScript Engine: JIT
Product: Firefox → Core

Out of curiosity, how is the with({}) {} changing the behavior of SM as this seems a prerequisite to trigger the issue (or at least makes it more likely)?

with disables Warp compilation, which in turn prevents inlining v8 into main. When main is too large to allow inlining, the assertion can also be triggered. main can be made too large by adding 36 for (let i = 0; i < 1; ++i); empty loops at the end. The bytecode size then exceeds 2000, which is above the limit for main-thread compilation.

Minimised test case:

function main() {
  // Disable Warp compilation, so we don't inline |f|.
  with ({}) {}

  let begin = 0;
  for (let i = 1; i < 30; i++) {
    f(begin);
    begin = undefined;
  }
}
main();

function f(begin) {
  for (let i = begin; i < 5; i++) {
    arguments[i];

    for (const c of "aaa") {}

    arguments.__proto__ = {};
  }
}

This was just an extra assertion to make sure the previous pass to compute
supported arguments operations doesn't let through any unexpected operations
which may have modified the prototype. We've already skipped this assertion for
MCreateInlinedArgumentsObject or when no template object is available.

Assignee: nobody → andrebargull
Status: NEW → ASSIGNED
Blocks: sm-opt-jits
Severity: -- → S2
Priority: -- → P1

S2 -> S4, based on the title of the submitted patch.

Severity: S2 → S4
Group: core-security → javascript-core-security

Bad assertion, so I'm removing the sec flag.

Group: javascript-core-security
Pushed by ctuns@mozilla.com: https://hg.mozilla.org/mozilla-central/rev/dea9b0b1371c Remove incorrect assertion when replacing prototype guard. r=iain
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 101 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: