Assertion failure: CheckGrayMarkingState(rt) @ gc/GC.cpp:5304
Categories
(Core :: JavaScript: GC, defect, P2)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox156 | --- | fixed |
People
(Reporter: x0e, Assigned: jonco)
References
(Blocks 2 open bugs)
Details
(Keywords: reporter-external)
Attachments
(1 external file)
Steps to reproduce:
engine version : 9f2e8c25f0b40fdce8d2f2ca40281e8711815a6d
engine version date : 2026-07-23T15:46:19Z
build date : 2026-07-24T10:32:44
Shell args:
--baseline-warmup-threshold=10 --ion-warmup-threshold=100 --ion-check-range-analysis --ion-extra-checks --fuzzing-safe --disable-oom-functions <input.js>
Test input:
gczeal("CheckGrayMarking")
verifyprebarriers()
eval(`grayRoot()`).a = Symbol()
gc()
eval("grayRoot()")
schedulezone("")
startgc()
Backtrace:
Found black to gray edge to gray JS Symbol 0x16e6e8410020 in zone 0x7d627effc000
from black JS Object Array 0x10d46a906190 in compartment 0x7d627efd4350 in zone 0x7d627ef99000 objectDynamicSlots edge
from root shell root array
Source:
{
"address": "(JSObject*)0x10d46a906190",
"nonCCWGlobal": "<global @ (JSObject*)0x10d46a906030>",
"clasp": "<Array @ (JSClass*)0x5c7bedc1ed10>",
"shape": "<(js::Shape*)0x10d46a921380, objectFlags=[HasEnumerable, HasNonWritableOrAccessorPropExclProto]>",
"shape.base": {
"address": "(js::BaseShape*)0x10d46a904130",
"realm": "(JS::Realm*)0x7d627ef06800",
"proto": "(JSObject*)0x10d46a906088"
},
"elementsHeader": "<(js::ObjectElements*)0x10d46a9061a8, flags=[FIXED], init=0, capacity=6, length=0>",
"properties": {
"length": "(map=(js::NormalPropMap*)0x10d46a9221a8, index=0, writable, <custom-data-prop>)",
"a": "Symbol(undefined) @ (JS::Symbol*)0x16e6e8410020 (map=(js::NormalPropMap*)0x10d46a9221a8, index=1, enumerable, configurable, writable, slot=0)"
}
}
[2970618] Assertion failure: CheckGrayMarkingState(rt), at .worktree-repro/js/src/gc/GC.cpp:5304
#01: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x237989a]
#02: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x1fc2340]
#03: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x2d77b45]
#04: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x2d53006]
#05: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x2d62e71]
#06: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x2d52a57]
#07: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x2d5269b]
#08: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x2d554e1]
#09: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x2d5593f]
#10: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x3009b02]
#11: JS_ExecuteScript(JSContext*, JS::Handle<JSScript*>)[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x3009ce9]
#12: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x1d04c0e]
#13: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x1d03f09]
#14: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x1cbc4ea]
#15: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x1cb43e0]
#16: ???[/lib/x86_64-linux-gnu/libc.so.6 +0x2a575]
#17: __libc_start_main[/lib/x86_64-linux-gnu/libc.so.6 +0x2a628]
#18: ???[targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js +0x1c7a169]
#19: ??? (???:???)
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==2970618==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5c7bec51b8b2 bp 0x7fffdfe5e710 sp 0x7fffdfe5e670 T2970618)
==2970618==The signal is caused by a WRITE memory access.
==2970618==Hint: address points to the zero page.
#0 0x5c7bec51b8b2 in MOZ_CrashSequence(void*, long) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/include/mozilla/Assertions.h:261:3
#1 0x5c7bec51b8b2 in js::gc::GCRuntime::collect(bool, JS::SliceBudget const&, JS::GCReason) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/gc/./../../../../../../.worktree-repro/js/src/gc/GC.cpp:5304:7
#2 0x5c7bec16433f in StartGC(JSContext*, unsigned int, JS::Value*) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/builtin/./../../../../../../.worktree-repro/js/src/builtin/TestingFunctions.cpp:3222:10
#3 0x5c7becf19b44 in CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:498:13
#4 0x5c7becef5005 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:594:12
#5 0x5c7becf04e70 in js::CallFromStack(JSContext*, JS::CallArgs const&, js::CallReason) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:666:10
#6 0x5c7becf04e70 in js::Interpret(JSContext*, js::RunState&) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:3280:16
#7 0x5c7becef4a56 in MaybeEnterInterpreterTrampoline(JSContext*, js::RunState&) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:392:10
#8 0x5c7becef469a in js::RunScript(JSContext*, js::RunState&) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:468:13
#9 0x5c7becef74e0 in js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, js::AbstractFramePtr, JS::MutableHandle<JS::Value>) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:858:10
#10 0x5c7becef793e in js::Execute(JSContext*, JS::Handle<JSScript*>, JS::Handle<JSObject*>, JS::MutableHandle<JS::Value>) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/spidermonkey/js/src/vm/Interpreter.cpp:888:10
#11 0x5c7bed1abb01 in ExecuteScript(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSScript*>, JS::MutableHandle<JS::Value>) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/./../../../../../../.worktree-repro/js/src/vm/CompilationAndEvaluation.cpp:544:10
#12 0x5c7bed1abce8 in JS_ExecuteScript(JSContext*, JS::Handle<JSScript*>) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/vm/./../../../../../../.worktree-repro/js/src/vm/CompilationAndEvaluation.cpp:568:10
#13 0x5c7bebea6c0d in RunFile(JSContext*, char const*, _IO_FILE*, CompileUtf8, bool, bool) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/shell/./../../../../../../.worktree-repro/js/src/shell/js.cpp:1429:10
#14 0x5c7bebea5f08 in Process(JSContext*, char const*, bool, FileKind) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/shell/./../../../../../../.worktree-repro/js/src/shell/js.cpp
#15 0x5c7bebe5e4e9 in ProcessArgs(JSContext*, js::cli::OptionParser*) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/shell/./../../../../../../.worktree-repro/js/src/shell/js.cpp:12197:10
#16 0x5c7bebe5e4e9 in Shell(JSContext*, js::cli::OptionParser*) targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/shell/./../../../../../../.worktree-repro/js/src/shell/js.cpp:12476:12
#17 0x5c7bebe563df in main targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/js/src/shell/./../../../../../../.worktree-repro/js/src/shell/js.cpp:12909:12
#18 0x7d62811b0574 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#19 0x7d62811b0627 in __libc_start_main csu/../csu/libc-start.c:360:3
#20 0x5c7bebe1c168 in _start (targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/bin/js+0x1c7a168) (BuildId: 0b63a60c4f7a9405fc4bcaed4bebea83)
==2970618==Register values:
rax = 0x0000000000000000 rbx = 0x00007d6280d387b8 rcx = 0x00000000000014b8 rdx = 0x0000000000000000
rdi = 0x00007d62813bc780 rsi = 0x0000000000000000 rbp = 0x00007fffdfe5e710 rsp = 0x00007fffdfe5e670
r8 = 0x0000000000000000 r9 = 0x0000000000000000 r10 = 0x0000000000000000 r11 = 0x00007d6281181880
r12 = 0x0000000000000008 r13 = 0x0000000000000007 r14 = 0x0000000000000000 r15 = 0x00007fffdfe5e760
UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV targets/spidermonkey/artifacts/builds/reproducebuild-9f2e8c25f0b4/dist/include/mozilla/Assertions.h:261:3 in MOZ_CrashSequence(void*, long)
==2970618==ABORTING
Updated•3 months ago
|
Comment 1•3 months ago
|
||
The rating assigned by our bug rating tool (currently under development) is:
Rating: sec-moderate
Explanation: SpiderMonkey JS-shell fuzzing report. The crash is the diagnostic assertion CheckGrayMarkingState (GC.cpp:5304), a gray-marking verifier that only runs under gczeal("CheckGrayMarking"); it reports a black->gray edge from a live (black) Array to a gray JS::Symbol via an objectDynamicSlots edge. The immediate effect is a controlled/safe MOZ_CRASH abort, not attacker-controlled memory corruption. The repro relies on shell-only testing functions (grayRoot(), gczeal, verifyprebarriers, schedulezone, startgc); grayRoot() simulates the browser's cycle-collector gray roots. The underlying condition (a Symbol left gray after ExposeObjectToActiveJS/UnmarkGrayGCThingRecursively) appears to be a genuine GC gray-marking/atoms-zone consistency bug that warrants GC-team investigation, and gray-marking invariant violations can underlie cycle-collector use-after-free. However, web-content reachability and an actual UAF (the Symbol is in the atoms zone and would still be traced from the live black array) are not demonstrated. Rated sec-moderate as a cautious estimate: a real gray-marking correctness bug with potential but unproven UAF impact.
Please ni? me if you disagree with this rating.
Updated•3 months ago
|
| Assignee | ||
Comment 2•3 months ago
|
||
This is a problem with pre-barrier verification which is not present in release builds.
| Assignee | ||
Comment 3•3 months ago
|
||
Pre-barrier verification turns on pre-barriers to check that targets of removed
GC edges are marked black but it doesn't mark through these edges as would
happen in a normal GC. Instead it clears simply the mark stack at the end.
This means that gray unmarking that otherwise would have happened is skipped
leaving the gray marking state invalid.
The patch set a flag after verification so that gray marking checks will be
skipped until the state becomes valid after a full GC.
Comment 5•2 months ago
|
||
| bugherder | ||
Comment 6•2 months ago
|
||
per comment 2 this is not a security issue.
Description
•