Closed Bug 2046893 Opened 5 months ago Closed 4 months ago

Differential behavior: ProxyObject::swap (JS_TransplantObject) empties live WeakRefs / unlinks weak observers of the transplanted object

Categories

(Core :: JavaScript Engine, defect, P1)

x86_64
Linux
defect

Tracking

()

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

People

(Reporter: decoder, Assigned: jonco)

References

(Regression)

Details

(4 keywords, Whiteboard: [adv-main154-])

Attachments

(2 files, 2 external files)

Summary

JS_TransplantObject — whose object-mutating engine is ProxyObject::swap (js/src/vm/ProxyObject.cpp:193) — permanently empties WeakRefs (and unlinks weak observer registrations) whose target is the object being transplanted, even though that object stays alive and fully usable.

Once the transplanted identity has at least one cross-compartment wrapper (i.e. on any transplant after the first hop, or on the very first transplant of a WindowProxy a parent compartment can see), the transplant flow remaps those wrappers by nuking them and swapping in new ones. The nuke primitive unconditionally severs all weak observers of the wrapped target, and the compensating relocation step in JS_TransplantObject runs after the remap, so it can only relocate registrations that were not already destroyed.

Observable from plain JavaScript with no GC at all:

  • WeakRef.prototype.deref() returns undefined while the program holds a strong, working reference to the target — a direct violation of the ECMAScript WeakRef liveness invariant (https://tc39.es/ecma262/#sec-weakref-invariants). Neither V8 nor a fixed SpiderMonkey produces this state.
  • FinalizationRegistry/WeakRef-based resource management in the affected compartment is silently broken for the transplanted object.

In the browser, transplantation is exactly what navigation does to WindowProxies (nsGlobalWindowOuter::SetNewDocument → xpc::TransplantObject → JS_TransplantObject) and what Fission process swaps do to remote proxies (js::RemapRemoteWindowProxies). The shell functions used in the PoC (transplantableObject(), newGlobal() with useWindowProxy/transplantWindowProxy) merely drive the same browser-reachable engine paths.

Root cause

Call chain for the second transplant of an identity (or the first transplant of an object that already has CCWs pointing at it, e.g. a WindowProxy):

  1. JS_TransplantObject (js/src/jsapi.cpp:650):
    • js/src/jsapi.cpp:702 — RemapAllWrappersForObject(cx, origobj, newIdentity) walks every compartment that has a CCW for origobj.
    • For each such wrapper: js::RemapWrapper (js/src/proxy/CrossCompartmentWrapper.cpp:511) calls NukeCrossCompartmentWrapper(cx, wobj) at js/src/proxy/CrossCompartmentWrapper.cpp:541 before re-pointing the wrapper via RemapDeadWrapper → ProxyObject::swap.
    • NukeCrossCompartmentWrapper (js/src/proxy/CrossCompartmentWrapper.cpp:357-371) unconditionally executes at line 368: gc::GCRuntime::clearWeakRefTargets(comp, ObjectValue(*target)).
    • clearWeakRefTargets (js/src/gc/FinalizationObservers.cpp:748,756) calls WeakRefObject::clearTargetAndUnlink() on every WeakRef in that compartment whose target is the transplanted object, permanently emptying them.
  2. Only afterwards does js/src/jsapi.cpp:710 run gc::GCRuntime::relocateFinalizationObserverTarget(ObjectValue(*origobj), ObjectValue(*newIdentity)) (js/src/gc/FinalizationObservers.cpp:659), which updates the surviving registrations to observe the new identity — the ones cleared in step 1 are already gone.

The clearWeakRefTargets call in the nuke primitive is correct for genuine nuking (document teardown — bug 2031152, "Clear weak ref targets when CCWs are nuked"), where the boundary is destroyed forever. The transplant path reuses nuking as an internal step of remapping a boundary that remains alive (bug 2032512, "Update weak ref state when target is transplanted", added relocation for exactly this reason — but it is ordered after the wrapper remap and cannot resurrect already-cleared observers).

The intended behavior is established by the engine's own test js/src/jit-test/tests/gc/transplant-weak-targets.js (WeakRefs must survive transplantation; it passes only because it covers the first hop, where no pre-existing CCWs exist) and by the asymmetry that FinalizationRegistry record registrations of the same object survive the same flow (only the WeakRef side is cleared by the nuke step). ProxyObject::swap and its callers provide no mechanism to preserve or restore these observer registrations across the wrapper remap.

Security relevance

The GC's weak-reference bookkeeping becomes observably wrong about object liveness. In the browser, web and chrome JS increasingly use FinalizationRegistry/WeakRef to manage caches of C++-backed resources; after a navigation-induced transplant an attacker-controlled page can drive these mechanisms into a state where a live object is reported dead (deref() === undefined). Embedder logic that frees or recycles backing state for "dead" entries while the actual object is still reachable and scriptable is a use-after-free pattern at the embedder level. Conversely, dropped (rather than relocated) registrations mean cleanup callbacks never run for objects that do die. No shell-reachable memory-corruption PoC is provided (the demonstrable effect is the spec-invariant / differential violation), so this is filed sec-audit.

Reproduction

JS shell version: 20260603-5cffec5992d3 (m-c-asan-debug). Both testcases are deterministic, trigger no GC, and reproduce identically with and without --differential-testing (3/3 runs).

poc.js — double transplant of a transplantable proxy

$ dist/bin/js --fuzzing-safe poc.js
poc.js:58:9 Error: BUG: WeakRef emptied while its target is alive (transplant severed the weak observer registrations)
(exit code 3)

$ d8 poc.js
OK: WeakRef still observes the live target
(exit code 0)

The final invariant check (wr.deref() === undefined while object.x === 42 through a strong reference) is plain ECMAScript; the transplant machinery is feature-guarded so the same file runs on V8 and exits 0. A fixed SpiderMonkey also exits 0 (single-hop transplants already preserve the WeakRef, per gc/transplant-weak-targets.js).

poc-windowproxy.js — browser-shaped, single navigation

Models the parent-window-observes-iframe-window case: the parent compartment holds a CCW to a WindowProxy and a WeakRef on it; one WindowProxy transplant ("navigation") empties the WeakRef while the WindowProxy keeps working.

$ dist/bin/js --fuzzing-safe poc-windowproxy.js
poc-windowproxy.js:33:9 Error: BUG: WeakRef on a live WindowProxy was emptied by navigation (WindowProxy transplant)
(exit code 3)

$ d8 poc-windowproxy.js
OK: WeakRef still observes the live WindowProxy
(exit code 0)

Suggested fix direction

Relocate (or snapshot-and-restore) the weak observer registrations for origobj before RemapAllWrappersForObject runs, or teach the remap path (RemapWrapper/NukeCrossCompartmentWrapper) to distinguish "boundary being destroyed" from "boundary being remapped" and skip clearWeakRefTargets in the latter case.

Secondary observations (no shell-reachable PoC, for completeness)

  1. ProxyObject::swap is the only delegate-changing operation in the engine with no Zone::beforeClearDelegate-style notification: it can give a weakmap key a new delegate mid-incremental-mark (js/src/vm/ProxyObject.cpp:264-267). Every in-tree caller happens to pre-barrier the key through other side effects, but the invariant documented in js/src/gc/WeakMap-inl.h:188-194 is not upheld by swap itself.
  2. ProxyObject::swap permits nursery/tenured-mixed swaps and so can move guts whose handler requires finalization (!canNurseryAllocate(), e.g. browser RemoteObjectProxy) into a nursery cell, where dying objects skip proxy_Finalize (js/public/Proxy.h:222-228; only a DEBUG assert in js/src/gc/Tenuring.cpp checks survivors). Browser-relevant only.

Jon, NI you to take a look since this looks related to WeakRef/FinalizationRegistry.

Flags: needinfo?(jcoppeard)
Assignee: nobody → jcoppeard
Attached file (secure) —

The issue here is that NukeCrossCompartmentWrapper calls
GCRuntime::clearWeakRefTargets which is not appropriate when we are merely
remapping a wrapper as we lose information about any WeakRefs/Finalization
registries obsevering the target.

I found that we call this in some places where the wrapper has already been
removed and we could call NukeRemovedCrossCompartmentWrapper instead and
replacing these calls fixes the problem. This happens in:

  • JS_TransplantObject
  • RemapWrapper
  • Compartment::getOrCreateWrapper

Places that still call NukeCrossCompartmentWrapper and still remove
WeakRef/FinalizationRegistry targets:

  • NukeCCW testing function
  • NukeCrossCompartmentWrapperIfExists
  • NukeCrossCompartmentWrappers

In the browser, web and chrome JS increasingly use FinalizationRegistry/WeakRef to manage caches of C++-backed resources

We only allow transplanting a restricted set of proxies. I don't think that coincides with any such use.

Flags: needinfo?(jcoppeard)
Keywords: regression
Regressed by: 2031152

Comment on attachment 9598208 [details]
(secure)

Security Approval Request

  • How easily could an exploit be constructed based on the patch?: Possible exploit requires finding a transplantable object with C++ storage where a FinalizationRegistry is used to manage its lifetime. I don't think any such object exists but it might do I suppose.
  • Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem?: No
  • Which branches (beta, release, and/or ESR) are affected by this flaw, and do the release status flags reflect this affected/unaffected state correctly?: Everything back to version 151
  • If not all supported branches, which bug introduced the flaw?: Bug 2031152
  • Do you have backports for the affected branches?: No
  • If not, how different, hard to create, and risky will they be?: Should be trivial.
  • How likely is this patch to cause regressions; how much testing does it need?: This is a very simple change and unlikely to cause any problems.
  • Is the patch ready to land after security approval is given?: Yes
  • Is Android affected?: Yes
Attachment #9598208 - Flags: sec-approval?
Priority: -- → P1

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

Attachment #9598208 - Flags: sec-approval? → sec-approval+
Pushed by jcoppeard@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/5f3195d2abd1 https://hg.mozilla.org/integration/autoland/rev/fc4736289534 Replace calls to NukeCrossCompartmentWrapper with NukeRemovedCrossCompartmentWrapper where possible r=jandem
Pushed by abutkovits@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/64a24c67c9f9 https://hg.mozilla.org/integration/autoland/rev/06ac350c0f7f Revert "Bug 2046893 - Replace calls to NukeCrossCompartmentWrapper with NukeRemovedCrossCompartmentWrapper where possible r=jandem" for causing failures at Proxy.cpp.
[task 2026-06-19T14:13:30.216+00:00] 14:13:30     INFO - TEST-START | dom/canvas/test/test_capture.html
[task 2026-06-19T14:13:30.379+00:00] 14:13:30     INFO - GECKO(9033) | [WARN  audioipc2_server::server] Promotion of content process thread to real-time error
[task 2026-06-19T14:13:30.387+00:00] 14:13:30     INFO - GECKO(9033) | ### XPCOM_MEM_BLOAT_LOG defined -- logging bloat/leaks to /tmp/tmp51ayrbia.mozrunner/runtests_leaks_tab_pid12061.log
[task 2026-06-19T14:13:42.832+00:00] 14:13:42     INFO - GECKO(9033) | MEMORY STAT | vsize 2630MB | residentFast 158MB | heapAllocated 9MB
[task 2026-06-19T14:13:42.856+00:00] 14:13:42     INFO - GECKO(9033) | [11959] Assertion failure: p, at checkouts/gecko/js/src/proxy/Proxy.cpp:878
[task 2026-06-19T14:13:42.857+00:00] 14:13:42     INFO -  Initializing stack-fixing for the first stack frame, this may take a while...
[task 2026-06-19T14:13:56.094+00:00] 14:13:56     INFO - GECKO(9033) | #01: js::ProxyObject::trace(JSTracer*, JSObject*) [git:github.com/mozilla-firefox/firefox:js/src/proxy/Proxy.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:893]
[task 2026-06-19T14:13:56.097+00:00] 14:13:56     INFO - GECKO(9033) | #02: JSObject::traceChildren(JSTracer*) [git:github.com/mozilla-firefox/firefox:js/src/vm/JSObject.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:2980]
[task 2026-06-19T14:13:56.097+00:00] 14:13:56     INFO - GECKO(9033) | #03: JS::TraceChildren(JSTracer*, JS::GCCellPtr) [git:github.com/mozilla-firefox/firefox:js/src/gc/Tracer.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:56]
[task 2026-06-19T14:13:56.097+00:00] 14:13:56     INFO - GECKO(9033) | #04: js::gc::UnmarkGrayTracer<(unsigned int)0>::unmark(JS::GCCellPtr) [git:github.com/mozilla-firefox/firefox:js/src/gc/Marking.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:3379]
[task 2026-06-19T14:13:56.097+00:00] 14:13:56     INFO - GECKO(9033) | #05: js::gc::UnmarkGrayGCThingUnchecked(js::GCMarker*, JS::GCCellPtr) [git:github.com/mozilla-firefox/firefox:js/src/gc/Marking.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:3395]
[task 2026-06-19T14:13:56.098+00:00] 14:13:56     INFO - GECKO(9033) | #06: JS::UnmarkGrayGCThingRecursively(JS::GCCellPtr) [git:github.com/mozilla-firefox/firefox:js/src/gc/Marking.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:3419]
[task 2026-06-19T14:13:56.099+00:00] 14:13:56     INFO - GECKO(9033) | #07: js::Wrapper::wrappedObject(JSObject*) [git:github.com/mozilla-firefox/firefox:js/src/proxy/Wrapper.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:308]
[task 2026-06-19T14:13:56.100+00:00] 14:13:56     INFO - GECKO(9033) | #08: js::NukeRemovedCrossCompartmentWrapper(JSContext*, JSObject*) [git:github.com/mozilla-firefox/firefox:js/src/proxy/BaseProxyHandler.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:412]
[task 2026-06-19T14:13:56.101+00:00] 14:13:56     INFO - GECKO(9033) | #09: js::NukeCrossCompartmentWrappers(JSContext*, js::CompartmentFilter const&, JS::Realm*, js::NukeReferencesToWindow, js::NukeReferencesFromTarget) [git:github.com/mozilla-firefox/firefox:js/src/proxy/CrossCompartmentWrapper.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:471]
[task 2026-06-19T14:13:56.101+00:00] 14:13:56     INFO - GECKO(9033) | #10: mozilla::WindowDestroyedEvent::Run() [git:github.com/mozilla-firefox/firefox:dom/base/WindowDestroyedEvent.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:140]
[task 2026-06-19T14:13:56.103+00:00] 14:13:56     INFO - GECKO(9033) | #11: IdleRunnableWrapper::Run() [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:318]
[task 2026-06-19T14:13:56.103+00:00] 14:13:56     INFO - GECKO(9033) | #12: mozilla::RunnableTask::Run() [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:720]
[task 2026-06-19T14:13:56.104+00:00] 14:13:56     INFO - GECKO(9033) | #13: mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:1358]
[task 2026-06-19T14:13:56.106+00:00] 14:13:56     INFO - GECKO(9033) | #14: mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:1223]
[task 2026-06-19T14:13:56.106+00:00] 14:13:56     INFO - GECKO(9033) | #15: mozilla::TaskController::ProcessPendingMTTask(bool) [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:655]
[task 2026-06-19T14:13:56.107+00:00] 14:13:56     INFO - GECKO(9033) | #16: mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.h:5f3195d2abd1b00d166db7ad5aef9c9207464114:537]
[task 2026-06-19T14:13:56.108+00:00] 14:13:56     INFO - GECKO(9033) | #17: nsThread::ProcessNextEvent(bool, bool*) [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThread.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:1183]
[task 2026-06-19T14:13:56.110+00:00] 14:13:56     INFO - GECKO(9033) | #18: NS_ProcessNextEvent(nsIThread*, bool) [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:472]
[task 2026-06-19T14:13:56.110+00:00] 14:13:56     INFO - GECKO(9033) | #19: mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessagePump.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:84]
[task 2026-06-19T14:13:56.111+00:00] 14:13:56     INFO - GECKO(9033) | #20: MessageLoop::Run() [git:github.com/mozilla-firefox/firefox:ipc/chromium/src/base/message_loop.cc:5f3195d2abd1b00d166db7ad5aef9c9207464114:347]
[task 2026-06-19T14:13:56.112+00:00] 14:13:56     INFO - GECKO(9033) | #21: nsBaseAppShell::Run() [git:github.com/mozilla-firefox/firefox:widget/nsBaseAppShell.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:153]
[task 2026-06-19T14:13:56.113+00:00] 14:13:56     INFO - GECKO(9033) | #22: nsAppShell::Run() [git:github.com/mozilla-firefox/firefox:widget/gtk/nsAppShell.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:575]
[task 2026-06-19T14:13:56.114+00:00] 14:13:56     INFO - GECKO(9033) | #23: XRE_RunAppShell() [git:github.com/mozilla-firefox/firefox:toolkit/xre/nsEmbedFunctions.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:656]
[task 2026-06-19T14:13:56.115+00:00] 14:13:56     INFO - GECKO(9033) | #24: mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessagePump.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:233]
[task 2026-06-19T14:13:56.116+00:00] 14:13:56     INFO - GECKO(9033) | #25: MessageLoop::Run() [git:github.com/mozilla-firefox/firefox:ipc/chromium/src/base/message_loop.cc:5f3195d2abd1b00d166db7ad5aef9c9207464114:347]
[task 2026-06-19T14:13:56.116+00:00] 14:13:56     INFO - GECKO(9033) | #26: XRE_InitChildProcess(int, char**, XREChildData const*) [git:github.com/mozilla-firefox/firefox:toolkit/xre/nsEmbedFunctions.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:598]
[task 2026-06-19T14:13:56.154+00:00] 14:13:56     INFO - GECKO(9033) | #27: main [git:github.com/mozilla-firefox/firefox:browser/app/nsBrowserApp.cpp:5f3195d2abd1b00d166db7ad5aef9c9207464114:466]
[task 2026-06-19T14:13:56.155+00:00] 14:13:56     INFO - GECKO(9033) | #28: ??? [/lib/x86_64-linux-gnu/libc.so.6 + 0x2a1ca]
[task 2026-06-19T14:13:56.156+00:00] 14:13:56     INFO - GECKO(9033) | #29: __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6 + 0x2a28b]
[task 2026-06-19T14:13:56.157+00:00] 14:13:56     INFO - GECKO(9033) | #30: ??? [/builds/worker/workspace/build/application/firefox/firefox-bin + 0x3e539]
[task 2026-06-19T14:13:56.158+00:00] 14:13:56     INFO - GECKO(9033) | #31: ??? (???:???)
Flags: needinfo?(jcoppeard)
Flags: needinfo?(jcoppeard)
Pushed by jcoppeard@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/2e75f71e7d2e https://hg.mozilla.org/integration/autoland/rev/8f41de9c9153 Replace calls to NukeCrossCompartmentWrapper with NukeRemovedCrossCompartmentWrapper where possible r=jandem
Pushed by ctuns@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/5066580ec305 https://hg.mozilla.org/integration/autoland/rev/bc06adcf8d8b Revert "Bug 2046893 - Replace calls to NukeCrossCompartmentWrapper with NukeRemovedCrossCompartmentWrapper where possible r=jandem" for causing reftest failures in BaseProxyHandler.cpp

General bustage. Example:

[task 2026-06-19T15:44:24.032+00:00] 15:44:24     INFO - REFTEST SUITE-START | Running 10946 tests
[task 2026-06-19T15:44:24.033+00:00] 15:44:24     INFO - REFTEST TEST-START | js/src/tests/test262/language/statements/async-generator/dstr/ary-ptrn-rest-id-iter-step-err.js
[task 2026-06-19T15:44:24.033+00:00] 15:44:24     INFO - REFTEST TEST-LOAD | file:///builds/worker/workspace/build/tests/jsreftest/tests/js/src/tests/jsreftest.html?test=test262/language/statements/async-generator/dstr/ary-ptrn-rest-id-iter-step-err.js | 0 / 10946 (0%)
[task 2026-06-19T15:44:24.034+00:00] 15:44:24     INFO - ### XPCOM_MEM_BLOAT_LOG defined -- logging bloat/leaks to /tmp/tmptw4v40uc.mozrunner/runreftest_leaks_tab_pid1837.log
[task 2026-06-19T15:44:24.034+00:00] 15:44:24     INFO - [Child 1837, Main Thread] WARNING: NS_ENSURE_SUCCESS(rv, rv) failed with result 0x80520012 (NS_ERROR_FILE_NOT_FOUND): file checkouts/gecko/layout/style/Loader.cpp:2150
[task 2026-06-19T15:44:24.036+00:00] 15:44:24     INFO - console.error: services.settings:
[task 2026-06-19T15:44:24.037+00:00] 15:44:24     INFO -   Message: EmptyDatabaseError: "main/normandy-recipes-capabilities" has not been synced yet
[task 2026-06-19T15:44:24.037+00:00] 15:44:24     INFO -   Stack:
[task 2026-06-19T15:44:24.038+00:00] 15:44:24     INFO -     EmptyDatabaseError@resource://services-settings/Database.sys.mjs:19:5
[task 2026-06-19T15:44:24.038+00:00] 15:44:24     INFO - list@resource://services-settings/Database.sys.mjs:96:13
[task 2026-06-19T15:44:24.039+00:00] 15:44:24     INFO - 1781883863072	addons.xpi	ERROR	System addon update list error Error: Failed downloading XML, status: 0, channelStatus: 2152398861, errorCode: 2, reason: error
[task 2026-06-19T15:44:24.045+00:00] 15:44:24     INFO - REFTEST TEST-PASS | js/src/tests/test262/language/statements/async-generator/dstr/ary-ptrn-rest-id-iter-step-err.js |   item 1
[task 2026-06-19T15:44:24.045+00:00] 15:44:24     INFO - REFTEST TEST-END | js/src/tests/test262/language/statements/async-generator/dstr/ary-ptrn-rest-id-iter-step-err.js
[task 2026-06-19T15:44:24.046+00:00] 15:44:24     INFO - REFTEST TEST-START | js/src/tests/test262/language/statements/async-generator/dstr/ary-ptrn-rest-id-iter-val-err.js
[task 2026-06-19T15:44:24.047+00:00] 15:44:24     INFO - REFTEST TEST-LOAD | file:///builds/worker/workspace/build/tests/jsreftest/tests/js/src/tests/jsreftest.html?test=test262/language/statements/async-generator/dstr/ary-ptrn-rest-id-iter-val-err.js | 1 / 10946 (0%)
[task 2026-06-19T15:44:24.048+00:00] 15:44:24     INFO - [1837] Assertion failure: !wrapper->compartment()->lookupWrapper( UncheckedUnwrapWithoutExpose(wrapper)), at checkouts/gecko/js/src/proxy/BaseProxyHandler.cpp:413
[task 2026-06-19T15:44:24.048+00:00] 15:44:24     INFO -  Initializing stack-fixing for the first stack frame, this may take a while...
[task 2026-06-19T15:44:35.411+00:00] 15:44:35     INFO - #01: js::NukeRemovedCrossCompartmentWrapper(JSContext*, JSObject*) [git:github.com/mozilla-firefox/firefox:js/src/proxy/BaseProxyHandler.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:412]
[task 2026-06-19T15:44:35.411+00:00] 15:44:35     INFO - #02: js::NukeCrossCompartmentWrappers(JSContext*, js::CompartmentFilter const&, JS::Realm*, js::NukeReferencesToWindow, js::NukeReferencesFromTarget) [git:github.com/mozilla-firefox/firefox:js/src/proxy/CrossCompartmentWrapper.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:471]
[task 2026-06-19T15:44:35.412+00:00] 15:44:35     INFO - #03: mozilla::WindowDestroyedEvent::Run() [git:github.com/mozilla-firefox/firefox:dom/base/WindowDestroyedEvent.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:140]
[task 2026-06-19T15:44:35.412+00:00] 15:44:35     INFO - #04: IdleRunnableWrapper::Run() [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:318]
[task 2026-06-19T15:44:35.413+00:00] 15:44:35     INFO - #05: mozilla::RunnableTask::Run() [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:720]
[task 2026-06-19T15:44:35.414+00:00] 15:44:35     INFO - #06: mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:1358]
[task 2026-06-19T15:44:35.414+00:00] 15:44:35     INFO - #07: mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:1223]
[task 2026-06-19T15:44:35.415+00:00] 15:44:35     INFO - #08: mozilla::TaskController::ProcessPendingMTTask(bool) [git:github.com/mozilla-firefox/firefox:xpcom/threads/TaskController.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:655]
[task 2026-06-19T15:44:35.415+00:00] 15:44:35     INFO - #09: mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.h:2e75f71e7d2e171ebf3818b42d9914ba757481f1:537]
[task 2026-06-19T15:44:35.416+00:00] 15:44:35     INFO - #10: nsThread::ProcessNextEvent(bool, bool*) [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThread.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:1183]
[task 2026-06-19T15:44:35.416+00:00] 15:44:35     INFO - #11: NS_ProcessNextEvent(nsIThread*, bool) [git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:472]
[task 2026-06-19T15:44:35.417+00:00] 15:44:35     INFO - #12: mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessagePump.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:84]
[task 2026-06-19T15:44:35.417+00:00] 15:44:35     INFO - #13: MessageLoop::Run() [git:github.com/mozilla-firefox/firefox:ipc/chromium/src/base/message_loop.cc:2e75f71e7d2e171ebf3818b42d9914ba757481f1:347]
[task 2026-06-19T15:44:35.418+00:00] 15:44:35     INFO - #14: nsBaseAppShell::Run() [git:github.com/mozilla-firefox/firefox:widget/nsBaseAppShell.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:153]
[task 2026-06-19T15:44:35.418+00:00] 15:44:35     INFO - #15: nsAppShell::Run() [git:github.com/mozilla-firefox/firefox:widget/gtk/nsAppShell.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:575]
[task 2026-06-19T15:44:35.419+00:00] 15:44:35     INFO - #16: XRE_RunAppShell() [git:github.com/mozilla-firefox/firefox:toolkit/xre/nsEmbedFunctions.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:656]
[task 2026-06-19T15:44:35.419+00:00] 15:44:35     INFO - #17: mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) [git:github.com/mozilla-firefox/firefox:ipc/glue/MessagePump.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:233]
[task 2026-06-19T15:44:35.420+00:00] 15:44:35     INFO - #18: MessageLoop::Run() [git:github.com/mozilla-firefox/firefox:ipc/chromium/src/base/message_loop.cc:2e75f71e7d2e171ebf3818b42d9914ba757481f1:347]
[task 2026-06-19T15:44:35.420+00:00] 15:44:35     INFO - #19: XRE_InitChildProcess(int, char**, XREChildData const*) [git:github.com/mozilla-firefox/firefox:toolkit/xre/nsEmbedFunctions.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:598]
[task 2026-06-19T15:44:35.451+00:00] 15:44:35     INFO - #20: main [git:github.com/mozilla-firefox/firefox:browser/app/nsBrowserApp.cpp:2e75f71e7d2e171ebf3818b42d9914ba757481f1:466]
[task 2026-06-19T15:44:35.452+00:00] 15:44:35     INFO - #21: ??? [/lib/x86_64-linux-gnu/libc.so.6 + 0x2a1ca]
[task 2026-06-19T15:44:35.452+00:00] 15:44:35     INFO - #22: __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6 + 0x2a28b]
[task 2026-06-19T15:44:35.453+00:00] 15:44:35     INFO - #23: ??? [/builds/worker/workspace/build/application/firefox/firefox-bin + 0x3e539]
[task 2026-06-19T15:44:35.453+00:00] 15:44:35     INFO - #24: ??? (???:???)
Group: javascript-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 4 months ago
Flags: needinfo?(jcoppeard)
Resolution: --- → FIXED
Target Milestone: --- → 154 Branch
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Target Milestone: 154 Branch → ---
Pushed by jcoppeard@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/b7a63dea49b7 https://hg.mozilla.org/integration/autoland/rev/01fcf88b0fd6 Replace calls to NukeCrossCompartmentWrapper with NukeRemovedCrossCompartmentWrapper where possible r=jandem
Flags: needinfo?(jcoppeard)
Status: REOPENED → RESOLVED
Closed: 4 months ago → 4 months ago
Resolution: --- → FIXED
Target Milestone: --- → 154 Branch

The patch landed in nightly and beta is affected.
:jonco, is this bug important enough to require an uplift?

For more information, please visit BugBot documentation.

Flags: needinfo?(jcoppeard)

No crash or exploit was demonstrated and it's not obvious how one could be constructed. We can let this ride the trains.

Flags: needinfo?(jcoppeard)
Regressions: 2055458
QA Whiteboard: [qa-triage-done-c155/b154][sec]
Whiteboard: [adv-main154-]
Group: core-security-release
Attachment #9598209 - Attachment description: (secure) → Bug 2046893 - Add tests r?jandem
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: