Closed Bug 1470921 Opened 6 years ago Closed 6 years ago

Crash [@ AssertShouldMarkInZone]

Categories

(Core :: JavaScript Engine, defect, P1)

x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
mozilla63
Tracking Status
firefox-esr52 --- unaffected
firefox-esr60 --- disabled
firefox61 --- disabled
firefox62 --- disabled
firefox63 --- fixed

People

(Reporter: decoder, Assigned: sfink)

References

Details

(5 keywords, Whiteboard: [jsbugmon:][post-cristsmash-triage])

Crash Data

Attachments

(2 files)

The following testcase crashes on mozilla-central revision d69b7fc884fb (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --disable-profiling --enable-debug --enable-optimize, run with --fuzzing-safe --cpu-count=2 --ion-offthread-compile=off --baseline-eager --ion-eager --ion-check-range-analysis --ion-extra-checks --disable-oom-functions --nursery-strings=on): See attachment. Backtrace: received signal SIGSEGV, Segmentation fault. AssertShouldMarkInZone (str=<optimized out>) at js/src/gc/Marking.cpp:362 #0 AssertShouldMarkInZone (str=<optimized out>) at js/src/gc/Marking.cpp:362 #1 0x0000000000f888e5 in js::GCMarker::mark<JSString> (this=this@entry=0x7ffff5f1a6c8, thing=thing@entry=0x7ffff5900008) at js/src/gc/Marking.cpp:908 #2 0x0000000000f89268 in js::GCMarker::eagerlyMarkChildren (this=0x7ffff5f1a6c8, rope=0x7ffff4c89970) at js/src/gc/Marking.cpp:1117 #3 0x0000000000f768b4 in js::GCMarker::eagerlyMarkChildren (str=<optimized out>, this=<optimized out>) at js/src/gc/Marking.cpp:1036 #4 js::GCMarker::markAndScan<JSString> (this=<optimized out>, thing=<optimized out>) at js/src/gc/Marking.cpp:794 #5 0x0000000000f89659 in js::GCMarker::markAndScan<JSString> (thing=<optimized out>, this=<optimized out>) at js/src/gc/Marking.cpp:865 #6 js::GCMarker::traverse<JSString*> (thing=<optimized out>, this=<optimized out>) at js/src/gc/Marking.cpp:797 #7 js::GCMarker::traverseEdge<JSObject*, JSString> (this=<optimized out>, source=<optimized out>, target=<optimized out>) at js/src/gc/Marking.cpp:864 #8 0x0000000000f9acad in TraverseObjectFunctor::operator()<JSString*> (this=<optimized out>, thing=<optimized out>, src=<optimized out>, gcmarker=<optimized out>) at js/src/gc/Marking.cpp:1449 #9 VisitTraceList<TraverseObjectFunctor, js::GCMarker*, JSObject*&>(const int32_t *, uint8_t *, <unknown type in /mnt/LangFuzz/work/builds/debug64/dist/bin/js, CU 0x7cb4043, DIE 0x7e27bf1>, JSObject *&) (traceList=0x7ffff4c22e7c, memory=0x7fffffff8e20 "Ȧ\361\365\377\177", memory@entry=0x7ffff4c22e90 "\300.\302\364\377\177", f=...) at js/src/gc/Marking.cpp:1509 #10 0x0000000000f9bb3e in CallTraceHook<TraverseObjectFunctor, js::GCMarker*, JSObject*&> (check=CheckGeneration::DoChecks, obj=0x7ffff4c22e80, trc=0x7ffff4c22e80, f=...) at js/src/gc/Marking.cpp:1490 #11 js::GCMarker::processMarkStackTop (this=this@entry=0x7ffff5f1a6c8, budget=...) at js/src/gc/Marking.cpp:1733 #12 0x0000000000f87025 in js::GCMarker::drainMarkStack (this=this@entry=0x7ffff5f1a6c8, budget=...) at js/src/gc/Marking.cpp:1543 #13 0x0000000000f08ccb in js::gc::GCRuntime::drainMarkStack (this=this@entry=0x7ffff5f19710, sliceBudget=..., phase=phase@entry=js::gcstats::PhaseKind::MARK) at js/src/gc/GC.cpp:5959 #14 0x0000000000f38c6e in js::gc::GCRuntime::incrementalCollectSlice (this=this@entry=0x7ffff5f19710, budget=..., reason=reason@entry=JS::gcreason::ALLOC_TRIGGER, session=...) at js/src/gc/GC.cpp:7168 #15 0x0000000000f39ff1 in js::gc::GCRuntime::gcCycle (this=this@entry=0x7ffff5f19710, nonincrementalByAPI=nonincrementalByAPI@entry=false, budget=..., reason=reason@entry=JS::gcreason::ALLOC_TRIGGER) at js/src/gc/GC.cpp:7532 #16 0x0000000000f3a78d in js::gc::GCRuntime::collect (this=this@entry=0x7ffff5f19710, nonincrementalByAPI=nonincrementalByAPI@entry=false, budget=..., reason=reason@entry=JS::gcreason::ALLOC_TRIGGER) at js/src/gc/GC.cpp:7678 #17 0x0000000000f3ada2 in js::gc::GCRuntime::gcSlice (this=0x7ffff5f19710, reason=JS::gcreason::ALLOC_TRIGGER, millis=0) at js/src/gc/GC.cpp:7769 #18 0x0000000000f3ae6e in js::gc::GCRuntime::gcIfRequested (this=0x7ffff5f19710) at js/src/gc/GC.cpp:7946 #19 0x0000000000c6f4d4 in HandleInterrupt (cx=0x7ffff5f17000, invokeCallback=false) at js/src/vm/Runtime.cpp:427 #20 0x00000e9b67cfc6d6 in ?? () #21 0xfffe2d2d2d2d2d2d in ?? () #22 0x00007fffffff97f8 in ?? () #23 0x0000000000000000 in ?? () rax 0xfffe2f2f2f2f2f2f -511070251831505 rbx 0x7ffff5900008 140737313243144 rcx 0x1132e 70446 rdx 0x0 0 rsi 0x7ffff5900008 140737313243144 rdi 0x7ffff59fffe8 140737314291688 rbp 0x7fffffff8980 140737488324992 rsp 0x7fffffff8980 140737488324992 r8 0x7fffffff89a0 140737488325024 r9 0x7ffff5200000 140737305903104 r10 0x0 0 r11 0x206 518 r12 0x3 3 r13 0x7ffff5f1a6c8 140737319642824 r14 0x7ffff5f1a6e0 140737319642848 r15 0x7ffff5900008 140737313243144 rip 0xf6fe39 <AssertShouldMarkInZone(JSString*)+9> => 0xf6fe39 <AssertShouldMarkInZone(JSString*)+9>: mov 0x10(%rax),%edx 0xf6fe3c <AssertShouldMarkInZone(JSString*)+12>: test %edx,%edx Test is pretty fragile, doesn't reduce properly any further without breaking. Might also be intermittent. Marking s-s due to 0x2f pattern in crash address.
Attached file Testcase (deleted) —
JSBugMon: Cannot process bug: Unable to automatically reproduce, please track manually.
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:bisect]
Whiteboard: [jsbugmon:bisect] → [jsbugmon:]
Needinfo Steve for --nursery-strings=on.
Flags: needinfo?(sphink)
Keywords: sec-high
On my first run (without any of the given options, but with a build that defaults nursery strings to on), I hit a different assert: Assertion failure: cx->isExceptionPending() (Thunk execution failed but no exception was raised - missing call to js::ReportOutOfMemory()?), at /home/sfink/src/mozilla2/js/src/builtin/TestingFunctions.cpp:1797 I'll probably fix it first. But I will definitely try to reproduce the problem originally reported here; it's very similar to the crash I see in automation for nursery strings right now.
Steve - are you taking this bug (or did you file another one for the assertion you mention in comment 4?)
Assignee: nobody → sphink
Flags: needinfo?(sphink)
Priority: -- → P1
Chatting with sfink right now. If this only happens for --nursery-strings=on then it probably doesn't need P1 or security, since that's not yet enabled.
Blocks: 1442481
What's happening here is that we are creating a string, nursery strings are enabled, so we try to allocate it in the nursery. But the nursery is full, so we do a minor GC to clear it out. During that minor GC, we decide to stop nursery-allocating strings -- but then when we continue the allocation, we don't re-check that flag, and happily allocate the string in the nursery. Later, we compile some JIT code that concatenates two strings together. The macroassembler sees that nursery strings are disabled, so it doesn't emit post barriers. In short, very much the exact sort of thing that fuzzing is great at uncovering and I wouldn't have stumbled across myself in 100 years. I am really glad this wasn't too timing-sensitive to reduce.
Comment on attachment 9001801 [details] [diff] [review] Re-check whether nursery strings are enabled after collecting during allocation Review of attachment 9001801 [details] [diff] [review]: ----------------------------------------------------------------- Nice.
Attachment #9001801 - Flags: review?(jcoppeard) → review+
Blocks: 903519
Group: javascript-core-security → core-security-release
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla63
Flags: qe-verify-
Whiteboard: [jsbugmon:] → [jsbugmon:][post-cristsmash-triage]
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: