Closed Bug 2033802 Opened 6 months ago Closed 6 months ago

Assertion failure: js::CurrentThreadCanAccessRuntime(runtime_) @ js/shadow/Zone.h:79

Categories

(Core :: JavaScript: GC, defect, P1)

defect

Tracking

()

RESOLVED FIXED
152 Branch
Tracking Status
firefox152 --- fixed

People

(Reporter: x0e, Assigned: jonco, NeedInfo)

References

(Blocks 2 open bugs)

Details

(Keywords: reporter-external)

Attachments

(1 external file)

Steps to reproduce:

Build information

engine version         : c34ebfaedf1a009f0bd13f1700e9b795a1b520c7
engine version date    : 2026-04-21T08:56:18
build date             : 2026-04-21T13:59:17.095440

Shell arguments

--fuzzing-safe <input.js>

Test input

new Uint8Array(512);
[Uint8Array,[9]];
const v9 = new SharedArrayBuffer(8, { maxByteLength: 255 });
new Float64Array(v9);
const v16 = new ArrayBuffer(1024, { maxByteLength: 3422723342 });
new Int32Array(v16);
function f19(a20) {
    actual += a20 + ",";
}
var appendToActual = f19;
let hasFunction = {};
for (const v45 of ["gczeal","unsetgczeal","schedulegc","selectforgc","verifyprebarriers","verifypostbarriers","currentgc","det
    const present = v45 in this;
    if (!present) {
        function f50() {
        }
        this[v45] = f50;
    }
    hasFunction[v45] = present;
}
gcparam("parallelMarkingThresholdMB", 0);
var g1 = newGlobal();
var g2 = newGlobal({ sameZoneAs: g1 });
g2.evaluate("enableTrackAllocations()");
do {
    const v66 = () => {
        let objects = [];
        objects.push(newObjectWithCallHook());
        objects.push(createIsHTMLDDA());
        objects.push(g1);
        objects.push(g2);
        const v82 = new WeakSet(objects);
        assertEq(v82.has(createIsHTMLDDA()), false);
        assertEq(v82.delete(createIsHTMLDDA()), false);
        objects = gc();
        objects = null;
        gc();
    };
    var f = v66;
    try { f(); } catch (e) {}
    oomTest(f, { keepFailing: true });
} while ((() => {
        const v99 = !inIon();
        const v101 = transplantableObject();
        const v102 = v101.object;
        Object.defineProperty(v102, "e", { writable: true, value: v102 });
        v102.e = v102;
        v101.transplant(newGlobal({ newCompartment: true }));
        return v99;
    })())
gc();

Backtrace

[546754] Assertion failure: js::CurrentThreadCanAccessRuntime(runtime_), at targets/spidermonkey/artifacts/builds/reproducebui
#01: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x22ee4f7]
#02: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x22d9631]
#03: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x22d7903]
#04: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x22d75eb]
#05: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x22c97d8]
#06: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x1fd23c6]
#07: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x1fd214d]
#08: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x1fce204]
#09: JS::Zone::sweepWeakMaps(JSTracer*)[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x23e2d35]
#10: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x23e2a38]
#11: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x2415b22]
#12: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x2336910]
#13: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x2336ce4]
#14: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x2ff4e4f]
#15: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x30114eb]
#16: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x301125c]
#17: ???[targets/spidermonkey/artifacts/reproducebuild/dist/bin/js +0x301ea68]
#18: ???[/lib/x86_64-linux-gnu/libc.so.6 +0xa3d64]
#19: ???[/lib/x86_64-linux-gnu/libc.so.6 +0x1373fc]
#20: ??? (???:???)
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==546754==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x583321d0050f bp 0x70afeb9fe780 sp 0x
==546754==The signal is caused by a WRITE memory access.
==546754==Hint: address points to the zero page.
    #0 0x583321d0050f in MOZ_CrashSequence(void*, long) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/dist
    #1 0x583321d0050f in JS::shadow::Zone::runtimeFromMainThread() const targets/spidermonkey/artifacts/builds/reproducebuild-
    #2 0x583321ceb630 in js::gc::BufferAllocator::RefillResult js::gc::BufferAllocator::refillFreeLists<js::gc::BufferAllocato
    #3 0x583321ceb630 in void* js::gc::BufferAllocator::refillFreeListsAndRetryAlloc<js::gc::BufferAllocator::retryAlignedAllo
    #4 0x583321ceb630 in js::gc::BufferAllocator::retryAlignedAlloc(unsigned long, bool) targets/spidermonkey/artifacts/builds
    #5 0x583321ce9902 in js::gc::BufferAllocator::allocMediumAligned(unsigned long, bool) targets/spidermonkey/artifacts/build
    #6 0x583321ce9902 in js::gc::BufferAllocator::allocNewSmallRegion(bool) targets/spidermonkey/artifacts/builds/reproducebui
    #7 0x583321ce95ea in js::gc::BufferAllocator::retrySmallAlloc(unsigned long, unsigned long, bool)::$_1::operator()() const
    #8 0x583321ce95ea in js::gc::BufferAllocator::RefillResult js::gc::BufferAllocator::refillFreeLists<js::gc::BufferAllocato
    #9 0x583321ce95ea in void* js::gc::BufferAllocator::refillFreeListsAndRetryAlloc<js::gc::BufferAllocator::retrySmallAlloc(
    #10 0x583321ce95ea in js::gc::BufferAllocator::retrySmallAlloc(unsigned long, unsigned long, bool) targets/spidermonkey/ar
    #11 0x583321cdb7d7 in js::gc::BufferAllocator::allocSmall(unsigned long, bool, bool) targets/spidermonkey/artifacts/builds
    #12 0x5833219e43c5 in mozilla::detail::HashTable<mozilla::HashMapEntry<js::PreBarriered<JS::Value>, js::PreBarriered<JS::V
    #13 0x5833219e414c in mozilla::detail::HashTable<mozilla::HashMapEntry<js::PreBarriered<JS::Value>, js::PreBarriered<JS::V
    #14 0x5833219e0203 in mozilla::Maybe<mozilla::detail::HashTable<mozilla::HashMapEntry<js::PreBarriered<JS::Value>, js::Pre
    #15 0x5833219e0203 in js::WeakMap<JS::Value, JS::Value, js::BufferAllocPolicy>::traceWeakEdgesDuringSweeping(JSTracer*) ta
    #16 0x583321df4d34 in JS::Zone::sweepWeakMaps(JSTracer*) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a
    #17 0x583321df4a37 in js::gc::GCRuntime::sweepWeakMaps() targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a
    #18 0x583321e27b21 in js::gc::AutoRunParallelTask::run(js::AutoLockHelperThreadState&) targets/spidermonkey/artifacts/buil
    #19 0x583321d4890f in js::GCParallelTask::runTask(JS::GCContext*, js::AutoLockHelperThreadState&) targets/spidermonkey/art
    #20 0x583321d48ce3 in js::GCParallelTask::runHelperThreadTask(js::AutoLockHelperThreadState&) targets/spidermonkey/artifac
    #21 0x583322a06e4e in js::GlobalHelperThreadState::runTaskLocked(JS::HelperThreadTask*, js::AutoLockHelperThreadState&) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/vm/./../../../../../../.worktree-repro/js/src/vm/HelperThreads.cpp:665:11
    #22 0x583322a234ea in js::GlobalHelperThreadState::runOneTask(JS::HelperThreadTask*, js::AutoLockHelperThreadState&) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/vm/./../../../../../../.worktree-repro/js/src/vm/HelperThreads.cpp:621:3
    #23 0x583322a234ea in js::HelperThread::threadLoop(js::InternalThreadPool*) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/vm/./../../../../../../.worktree-repro/js/src/vm/InternalThreadPool.cpp:324:25
    #24 0x583322a2325b in js::HelperThread::ThreadMain(js::InternalThreadPool*, js::HelperThread*) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/vm/./../../../../../../.worktree-repro/js/src/vm/InternalThreadPool.cpp:251:11
    #25 0x583322a30a67 in void js::detail::ThreadTrampoline<void (&)(js::InternalThreadPool*, js::HelperThread*), js::InternalThreadPool*&, js::HelperThread*>::callMain<0ul, 1ul>(std::integer_sequence<unsigned long, 0ul, 1ul>) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/vm/spidermonkey/js/src/threading/Thread.h:224:5
    #26 0x583322a30a67 in js::detail::ThreadTrampoline<void (&)(js::InternalThreadPool*, js::HelperThread*), js::InternalThreadPool*&, js::HelperThread*>::Start(void*) targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/js/src/vm/spidermonkey/js/src/threading/Thread.h:213:11
    #27 0x70afecdaad63 in start_thread nptl/pthread_create.c:448:8
    #28 0x70afece3e3fb in __GI___clone3 misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

==546754==Register values:
rax = 0x0000000000000000  rbx = 0x000070afea70c000  rcx = 0x000000000000004f  rdx = 0x0000000000000000
rdi = 0x000070afecf3d780  rsi = 0x0000000000000000  rbp = 0x000070afeb9fe780  rsp = 0x000070afeb9fe770
 r8 = 0x0000000000000000   r9 = 0x0000000000000000  r10 = 0x0000000000000000  r11 = 0x000070afeb9ff6c0
r12 = 0x0000000000000000  r13 = 0x0000000000000000  r14 = 0x000070afea70c7b0  r15 = 0x000000000000000b
UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV targets/spidermonkey/artifacts/builds/reproducebuild-c34ebfaedf1a/dist/include/mozilla/Assertions.h:261:3 in MOZ_CrashSequence(void*, long)
==546754==ABORTING
Group: firefox-core-security → core-security
Component: Untriaged → JavaScript Engine
Product: Firefox → Core
Group: core-security → javascript-core-security

Test case was cut in between:

Test input

new Uint8Array(512);
[Uint8Array,[9]];
const v9 = new SharedArrayBuffer(8, { maxByteLength: 255 });
new Float64Array(v9);
const v16 = new ArrayBuffer(1024, { maxByteLength: 3422723342 });
new Int32Array(v16);
function f19(a20) {
    actual += a20 + ",";
}
var appendToActual = f19;
let hasFunction = {};
for (const v45 of ["gczeal","unsetgczeal","schedulegc","selectforgc","verifyprebarriers","verifypostbarriers","currentgc","deterministicgc","dumpGCArenaInfo","setMarkStackLimit","oomThreadTypes","oomAfterAllocations","oomAtAllocation","resetOOMFailure","oomTest","stackTest","interruptTest"]) {
    const present = v45 in this;
    if (!present) {
        function f50() {
        }
        this[v45] = f50;
    }
    hasFunction[v45] = present;
}
gcparam("parallelMarkingThresholdMB", 0);
var g1 = newGlobal();
var g2 = newGlobal({ sameZoneAs: g1 });
g2.evaluate("enableTrackAllocations()");
do {
    const v66 = () => {
        let objects = [];
        objects.push(newObjectWithCallHook());
        objects.push(createIsHTMLDDA());
        objects.push(g1);
        objects.push(g2);
        const v82 = new WeakSet(objects);
        assertEq(v82.has(createIsHTMLDDA()), false);
        assertEq(v82.delete(createIsHTMLDDA()), false);
        objects = gc();
        objects = null;
        gc();
    };
    var f = v66;
    try { f(); } catch (e) {}
    oomTest(f, { keepFailing: true });
} while ((() => {
        const v99 = !inIon();
        const v101 = transplantableObject();
        const v102 = v101.object;
        Object.defineProperty(v102, "e", { writable: true, value: v102 });
        v102.e = v102;
        v101.transplant(newGlobal({ newCompartment: true }));
        return v99;
    })())
gc();

Jon, would this be of some interest to you?

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

Can you include the configuration flags you used to build the shell?

Flags: needinfo?(x0e)

Never mind, it reproduces easily.

Assignee: nobody → jcoppeard
Component: JavaScript Engine → JavaScript: GC
Flags: needinfo?(x0e)
Flags: needinfo?(jcoppeard)

This a problem with the assertion being too strict and is not a security issue.

Group: javascript-core-security

The problem exposed by the testcase is that the assertion is too strict. We can
use the buffer allocator off thread in some cases (e.g. sweeping weakmaps)
provided we hold a mutex.

In general though it's a bad idea to wait on background threads if you are
running on one. I don't think think can deadlock at the moment but it's
probably best to skip this part if we're running off-thread.

Pushed by jcoppeard@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/69786e53c101 https://hg.mozilla.org/integration/autoland/rev/9d41e9a9d65a Change buffer allocator OOM handling to not wait on background threads if it's being used off-thread r=sfink
Pushed by rperta@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/ebfc92326572 https://hg.mozilla.org/integration/autoland/rev/2df517206198 Revert "Bug 2033802 - Change buffer allocator OOM handling to not wait on background threads if it's being used off-thread r=sfink" for causing spidermokey bustages

Backed out for causing spidermokey bustages
Backout link
Push with failures
Failure log(s)

Flags: needinfo?(jcoppeard)
Pushed by jcoppeard@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/b6f9113e56c3 https://hg.mozilla.org/integration/autoland/rev/6a310789b6fa Change buffer allocator OOM handling to not wait on background threads if it's being used off-thread r=sfink
Status: NEW → RESOLVED
Closed: 6 months ago
Resolution: --- → FIXED
Target Milestone: --- → 152 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: