summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@qt.io>2020-08-11 13:28:29 +0200
committerMichael BrĂ¼ning <michael.bruning@qt.io>2020-08-11 15:00:03 +0000
commit30a0c954b97ae86385ff022d6c101fe900295695 (patch)
tree00cdd1e8d4710a841ded8df8808f3642be262c22
parent3cebf422618e308b48639057593ee795685e6cb7 (diff)
downloadqtwebengine-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.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h14
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 {