diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-08-11 13:28:29 +0200 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-08-11 15:00:03 +0000 |
commit | 30a0c954b97ae86385ff022d6c101fe900295695 (patch) | |
tree | 00cdd1e8d4710a841ded8df8808f3642be262c22 | |
parent | 3cebf422618e308b48639057593ee795685e6cb7 (diff) | |
download | qtwebengine-chromium-30a0c954b97ae86385ff022d6c101fe900295695.tar.gz |
[Backport] CVE-2020-6545: Use after free in audio
Manual backport of patch originally reviewed on
https://chromium-review.googlesource.com/c/chromium/src/+/2285473:
Use SupportWeakPtr in OfflineAudioDestinationHandler
OfflineAudioDestinationHandler's render thread notifies the
main thread when the rendering state changes. In this process,
the associated audio context can be deleted when a posted task
is performed sometime later in the task runner's queue.
By using WeakPtr, the task runner will not perform a scheduled task
in the queue when the target object is no longer valid.
Bug: 1095584
Test: Locally confirmed that the repro case does not crash after 30 min.
Change-Id: Ic1814b97f8d9a8d1027ef04f475112874cfa8137
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Reviewed-by: Raymond Toy <rtoy@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#786381}
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r-- | chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc | 16 | ||||
-rw-r--r-- | chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h | 14 |
2 files changed, 21 insertions, 9 deletions
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc index 71f8855b94b..36a42675f2b 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc @@ -51,17 +51,15 @@ OfflineAudioDestinationHandler::OfflineAudioDestinationHandler( frames_to_process_(frames_to_process), is_rendering_started_(false), number_of_channels_(number_of_channels), - sample_rate_(sample_rate) { + sample_rate_(sample_rate), + main_thread_task_runner_(Context()->GetExecutionContext()->GetTaskRunner( + TaskType::kInternalMedia)) { + DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); + channel_count_ = number_of_channels; SetInternalChannelCountMode(kExplicit); SetInternalChannelInterpretation(AudioBus::kSpeakers); - - if (Context()->GetExecutionContext()) { - main_thread_task_runner_ = Context()->GetExecutionContext()->GetTaskRunner( - TaskType::kMiscPlatformAPI); - DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); - } } scoped_refptr<OfflineAudioDestinationHandler> @@ -218,7 +216,7 @@ void OfflineAudioDestinationHandler::SuspendOfflineRendering() { PostCrossThreadTask( *main_thread_task_runner_, FROM_HERE, CrossThreadBindOnce(&OfflineAudioDestinationHandler::NotifySuspend, - WrapRefCounted(this), + GetWeakPtr(), Context()->CurrentSampleFrame())); } @@ -229,7 +227,7 @@ void OfflineAudioDestinationHandler::FinishOfflineRendering() { PostCrossThreadTask( *main_thread_task_runner_, FROM_HERE, CrossThreadBindOnce(&OfflineAudioDestinationHandler::NotifyComplete, - WrapRefCounted(this))); + GetWeakPtr())); } void OfflineAudioDestinationHandler::NotifySuspend(size_t frame) { diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h index e4d2d8bfcd5..07d80e4cff5 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h @@ -28,6 +28,7 @@ #include <memory> #include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" #include "third_party/blink/renderer/modules/webaudio/audio_buffer.h" #include "third_party/blink/renderer/modules/webaudio/audio_destination_node.h" #include "third_party/blink/renderer/modules/webaudio/offline_audio_context.h" @@ -124,6 +125,17 @@ class OfflineAudioDestinationHandler final : public AudioDestinationHandler { // from AudioWorkletThread will be used until the rendering is finished. void PrepareTaskRunnerForRendering(); + // For cross-thread posting, this object uses two different targets. + // 1. rendering thread -> main thread: WeakPtr + // When the main thread starts deleting this object, a task posted with + // a WeakPtr from the rendering thread will be cancelled. + // 2. main thread -> rendering thread: scoped_refptr + // |render_thread_| is owned by this object, so it is safe to target with + // WrapRefCounted() instead of GetWeakPtr(). + base::WeakPtr<OfflineAudioDestinationHandler> GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + // This AudioHandler renders into this SharedAudioBuffer. std::unique_ptr<SharedAudioBuffer> shared_render_target_; // Temporary AudioBus for each render quantum. @@ -148,6 +160,8 @@ class OfflineAudioDestinationHandler final : public AudioDestinationHandler { scoped_refptr<base::SingleThreadTaskRunner> render_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + + base::WeakPtrFactory<OfflineAudioDestinationHandler> weak_factory_{this}; }; class OfflineAudioDestinationNode final : public AudioDestinationNode { |