From 64a1612b70f806bccf6d2d70efab7ade9157b25f Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Mon, 22 Mar 2021 13:52:01 -0400 Subject: [PATCH] Fix potential use-after-free of V8TrackArrayBuffer (fixes issue #3074) --- libcef/renderer/v8_impl.cc | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/libcef/renderer/v8_impl.cc b/libcef/renderer/v8_impl.cc index fd879fa79..27a250c2b 100644 --- a/libcef/renderer/v8_impl.cc +++ b/libcef/renderer/v8_impl.cc @@ -322,7 +322,8 @@ class V8TrackArrayBuffer : public CefTrackNode { CefRefPtr release_callback) : isolate_(isolate), buffer_(buffer), - release_callback_(release_callback) { + release_callback_(release_callback), + weak_ptr_factory_(this) { DCHECK(isolate_); isolate_->AdjustAmountOfExternalAllocatedMemory( static_cast(sizeof(V8TrackArrayBuffer))); @@ -365,10 +366,16 @@ class V8TrackArrayBuffer : public CefTrackNode { return nullptr; } + base::WeakPtr GetWeakPtr() const { + return weak_ptr_factory_.GetWeakPtr(); + } + private: v8::Isolate* isolate_; void* buffer_; CefRefPtr release_callback_; + + base::WeakPtrFactory weak_ptr_factory_; }; // Object wrapped in a v8::External and passed as the Data argument to @@ -1416,15 +1423,24 @@ CefRefPtr CefV8Value::CreateArrayBuffer( V8TrackArrayBuffer* tracker = new V8TrackArrayBuffer(isolate, buffer, release_callback); + struct WeakPtrWrapper { + WeakPtrWrapper(V8TrackArrayBuffer* tracker) { + weak_ptr_ = tracker->GetWeakPtr(); + } + base::WeakPtr weak_ptr_; + }; + auto deleter = [](void* data, size_t length, void* deleter_data) { - auto* tracker = reinterpret_cast(deleter_data); - if (tracker) { - tracker->ReleaseBuffer(); + auto* wrapper = reinterpret_cast(deleter_data); + if (wrapper) { + if (wrapper->weak_ptr_) + wrapper->weak_ptr_->ReleaseBuffer(); + delete wrapper; } }; - std::unique_ptr backing = - v8::ArrayBuffer::NewBackingStore(buffer, length, deleter, tracker); + std::unique_ptr backing = v8::ArrayBuffer::NewBackingStore( + buffer, length, deleter, new WeakPtrWrapper(tracker)); v8::Local ab = v8::ArrayBuffer::New(isolate, std::move(backing));