Closed Bug 1535609 Opened 1 year ago Closed 1 year ago

Crash [@ ShouldMark<JSObject*>] or Crash [@ js::wasm::UnboxAnyRef] Assertion failure: addr % CellAlignBytes == 0, at gc/Cell.h:265 with wasm

Categories

(Core :: Javascript: WebAssembly, defect, P1)

x86_64
Linux
defect

Tracking

()

VERIFIED FIXED
mozilla68
Tracking Status
firefox-esr60 --- unaffected
firefox66 --- unaffected
firefox67 --- disabled
firefox68 --- verified

People

(Reporter: decoder, Assigned: lth)

References

Details

(7 keywords, Whiteboard: [jsbugmon:update])

Crash Data

Attachments

(4 files)

The following testcase crashes on mozilla-central revision 4d15e90af575 (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --disable-profiling --disable-debug --enable-optimize, run with --fuzzing-safe --cpu-count=2 --ion-offthread-compile=off):

See attachment.

Backtrace:

received signal SIGSEGV, Segmentation fault.
#0  ShouldMark<JSObject*> (obj=0x2f2f2f2f2f2f2f2c, gcmarker=0x7ffff5f1c0f8) at js/src/gc/Marking.cpp:694
#1  DoMarking<JSObject> (gcmarker=0x7ffff5f1c0f8, thing=0x2f2f2f2f2f2f2f2c) at js/src/gc/Marking.cpp:727
#2  0x000055555602bd1c in js::TraceEdge<JSObject*> (name=0x5555565c565c "wasm ref/anyref global", thingp=<optimized out>, trc=0x7ffff5f1c0f8) at js/src/gc/Tracer.h:116
#3  js::TraceNullableEdge<JSObject*> (name=0x5555565c565c "wasm ref/anyref global", thingp=<optimized out>, trc=0x7ffff5f1c0f8) at js/src/gc/Tracer.h:133
#4  js::wasm::Instance::tracePrivate (this=0x7ffff5affbe0, trc=0x7ffff5f1c0f8) at js/src/wasm/WasmInstance.cpp:1362
#5  0x0000555555d7ccf2 in js::Class::doTrace (this=<optimized out>, obj=0x2d08219a4160, trc=0x7ffff5f1c0f8) at dist/include/js/Class.h:872
#6  CallTraceHook<js::GCMarker::processMarkStackTop(js::SliceBudget&)::<lambda(auto:20)> > (check=CheckGeneration::DoChecks, obj=0x2d08219a4160, trc=0x7ffff5f1c0f8, f=<...>) at js/src/gc/Marking.cpp:1545
#7  js::GCMarker::processMarkStackTop (this=this@entry=0x7ffff5f1c0f8, budget=...) at js/src/gc/Marking.cpp:1798
#8  0x0000555555d5a496 in js::GCMarker::markUntilBudgetExhausted (this=this@entry=0x7ffff5f1c0f8, budget=...) at js/src/gc/Marking.cpp:1598
#9  0x0000555555d5c67a in js::GCMarker::markUntilBudgetExhausted (budget=..., this=0x7ffff5f1c0f8) at dist/include/js/SliceBudget.h:77
#10 js::gc::GCRuntime::markUntilBudgetExhausted (this=this@entry=0x7ffff5f1b4f0, sliceBudget=..., phase=phase@entry=js::gcstats::PhaseKind::MARK) at js/src/gc/GC.cpp:5849
#11 0x0000555555d6d1aa in js::gc::GCRuntime::incrementalSlice (this=this@entry=0x7ffff5f1b4f0, budget=..., reason=reason@entry=JS::GCReason::DEBUG_GC, session=...) at js/src/gc/GC.cpp:7002
#12 0x0000555555d6d93b in js::gc::GCRuntime::gcCycle (this=this@entry=0x7ffff5f1b4f0, nonincrementalByAPI=nonincrementalByAPI@entry=true, budget=..., reason=reason@entry=JS::GCReason::DEBUG_GC) at js/src/gc/GC.cpp:7398
#13 0x0000555555d6db79 in js::gc::GCRuntime::collect (this=this@entry=0x7ffff5f1b4f0, nonincrementalByAPI=nonincrementalByAPI@entry=true, budget=..., reason=reason@entry=JS::GCReason::DEBUG_GC) at js/src/gc/GC.cpp:7569
#14 0x0000555555d6de48 in js::gc::GCRuntime::gc (this=this@entry=0x7ffff5f1b4f0, gckind=gckind@entry=GC_NORMAL, reason=JS::GCReason::DEBUG_GC) at js/src/gc/GC.cpp:7657
#15 0x0000555555d6ee1a in js::gc::GCRuntime::runDebugGC (this=this@entry=0x7ffff5f1b4f0) at js/src/gc/GC.cpp:8195
#16 0x0000555555d6ef18 in js::gc::GCRuntime::gcIfNeededAtAllocation (this=0x7ffff5f1b4f0, cx=0x7ffff5f16000) at js/src/gc/Allocator.cpp:337
#17 0x0000555555d820d9 in js::gc::GCRuntime::checkAllocatorState<(js::AllowGC)1> (this=<optimized out>, cx=0x7ffff5f16000, kind=<optimized out>) at js/src/gc/Allocator.cpp:301
#18 0x0000555555d82dfd in js::Allocate<js::BaseShape, (js::AllowGC)1> (cx=cx@entry=0x7ffff5f16000) at js/src/gc/Allocator.cpp:245
#19 0x0000555555b11c9d in js::BaseShape::getUnowned (cx=cx@entry=0x7ffff5f16000, base=...) at js/src/vm/Shape.cpp:1578
#20 0x0000555555b12421 in js::EmptyShape::getInitialShape (cx=cx@entry=0x7ffff5f16000, clasp=clasp@entry=0x5555574d8fc0 <js::SavedFrame::protoClass_>, proto=..., nfixed=0, objectFlags=0) at js/src/vm/Shape.cpp:2146
#21 0x00005555559ec161 in NewObject (cx=cx@entry=0x7ffff5f16000, group=group@entry=..., kind=kind@entry=js::gc::AllocKind::OBJECT0_BACKGROUND, newKind=newKind@entry=js::SingletonObject, initialShapeFlags=initialShapeFlags@entry=0) at js/src/vm/JSObject.cpp:789
#22 0x00005555559ec9ce in js::NewObjectWithGivenTaggedProto (cx=0x7ffff5f16000, clasp=0x5555574d8fc0 <js::SavedFrame::protoClass_>, proto=..., allocKind=<optimized out>, newKind=js::SingletonObject, initialShapeFlags=<optimized out>) at js/src/vm/JSObject.cpp:868
#23 0x00005555559bfb75 in js::NewObjectWithGivenProto (newKind=js::SingletonObject, proto=..., clasp=0x5555574d8fc0 <js::SavedFrame::protoClass_>, cx=0x7ffff5f16000) at js/src/vm/JSObject-inl.h:461
#24 js::NewNativeObjectWithGivenProto (newKind=js::SingletonObject, proto=..., clasp=0x5555574d8fc0 <js::SavedFrame::protoClass_>, cx=0x7ffff5f16000) at js/src/vm/NativeObject-inl.h:691
#25 CreateBlankProto (cx=cx@entry=0x7ffff5f16000, clasp=clasp@entry=0x5555574d8fc0 <js::SavedFrame::protoClass_>, proto=..., proto@entry=...) at js/src/vm/GlobalObject.cpp:770
#26 0x00005555559d1302 in js::GlobalObject::createBlankPrototype (cx=0x7ffff5f16000, global=..., clasp=clasp@entry=0x5555574d8fc0 <js::SavedFrame::protoClass_>) at js/src/vm/GlobalObject.cpp:787
#27 0x0000555555a8d47b in js::GenericCreatePrototype<js::SavedFrame> (cx=<optimized out>, key=<optimized out>) at js/src/vm/GlobalObject.h:967
#28 0x00005555559d06a0 in js::GlobalObject::resolveConstructor (cx=cx@entry=0x7ffff5f16000, global=..., key=key@entry=JSProto_SavedFrame, mode=mode@entry=js::GlobalObject::IfClassIsDisabled::Throw) at js/src/vm/GlobalObject.cpp:215
#29 0x0000555555a7a8d2 in js::GlobalObject::ensureConstructor (key=JSProto_SavedFrame, global=..., cx=0x7ffff5f16000) at js/src/vm/GlobalObject.h:169
#30 js::GlobalObject::getOrCreateSavedFramePrototype (global=..., cx=0x7ffff5f16000) at js/src/vm/GlobalObject.h:404
#31 js::SavedFrame::create (cx=cx@entry=0x7ffff5f16000) at js/src/vm/SavedStacks.cpp:553
#32 0x0000555555a89806 in js::SavedStacks::createFrameFromLookup (this=this@entry=0x7ffff59725b0, cx=cx@entry=0x7ffff5f16000, lookup=lookup@entry=...) at js/src/vm/SavedStacks.cpp:1667
#33 0x0000555555a8991e in js::SavedStacks::getOrCreateSavedFrame (this=this@entry=0x7ffff59725b0, cx=cx@entry=0x7ffff5f16000, lookup=lookup@entry=...) at js/src/vm/SavedStacks.cpp:1653
#34 0x0000555555a8b438 in js::SavedStacks::insertFrames(JSContext*, JS::MutableHandle<js::SavedFrame*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) (this=this@entry=0x7ffff59725b0, cx=0x7ffff5f16000, frame=..., capture=<...>) at js/src/vm/SavedStacks.cpp:1508
#35 0x0000555555a8bc06 in js::SavedStacks::saveCurrentStack(JSContext*, JS::MutableHandle<js::SavedFrame*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) (this=0x7ffff59725b0, cx=cx@entry=0x7ffff5f16000, frame=..., frame@entry=..., capture=capture@entry=<...>) at js/src/vm/SavedStacks.cpp:1248
#36 0x0000555555c05ee9 in JS::CaptureCurrentStack(JSContext*, JS::MutableHandle<JSObject*>, mozilla::Variant<JS::AllFrames, JS::MaxFrames, JS::FirstSubsumedFrame>&&) (cx=cx@entry=0x7ffff5f16000, stackp=stackp@entry=..., capture=capture@entry=<...>) at js/src/jsapi.cpp:6054
#37 0x0000555555c30f22 in CaptureStack (stack=..., cx=0x7ffff5f16000) at js/src/jsexn.cpp:320
#38 js::ErrorToException (cx=cx@entry=0x7ffff5f16000, reportp=reportp@entry=0x7fffffffc8d0, callback=<optimized out>, callback@entry=0x5555559d92a0 <js::GetErrorMessage(void*, unsigned int)>, userRef=userRef@entry=0x0) at js/src/jsexn.cpp:664
#39 0x00005555559eb42f in ReportError (userRef=0x0, callback=0x5555559d92a0 <js::GetErrorMessage(void*, unsigned int)>, reportp=0x7fffffffc8d0, cx=0x7ffff5f16000) at js/src/vm/JSContext.cpp:242
#40 js::ReportErrorNumberVA (cx=0x7ffff5f16000, flags=flags@entry=0, callback=0x5555559d92a0 <js::GetErrorMessage(void*, unsigned int)>, userRef=0x0, errorNumber=<optimized out>, argumentsType=argumentsType@entry=js::ArgumentsAreUTF8, ap=0x7fffffffc990) at js/src/vm/JSContext.cpp:825
#41 0x0000555555c02f5c in JS_ReportErrorNumberUTF8VA (cx=<optimized out>, errorCallback=<optimized out>, userRef=<optimized out>, errorNumber=<optimized out>, ap=ap@entry=0x7fffffffc990) at js/src/jsapi.cpp:4843
#42 0x0000555555c02ffa in JS_ReportErrorNumberUTF8 (cx=cx@entry=0x7ffff5f16000, errorCallback=errorCallback@entry=0x5555559d92a0 <js::GetErrorMessage(void*, unsigned int)>, userRef=userRef@entry=0x0, errorNumber=errorNumber@entry=1) at js/src/jsapi.cpp:4832
#43 0x00005555559dd541 in js::ReportIsNotDefined (id=..., cx=0x7ffff5f16000) at js/src/vm/JSContext.cpp:872
#44 js::ReportIsNotDefined (cx=0x7ffff5f16000, name=...) at js/src/vm/JSContext.cpp:878
#45 0x000055555588ecf8 in js::FetchName<(js::GetNameMode)0> (cx=0x7ffff5f16000, receiver=..., holder=..., name=..., prop=..., vp=...) at js/src/vm/Interpreter-inl.h:181
#46 0x000055555588651e in js::GetEnvironmentName<(js::GetNameMode)0> (vp=..., name=..., envChain=..., cx=<optimized out>) at js/src/vm/Interpreter-inl.h:256
#47 GetNameOperation (vp=..., pc=<optimized out>, fp=<optimized out>, cx=<optimized out>) at js/src/vm/Interpreter.cpp:241
#48 Interpret (cx=0x7ffff5f16000, state=...) at js/src/vm/Interpreter.cpp:3225

[...]
#58 main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at js/src/shell/js.cpp:11264
rax 0x2f2f2f2f2f200000 3399988123388608512
rbx 0x7ffff58e59a0 140737313135008
rcx 0x1482c 84012
rdx 0x5555565c565c 93825009473116
rsi 0x2f2f2f2f2f2f2f2c 3399988123389603628
rdi 0x7ffff5f1c0f8 140737319649528
rbp 0x7ffff5f1c0f8 140737319649528
rsp 0x7fffffffb248 140737488335432
r8 0x1 1
r9 0x100000000000 17592186044416
r10 0x100100100100 17596482060544
r11 0x0 0
r12 0x7ffff5affbe0 140737315339232
r13 0x5555565c565c 93825009473116
r14 0x7ffff58e59c8 140737313135048
r15 0x7fffffffb2b0 140737488335536
rip 0x555555d78129 <DoMarking<JSObject>(js::GCMarker*, JSObject*)+9>
=> 0x555555d78129 <DoMarking<JSObject>(js::GCMarker*, JSObject*)+9>: mov 0xffff8(%rax),%rdx
0x555555d78130 <DoMarking<JSObject>(js::GCMarker*, JSObject*)+16>: cmp %rdx,(%rdi)

Marking s-s due to GC and potential use-after-free according to crash address.

Attached file Testcase
JSBugMon: Bisection requested, result:
autoBisect shows this is probably related to the following changeset:

The first bad revision is:
changeset:   https://hg.mozilla.org/mozilla-central/rev/8085449bd426
user:        Lars T Hansen
date:        Fri Mar 01 09:55:31 2019 +0100
summary:     Bug 1488205 - Repurpose the --wasm-gc switch for GC. r=jseward

This iteration took 537.254 seconds to run.
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:update]

Lars, any thoughts?

Blocks: 1488205
Flags: needinfo?(lhansen)
Attached file Valgrind complaints

This fails with both --wasm-compiler=baseline and =ion. No other flags needed.

Julian's out until the end of the month so I'll look at this. It could be related to bug 1533932 so we should definitely apply that patch before testing.

Flags: needinfo?(lhansen)

Valgrind's a red herring too, just a regular debug shell will crash with the test case without any flags at all.

Assignee: nobody → lhansen
Status: NEW → ASSIGNED
Priority: -- → P1

The patch for bug 1533932 does not fix the problem.

Attached file test1535609.js

Slightly simpler and less confusing test case. The bug has something to do with either write barriers for nonexported wasm globals, or wasm boxed anyrefs, but it's a problem even for anyrefs that don't reference gc values, so it's not a problem with tracing through the anyrefs per se.

Oh dear, the exportArgs need to be rooted in callExport() now.

This is probably roughly right, though I worry that creating the second array unconditionally is going to hurt performance too much - hard to say if it matters, this is the slow path after all, and pointer-free APIs will not come this way as soon as the JS is jitted. Will try to benchmark a little.

Attachment #9052043 - Attachment description: Bug 1535609 - Root pointer args in callExport (WIP) → Bug 1535609 - Root pointer args in callExport. r?bbouvier

BTW, this is a gc bug so it's s-s, but it's nightly-only and will not need an uplift, and there is no web content using the feature, so we should be able to just land.

Keywords: sec-low

Talked to Lars, adjusting sec rating based on that.

Group: javascript-core-security → core-security-release
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla68
Status: RESOLVED → VERIFIED
JSBugMon: This bug has been automatically verified fixed.

Hi Lars, since 67 is marked as affected, should we consider uplifting this to Beta67?

Flags: needinfo?(lhansen)

This bug manifests as nightly-only, no uplift is necessary.

Flags: needinfo?(lhansen)
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.