Crash [@ js::Nursery::forwardBufferPointer] with TypedArray and use-after-free

VERIFIED FIXED in Firefox 51

Status

()

--
critical
VERIFIED FIXED
2 years ago
a year ago

People

(Reporter: decoder, Assigned: h4writer)

Tracking

(Blocks: 1 bug, 6 keywords)

Trunk
mozilla53
x86_64
Linux
crash, csectype-uaf, jsbugmon, regression, sec-critical, testcase
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(firefox-esr45 unaffected, firefox50 unaffected, firefox51 fixed, firefox52 fixed, firefox53 verified)

Details

(Whiteboard: [jsbugmon:update,bisect][post-critsmash-triage], crash signature)

(Reporter)

Description

2 years ago
The following testcase crashes on mozilla-central revision 701868bfddcb (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --enable-debug --enable-optimize, run with --fuzzing-safe):

var s = "";
gczeal(9, 1000);
var f32 = new Float32Array();
var i = 0;
for (var j = 0; j < 10000; ++j) {
    f32[i + 1] <<= f32[i] - 1;
    s += 1;
}



Backtrace:

 received signal SIGSEGV, Segmentation fault.
js::Nursery::forwardBufferPointer (this=this@entry=0x7ffff695fb20, pSlotsElems=pSlotsElems@entry=0x7fffffffc6f0) at js/src/gc/Nursery.cpp:476
#0  js::Nursery::forwardBufferPointer (this=this@entry=0x7ffff695fb20, pSlotsElems=pSlotsElems@entry=0x7fffffffc6f0) at js/src/gc/Nursery.cpp:476
#1  0x00000000006be436 in js::jit::UpdateIonJSFrameForMinorGC (trc=trc@entry=0x7fffffffbf90, frame=...) at js/src/jit/JitFrames.cpp:1150
#2  0x00000000006be655 in js::jit::UpdateJitActivationsForMinorGC (rt=rt@entry=0x7ffff695f208, trc=trc@entry=0x7fffffffbf90) at js/src/jit/JitFrames.cpp:1480
#3  0x0000000000dfa1b4 in js::Nursery::doCollection (this=this@entry=0x7ffff695fb20, rt=rt@entry=0x7ffff695f208, reason=reason@entry=JS::gcreason::DEBUG_GC, tenureCounts=...) at js/src/gc/Nursery.cpp:729
#4  0x0000000000dfee41 in js::Nursery::collect (this=this@entry=0x7ffff695fb20, rt=0x7ffff695f208, reason=reason@entry=JS::gcreason::DEBUG_GC) at js/src/gc/Nursery.cpp:585
#5  0x000000000094278d in js::gc::GCRuntime::minorGC (this=0x7ffff695fac8, reason=JS::gcreason::DEBUG_GC, phase=<optimized out>) at js/src/jsgc.cpp:6564
#6  0x000000000098793a in js::gc::GCRuntime::evictNursery (reason=JS::gcreason::DEBUG_GC, this=0x7ffff695fac8) at js/src/gc/GCRuntime.h:624
#7  js::gc::GCRuntime::gcCycle (this=this@entry=0x7ffff695fac8, nonincrementalByAPI=nonincrementalByAPI@entry=false, budget=..., reason=reason@entry=JS::gcreason::DEBUG_GC) at js/src/jsgc.cpp:6121
#8  0x00000000009883af in js::gc::GCRuntime::collect (this=0x7ffff695fac8, nonincrementalByAPI=<optimized out>, budget=..., reason=<optimized out>) at js/src/jsgc.cpp:6336
#9  0x0000000000989557 in js::gc::GCRuntime::runDebugGC (this=this@entry=0x7ffff695fac8) at js/src/jsgc.cpp:6792
#10 0x0000000000d821b8 in js::gc::GCRuntime::gcIfNeededPerAllocation (this=this@entry=0x7ffff695fac8, cx=cx@entry=0x7ffff695f000) at js/src/gc/Allocator.cpp:231
#11 0x0000000000d97269 in js::gc::GCRuntime::checkAllocatorState<(js::AllowGC)1> (this=0x7ffff695fac8, cx=0x7ffff695f000, kind=js::gc::AllocKind::STRING) at js/src/gc/Allocator.cpp:192
#12 0x0000000000da42dc in js::Allocate<JSString, (js::AllowGC)1> (cx=cx@entry=0x7ffff695f000) at js/src/gc/Allocator.cpp:143
#13 0x0000000000bd9c70 in JSRope::new_<(js::AllowGC)1> (length=2385, right=..., left=..., cx=0x7ffff695f000) at js/src/vm/String-inl.h:129
#14 js::ConcatStrings<(js::AllowGC)1> (cx=0x7ffff695f000, left=..., right=...) at js/src/vm/String.cpp:668
#15 0x00007ffff7e3f010 in ?? ()
#16 0xffffffffffffff00 in ?? ()
#17 0x00007fffffffc678 in ?? ()
#18 0x0000000000000000 in ?? ()
rax	0xfffe2f2f2f2f2f2f	-511070251831505
rbx	0x7ffff695fb20	140737330412320
rcx	0x7ffff691e0a0	140737330143392
rdx	0x7ffff691e0a0	140737330143392
rsi	0xfffe2f2f2f2f2f2f	-511070251831505
rdi	0x7ffff691e0a0	140737330143392
rbp	0x7fffffffbda0	140737488338336
rsp	0x7fffffffbd50	140737488338256
r8	0x1f	31
r9	0x1400	5120
r10	0x0	0
r11	0x7ffff068c201	140737226785281
r12	0x7fffffffc6f0	140737488340720
r13	0x7ffff0700300	140737227260672
r14	0x7fffffffc730	140737488340784
r15	0xa	10
rip	0xdf8fbc <js::Nursery::forwardBufferPointer(js::HeapSlot**)+124>
=> 0xdf8fbc <js::Nursery::forwardBufferPointer(js::HeapSlot**)+124>:	mov    (%rax),%rdx
   0xdf8fbf <js::Nursery::forwardBufferPointer(js::HeapSlot**)+127>:	mov    %rdx,(%rax)


Crash pattern indicates some form of use-after-free/poison pattern and GC is involved, marking as s-s and sec-critical.
I'm wondering if the fix we landed/backported for the other bug was wrong.
Flags: needinfo?(hv1989)
Probably affects aurora and beta too since bug 1312480 got uplifted to 51/52.
status-firefox51: --- → ?
status-firefox52: --- → ?
I backed out bug 1312480 on central, aurora and beta.
Can you confirm that this is fixed across Nightly/Aurora/Beta post-backout?
Flags: needinfo?(choller)
(Assignee)

Comment 5

2 years ago
Fixed by backout. Thanks!
Status: NEW → RESOLVED
Last Resolved: 2 years ago
Flags: needinfo?(hv1989)
Flags: needinfo?(choller)
Resolution: --- → FIXED
Assignee: nobody → hv1989
status-firefox50: --- → unaffected
status-firefox51: ? → fixed
status-firefox52: ? → fixed
status-firefox53: affected → fixed
status-firefox-esr45: --- → unaffected
Target Milestone: --- → mozilla53
Group: javascript-core-security → core-security-release
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:update,bisect][post-critsmash-triage]

Updated

2 years ago
Status: RESOLVED → VERIFIED
status-firefox53: fixed → verified

Comment 6

2 years ago
JSBugMon: This bug has been automatically verified fixed.
Keywords: csectype-uaf
Group: core-security-release
You need to log in before you can comment on or make changes to this bug.