|
@@ -0,0 +1,140 @@
|
|
|
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
+From: Andrey Belenko <[email protected]>
|
|
|
+Date: Thu, 10 Dec 2020 18:03:59 +0100
|
|
|
+Subject: Chromium backport: crbug.com/1142331
|
|
|
+
|
|
|
+M87-1
|
|
|
+Clipboard: Fix UaP in ClipboardWriter/FileReaderLoader
|
|
|
+https://chromium-review.googlesource.com/c/chromium/src/+/2536946
|
|
|
+CVE-2020-16037
|
|
|
+
|
|
|
+diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
|
|
|
+index 47bd085c92ff97e30b82f48b99bece2d3f8ffbd7..5b9d059291a8c60e33c15f5d981cea06045f4044 100644
|
|
|
+--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
|
|
|
++++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
|
|
|
+@@ -101,7 +101,7 @@ ScriptPromise ClipboardPromise::CreateForWriteText(ExecutionContext* context,
|
|
|
+
|
|
|
+ ClipboardPromise::ClipboardPromise(ExecutionContext* context,
|
|
|
+ ScriptState* script_state)
|
|
|
+- : ExecutionContextClient(context),
|
|
|
++ : ExecutionContextLifecycleObserver(context),
|
|
|
+ script_state_(script_state),
|
|
|
+ script_promise_resolver_(
|
|
|
+ MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
|
|
|
+@@ -396,12 +396,19 @@ scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() {
|
|
|
+ return GetExecutionContext()->GetTaskRunner(TaskType::kUserInteraction);
|
|
|
+ }
|
|
|
+
|
|
|
++// ExecutionContextLifecycleObserver implementation.
|
|
|
++void ClipboardPromise::ContextDestroyed() {
|
|
|
++ script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>(
|
|
|
++ DOMExceptionCode::kNotAllowedError, "Document detached."));
|
|
|
++ clipboard_writer_.Clear();
|
|
|
++}
|
|
|
++
|
|
|
+ void ClipboardPromise::Trace(Visitor* visitor) {
|
|
|
+ visitor->Trace(script_state_);
|
|
|
+ visitor->Trace(script_promise_resolver_);
|
|
|
+ visitor->Trace(clipboard_writer_);
|
|
|
+ visitor->Trace(clipboard_item_data_);
|
|
|
+- ExecutionContextClient::Trace(visitor);
|
|
|
++ ExecutionContextLifecycleObserver::Trace(visitor);
|
|
|
+ }
|
|
|
+
|
|
|
+ } // namespace blink
|
|
|
+diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
|
|
|
+index c2c7286149238db914087af743cc4c0042da95ba..65f4797b2e3eb45dd4c6f1ba8fda608d1488edef 100644
|
|
|
+--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
|
|
|
++++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
|
|
|
+@@ -24,7 +24,7 @@ class LocalFrame;
|
|
|
+ class ExecutionContext;
|
|
|
+
|
|
|
+ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
|
|
|
+- public ExecutionContextClient {
|
|
|
++ public ExecutionContextLifecycleObserver {
|
|
|
+ USING_GARBAGE_COLLECTED_MIXIN(ClipboardPromise);
|
|
|
+
|
|
|
+ public:
|
|
|
+@@ -74,6 +74,9 @@ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>,
|
|
|
+ LocalFrame* GetLocalFrame() const;
|
|
|
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
|
|
|
+
|
|
|
++ // ExecutionContextLifecycleObserver
|
|
|
++ void ContextDestroyed() override;
|
|
|
++
|
|
|
+ Member<ScriptState> script_state_;
|
|
|
+ Member<ScriptPromiseResolver> script_promise_resolver_;
|
|
|
+
|
|
|
+diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
|
|
|
+index 625934d39c613f2fce0f6a55b15f8e4a8ca604b6..7ae1f48e9dd9dac609b263462eeb15d30452ac2b 100644
|
|
|
+--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
|
|
|
++++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
|
|
|
+@@ -181,9 +181,12 @@ ClipboardWriter::ClipboardWriter(SystemClipboard* system_clipboard,
|
|
|
+ file_reading_task_runner_(promise->GetExecutionContext()->GetTaskRunner(
|
|
|
+ TaskType::kFileReading)),
|
|
|
+ system_clipboard_(system_clipboard),
|
|
|
+- raw_system_clipboard_(raw_system_clipboard) {}
|
|
|
++ raw_system_clipboard_(raw_system_clipboard),
|
|
|
++ self_keep_alive_(PERSISTENT_FROM_HERE, this) {}
|
|
|
+
|
|
|
+-ClipboardWriter::~ClipboardWriter() = default;
|
|
|
++ClipboardWriter::~ClipboardWriter() {
|
|
|
++ DCHECK(!file_reader_);
|
|
|
++}
|
|
|
+
|
|
|
+ // static
|
|
|
+ bool ClipboardWriter::IsValidType(const String& type) {
|
|
|
+@@ -209,7 +212,9 @@ void ClipboardWriter::DidFinishLoading() {
|
|
|
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
|
|
+ DOMArrayBuffer* array_buffer = file_reader_->ArrayBufferResult();
|
|
|
+ DCHECK(array_buffer);
|
|
|
++
|
|
|
+ file_reader_.reset();
|
|
|
++ self_keep_alive_.Clear();
|
|
|
+
|
|
|
+ worker_pool::PostTask(
|
|
|
+ FROM_HERE, CrossThreadBindOnce(&ClipboardWriter::DecodeOnBackgroundThread,
|
|
|
+@@ -219,6 +224,8 @@ void ClipboardWriter::DidFinishLoading() {
|
|
|
+ }
|
|
|
+
|
|
|
+ void ClipboardWriter::DidFail(FileErrorCode error_code) {
|
|
|
++ file_reader_.reset();
|
|
|
++ self_keep_alive_.Clear();
|
|
|
+ promise_->RejectFromReadOrDecodeFailure();
|
|
|
+ }
|
|
|
+
|
|
|
+diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
|
|
|
+index 45eb4bd91c0b7db4fc3648518e62f4071945a9e7..5241032714512405aaa0135ffa081ea4fa702851 100644
|
|
|
+--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
|
|
|
++++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.h
|
|
|
+@@ -10,6 +10,7 @@
|
|
|
+ #include "third_party/blink/renderer/core/fileapi/blob.h"
|
|
|
+ #include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
|
|
|
+ #include "third_party/blink/renderer/platform/heap/heap.h"
|
|
|
++#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
|
|
|
+ #include "third_party/skia/include/core/SkImage.h"
|
|
|
+
|
|
|
+ namespace blink {
|
|
|
+@@ -27,6 +28,11 @@ class RawSystemClipboard;
|
|
|
+ // (2) Decoding the blob's contents to avoid RCE in native applications that may
|
|
|
+ // take advantage of vulnerabilities in their decoders.
|
|
|
+ // (3) Writing the blob's decoded contents to the system clipboard.
|
|
|
++//
|
|
|
++// ClipboardWriter is owned only by itself and ClipboardPromise. It keeps
|
|
|
++// itself alive for the duration of FileReaderLoader's async operations using
|
|
|
++// SelfKeepAlive, and keeps itself alive afterwards during cross-thread
|
|
|
++// operations by using WrapCrossThreadPersistent.
|
|
|
+ class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
|
|
|
+ public FileReaderLoaderClient {
|
|
|
+ public:
|
|
|
+@@ -80,6 +86,10 @@ class ClipboardWriter : public GarbageCollected<ClipboardWriter>,
|
|
|
+ Member<SystemClipboard> system_clipboard_;
|
|
|
+ // Access to the global unsanitized system clipboard.
|
|
|
+ Member<RawSystemClipboard> raw_system_clipboard_;
|
|
|
++
|
|
|
++ // Oilpan: ClipboardWriter must remain alive until Member<T>::Clear() is
|
|
|
++ // called, to keep the FileReaderLoader alive and avoid unexpected UaPs.
|
|
|
++ SelfKeepAlive<ClipboardWriter> self_keep_alive_;
|
|
|
+ };
|
|
|
+
|
|
|
+ } // namespace blink
|