Closed Bug 1408584 Opened 4 years ago Closed 4 years ago

Assertion failure: aInitialCapacity != 0, at mozilla/BufferList.h:131 with clonebuffer


(Core :: JavaScript Engine, defect, P1)




Tracking Status
firefox-esr52 --- wontfix
firefox56 --- wontfix
firefox57 --- wontfix
firefox58 --- fixed


(Reporter: decoder, Assigned: sfink)



(Keywords: assertion, bugmon, testcase, Whiteboard: [jsbugmon:update])


(1 file)

The following testcase crashes on mozilla-central revision 196dadb2fe50 (build with --enable-posix-nspr-emulation --enable-valgrind --enable-gczeal --disable-tests --enable-stdcxx-compat --disable-profiling --enable-debug --enable-optimize, run with --fuzzing-safe min.js):

function byteArray(str) {}
var mutated = byteArray(serialize(new Date(NaN)).clonebuffer);
var a = [1 / 0, -1 / 0, ];
for (var i = 0; i < a.length; i++) {
    var n = a[i];
    var nbuf = serialize(n);
    nbuf.clonebuffer = String.fromCharCode.apply(null, mutated);


received signal SIGSEGV, Segmentation fault.
#0  0x00000000008e161e in mozilla::BufferList<js::SystemAllocPolicy>::Init (aInitialCapacity=<optimized out>, aInitialSize=<optimized out>, this=0x7ffff4297b60) at mozilla/BufferList.h:131
#1  CloneBufferObject::setCloneBuffer_impl (cx=cx@entry=0x7ffff6955000, args=...) at js/src/builtin/TestingFunctions.cpp:2757
#2  0x00000000008e176b in JS::CallNonGenericMethod<&CloneBufferObject::is, &CloneBufferObject::setCloneBuffer_impl> (args=..., cx=0x7ffff6955000) at js/CallNonGenericMethod.h:100
#3  CloneBufferObject::setCloneBuffer (cx=0x7ffff6955000, argc=<optimized out>, vp=<optimized out>) at js/src/builtin/TestingFunctions.cpp:2775
#4  0x000000000056153d in js::CallJSNative (cx=0x7ffff6955000, native=0x8e16d0 <CloneBufferObject::setCloneBuffer(JSContext*, unsigned int, JS::Value*)>, args=...) at js/src/jscntxtinlines.h:291
#5  0x0000000000555c9f in js::InternalCallOrConstruct (cx=cx@entry=0x7ffff6955000, args=..., construct=construct@entry=js::NO_CONSTRUCT) at js/src/vm/Interpreter.cpp:482
#6  0x000000000055607d in InternalCall (cx=cx@entry=0x7ffff6955000, args=...) at js/src/vm/Interpreter.cpp:531
#7  0x00000000005561e0 in js::Call (cx=cx@entry=0x7ffff6955000, fval=..., fval@entry=..., thisv=..., thisv@entry=..., args=..., rval=...) at js/src/vm/Interpreter.cpp:550
#8  0x0000000000556762 in js::CallSetter (cx=0x7ffff6955000, thisv=..., thisv@entry=..., setter=setter@entry=..., v=v@entry=...) at js/src/vm/Interpreter.cpp:679
#9  0x0000000000bddafe in SetExistingProperty (cx=0x7ffff6955000, obj=..., obj@entry=..., id=..., id@entry=..., v=v@entry=..., receiver=receiver@entry=..., pobj=..., pobj@entry=..., prop=..., result=...) at js/src/vm/NativeObject.cpp:2732
#10 0x0000000000bfca2f in js::NativeSetProperty<(js::QualifiedBool)1> (cx=cx@entry=0x7ffff6955000, obj=..., id=id@entry=..., value=..., value@entry=..., receiver=..., receiver@entry=..., result=...) at js/src/vm/NativeObject.cpp:2768
#11 0x000000000055e43c in js::SetProperty (cx=0x7ffff6955000, obj=..., id=..., v=..., receiver=..., result=...) at js/src/vm/NativeObject.h:1615
#12 0x000000000054a7e7 in SetPropertyOperation (rval=..., id=..., lval=..., op=<optimized out>, cx=0x7ffff6955000) at js/src/vm/Interpreter.cpp:269
#13 Interpret (cx=0x7ffff6955000, state=...) at js/src/vm/Interpreter.cpp:2873
#23 main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at js/src/shell/js.cpp:8892
rax	0x0	0
rbx	0x7fffffffd1a0	140737488343456
rcx	0x7ffff6c28a2d	140737333332525
rdx	0x0	0
rsi	0x7ffff6ef7770	140737336276848
rdi	0x7ffff6ef6540	140737336272192
rbp	0x7fffffffd190	140737488343440
rsp	0x7fffffffd110	140737488343312
r8	0x7ffff6ef7770	140737336276848
r9	0x7ffff7fe4740	140737354024768
r10	0x58	88
r11	0x7ffff6b9f750	140737332770640
r12	0x7ffff4297b60	140737289747296
r13	0x7fffffffd140	140737488343360
r14	0x7ffff69560e8	140737330372840
r15	0x0	0
rip	0x8e161e <CloneBufferObject::setCloneBuffer_impl(JSContext*, JS::CallArgs const&)+1150>
=> 0x8e161e <CloneBufferObject::setCloneBuffer_impl(JSContext*, JS::CallArgs const&)+1150>:	movl   $0x0,(%eax)
   0x8e1625 <CloneBufferObject::setCloneBuffer_impl(JSContext*, JS::CallArgs const&)+1157>:	ud2
Whiteboard: [jsbugmon:update,bisect] → [jsbugmon:update]
JSBugMon: Bisection requested, result:
autoBisect shows this is probably related to the following changeset:

The first bad revision is:
user:        Kan-Ru Chen
date:        Fri Apr 22 18:04:20 2016 +0800
summary:     Bug 1264642 - Part 4. Use BufferList to replace raw buffers in StructuredClone. r=baku r=billm r=jorendorff

This iteration took 225.980 seconds to run.
Kan-Ru, is bug 1264642 a likely regressor?
Blocks: 1264642
Flags: needinfo?(kchen)
This looks more like I introduced a bug when adding the ability to use binary data as a structured clone buffer. The minimal test case I came up with, fwiw, is

  serialize().clonebuffer = String.fromCharCode()

I think I moved the discard of the previous buffer to after where it is needed.
Assignee: nobody → sphink
Flags: needinfo?(kchen)
That was in bug 1400466. That's my guess as to the regressor.
Oh, it's simpler than that. serialize().clonebuffer = '' would also work. Init just doesn't want an empty buffer, it seems. I'll just extend the bad length check to cover it.
Really I should remove the string interface entirely, but this particular bug is shared with the ArrayBuffer interface.
Attachment #8918965 - Flags: review?(kchen)
and this means the autodetected bug 1264642 probably is the regressor, though the bug was really in the test function.
Priority: -- → P1
Attachment #8918965 - Flags: review?(kchen) → review+
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla58
You need to log in before you can comment on or make changes to this bug.