Closed Bug 1952168 Opened 16 days ago Closed 15 days ago

A bug in JIT optimization: an exception about outputs changed of Symbol

Categories

(Core :: JavaScript Engine: JIT, defect)

Other Branch
defect

Tracking

()

RESOLVED INVALID

People

(Reporter: anbu1024.me, Unassigned)

Details

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0

Steps to reproduce:

A bug in JIT optimization, whether there are security risks or not requires further in-depth analysis.

Version:
commit 7b3f3fb5fd2cad8f348131498a35a91bef68b47b

Build options:

/bin/sh ../../gecko-dev/js/src/configure --enable-debug --disable-optimize --disable-shared-js --disable-tests --enable-gczeal

Test options:

./js --baseline-warmup-threshold=10 --ion-warmup-threshold=50 --ion-check-range-analysis --ion-extra-checks --differential-testing

Case1:

Problem Description: Execution results exhibit discrepancies.

function opt(){
  const v0 = Symbol.search;
  const v1 = Symbol.valueOf;
  const v3 = v1.apply(v0);
  function v4() { }
  const v5 = v4.valueOf;
  const v6 = Object.bind(v5,v5);
  const v7 = new Proxy(v6,{});
  const v8 = new Proxy(Proxy,v7);
  const v9 = {"apply":eval,"call":eval,"__proto__":eval,"defineProperty":eval,"get":v8};
  const v11 = new Proxy(v4,v9);
  const v12 = [].keys();
  const v13 = v12.__proto__;
  v13.__proto__ = v11;
  const v14 = new Promise(v4);
  const v15 = [v14];
  const v16 = new Proxy({},v14);
  v14.__proto__ = v16;
  const v17 = Promise.allSettled(v15);
  const v18 = v17.catch(Object);
  const v19 = v3.toLocaleString();
  return v19;
}
  
let a = opt();
let b = opt();
for (let i = 0; i < 55; i++) {
  opt();
}
let c = opt();
print(JSON.stringify(a));
print(JSON.stringify(b));
print(JSON.stringify(c));

Actual results:

The result has changed after JIT optimization.

Case1:

a = "Symbol(Symbol.search)"
b = "Symbol(Symbol.search)"
c = undefined
Group: core-security → javascript-core-security

Note that --no-blinterp and V8 get the same output here.

Thanks for the report! However, this is not a bug. After the second iteration, Function.prototype.apply is overwritten, which causes const v3 = v1.apply(v0) to produce a different result.

Note that other engines get the same result. In general, before reporting a bug where it looks like we're getting the wrong result in a complicated case, it is a good idea to compare it against other JS implementations. It's unlikely that we all have the same bug, so if we get the same result, then it's probably correct. (This doesn't always work in reverse. There are some cases, especially around sorting and for-in enumeration, where the JS spec does not specify a single correct behaviour. In those cases, engines can give different correct results.)

Similarly, if you suspect that JIT optimization may be involved, it's a good idea to try running with --blinterp-disabled, which will turn off all the JITs. If you still see the same result, then it's not because of JIT optimization.

Running these quick checks before reporting the bug will save you time writing the bug report, and save us time investigating it.

Group: javascript-core-security
Status: NEW → RESOLVED
Closed: 15 days ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.