Code: void SerializedScriptValue::transferArrayBuffers(v8::Isolate* isolate, const ArrayBufferArray& arrayBuffers, ExceptionState& exceptionState)
{
    if (!arrayBuffers.size())
        return;

    for (size_t i = 0; i < arrayBuffers.size(); ++i) {
        if (arrayBuffers[i]->isNeutered()) {
            exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " is already neutered.");
            return;
        }
    }

    OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContentsArray(arrayBuffers.size()));

    HeapHashSet<Member<DOMArrayBufferBase>> visited;
    for (size_t i = 0; i < arrayBuffers.size(); ++i) {
        if (visited.contains(arrayBuffers[i]))
            continue;
        visited.add(arrayBuffers[i]);

        if (arrayBuffers[i]->isShared()) {
            bool result = arrayBuffers[i]->shareContentsWith(contents->at(i));
            if (!result) {
                exceptionState.throwDOMException(DataCloneError, "SharedArrayBuffer at index " + String::number(i) + " could not be transferred.");
                return;
            }
        } else {
            Vector<v8::Local<v8::ArrayBuffer>, 4> bufferHandles;
            v8::HandleScope handleScope(isolate);
            acculumateArrayBuffersForAllWorlds(isolate, static_cast<DOMArrayBuffer*>(arrayBuffers[i].get()), bufferHandles);
            bool isNeuterable = true;
            for (size_t j = 0; j < bufferHandles.size(); ++j)
                isNeuterable &= bufferHandles[j]->IsNeuterable();
 
             DOMArrayBufferBase* toTransfer = arrayBuffers[i];
             if (!isNeuterable)
                toTransfer = DOMArrayBuffer::create(arrayBuffers[i]->buffer());
             bool result = toTransfer->transfer(contents->at(i));
             if (!result) {
                 exceptionState.throwDOMException(DataCloneError, "ArrayBuffer at index " + String::number(i) + " could not be transferred.");
                return;
            }

            if (isNeuterable)
                for (size_t j = 0; j < bufferHandles.size(); ++j)
                    bufferHandles[j]->Neuter();
        }

    }
    m_arrayBufferContentsArray = contents.release();
}

Vulnerability Type: DoS 
CWE ID: 
Summary: The SerializedScriptValue::transferArrayBuffers function in WebKit/Source/bindings/core/v8/SerializedScriptValue.cpp in the V8 bindings in Blink, as used in Google Chrome before 50.0.2661.94, mishandles certain array-buffer data structures, which allows remote attackers to cause a denial of service (use-after-free) or possibly have unspecified other impact via a crafted web site.
Commit Message: When we can't neuter ArrayBuffers, we can't transfer them

Instead, we need to copy

BUG=603987
R=haraken@chromium.org

Review URL: https://codereview.chromium.org/1904913002

Cr-Commit-Position: refs/heads/master@{#388719}