Closed Bug 2044606 (CVE-2026-16392) Opened 4 months ago Closed 3 months ago

Assertion failure: hasRegisterIndex(reg), at jit/RegisterSets.h:459

Categories

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

All
Linux
defect

Tracking

()

RESOLVED FIXED
154 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox-esr140 --- unaffected
firefox151 --- wontfix
firefox152 --- wontfix
firefox153 + fixed
firefox154 + fixed

People

(Reporter: gkw, Assigned: jandem)

References

(Blocks 3 open bugs, Regression)

Details

(5 keywords, Whiteboard: [adv-main153+])

Attachments

(4 files, 1 obsolete file)

Attached file debug stack —
for (var i = 0; i < 9; i++) {
  oomTest(function () {
    (function () {
      try {
        Object.keys(function () {});
      } catch (e) {}
      return [];
    })();
  });
}
(gdb) bt
#0  0x000055555812921c in MOZ_CrashSequence (aAddress=0x0, aLine=459) at /home/msf2/shell-cache/js-dbg-64-linux-x86_64-6301b01791f9-630254/objd/dist/include/mozilla/Assertions.h:261
#1  js::jit::TypedRegisterSet<js::jit::Register>::offsetOfPushedRegister (this=<optimized out>, reg=...) at /home/msf2/trees/firefox/js/src/jit/RegisterSets.h:459
#2  js::jit::MachineState::SafepointState::addressOfRegister (this=<optimized out>, reg=...) at ./../../../../../../trees/firefox/js/src/jit/JitFrames.cpp:2536
#3  0x0000555558124f66 in js::jit::MachineState::read (this=0x7ffff7805700 <_IO_stdfile_2_lock>, reg=...) at ./../../../../../../trees/firefox/js/src/jit/JitFrames.cpp:2607
#4  js::jit::SnapshotIterator::fromRegister (this=0x7fffffffb530, reg=...) at /home/msf2/trees/firefox/js/src/jit/JSJitFrameIter.h:376
#5  js::jit::SnapshotIterator::allocationValue (this=0x7fffffffb530, alloc=..., rm=<optimized out>) at ./../../../../../../trees/firefox/js/src/jit/JitFrames.cpp:1820
/snip
e43e6780c6c0-628511
e43e6780c6c0aad349a6e4fe77350ee6253d9c08 is the first interesting commit
commit e43e6780c6c0aad349a6e4fe77350ee6253d9c08
Author: Iain Ireland
Date:   Tue May 26 19:36:11 2026 +0000

    Bug 2040903: Update alias set of ObjectToIterator r=jandem

    Differential Revision: https://phabricator.services.mozilla.com/D301605

Run with --fuzzing-safe --no-threads --ion-eager, compile with AR=ar sh ~/trees/firefox/js/src/configure --enable-debug --enable-debug-symbols --with-ccache --enable-nspr-build --enable-ctypes --enable-gczeal --enable-rust-simd --disable-tests, tested on gh rev 6301b01791f9c98637ae8d5b7a81dd004d48d468.

Jan, is bug 2040903 a likely regressor? (Note that it is marked s-s)

Flags: sec-bounty?
Flags: needinfo?(jdemooij)

Set release status flags based on info from the regressing bug 2040903

Group: core-security → javascript-core-security

Yes this is a regression from bug 2040903, the issue is the stealResumePoint here that moves the MObjectKeys resume point to MObjectToIterator.

When we have an exception bailout for an exception thrown by the MObjectToIterator instruction itself, the recover instruction for MObjectKeysFromIterator (called forRecovery in this code) tries to read the MObjectToIterator result but it's not available because that's the instruction we're still executing.

For an exception handler bailout, we don't read the expression stack slots so strictly speaking we don't need to execute these recover instructions (the result isn't used). That's not how the code is currently structured though.

Nicolas, can you take this one? I'm not sure what's the best fix for this one, also because we probably want to uplift.

Flags: needinfo?(jdemooij) → needinfo?(nicolas.b.pierron)
OS: macOS → Linux
Assignee: nobody → nicolas.b.pierron
Severity: -- → S3
Status: NEW → ASSIGNED
Priority: -- → P1

The problem is that ObjectKeysReplacer::run decompose the MObjectKeys function in 2, which is to build the iterator and then to build the keys from the iterator, even if the second is only used while recovering instructions.

This is not possible and this is the issue raised here.

We do ignore the returned value of a call when we are running into an exception, and the recover instruction would not have any function working with the result of this call as it would only be referenced as a register.

This code changes this assumption by adding extra operations on the bailout path, except that we cannot execute anything when there is no value to execute it onto. Which is exactly what this error message complains about.

Ideally we should split the original instruction, but in such case this is a single function call, and returning an iterator in-place of the array would cause even more issues. This can be achieved by having a MNop instruction inserted after which captured the modified resume-point while the original captures the MObjectToIterator. However, this would cause issues on invalidations as the MOSIPoint would use the iterator in place of the array, when there is no allocation failure, yet the code gets invalidated while we are processing the calls from LObjectToIterator.

I do not think we can carry over the fact that we should ignore the Recover instructions, like we ignore the returned value. The reason is that the recover instructions can technically be executed ahead of the return, like done in this exception handler, and like it is possible to do when using fun.arguments to invalidate functions which are on the stack.

While incorrect, I think the simplest choice is to go with the extra MNop and cloning the resume point. Other options are likely to be much more risky from my point of view.

The bug is marked as tracked for firefox152 (beta) and tracked for firefox153 (nightly). However, the bug still has low severity.

:sdetar, could you please increase the severity for this tracked bug? If you disagree with the tracking decision, please talk with the release managers.

For more information, please visit BugBot documentation.

Flags: needinfo?(sdetar)
Duplicate of this bug: 2045314
Attached file (secure) (obsolete) —

This bug needs a severity rating still also.

Reading the code, MachineState initialized from a SafePoint will read a register dump of all registers which are pushed on the stack.
I have not investigated the details of what might be stored in the returned register.
I will assign it a sec-moderate in the mean time.

Flags: needinfo?(nicolas.b.pierron)
Keywords: sec-moderate
Flags: needinfo?(sdetar)

Set release status flags based on info from the regressing bug 2040903

Found internally as well.

Flags: sec-bounty? → sec-bounty-
Comment 9 is private: false
Comment 1 is private: false
Blocks: 2049308
Attached file (secure) —
Attached file (secure) —
Assignee: nicolas.b.pierron → jdemooij

The following patch is waiting for review from a reviewer who resigned from the review:

ID Title Author Reviewer Status
D305340 Bug 2044606 - Object.keys optimization should split resume points. r=jandem nbp jandem: Resigned from review

:nbp, could you please find another reviewer?

For more information, please visit BugBot documentation.

Flags: needinfo?(nicolas.b.pierron)
Flags: needinfo?(nicolas.b.pierron)
Attachment #9595199 - Attachment is obsolete: true

https://hg-edge.mozilla.org/mozilla-central/rev/42e48216dd40

Please add a Beta uplift request on this.

Group: javascript-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 3 months ago
Flags: needinfo?(jdemooij)
Resolution: --- → FIXED
Target Milestone: --- → 154 Branch
Flags: needinfo?(jdemooij)

firefox-beta Uplift Approval Request

  • User impact if declined/Reason for urgency: Crashes, potential security issues.
  • Code covered by automated testing?: yes
  • Fix verified in Nightly?: yes
  • Needs manual QE testing?: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: medium
  • Explanation of risk level: Patch is non-trivial but should be fairly low risk. Affects a specific optimization for Object.keys in the JIT.
  • String changes made/needed?: N/A
  • Is Android affected?: yes
Attachment #9601796 - Flags: approval-mozilla-beta?
Attached file (secure) —
Attachment #9601796 - Flags: approval-mozilla-beta? → approval-mozilla-beta+
QA Whiteboard: [sec] [uplift] [qa-triage-done-c154/b153]
Whiteboard: [adv-main153+]
Alias: CVE-2026-16392
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: