summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-04-17 15:07:31 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-04-20 11:07:01 +0000
commit580c53c725c07e0e49b66812d3c0e9edca976ae6 (patch)
tree1395192c920c48caa3be3177db1c91bb3691aa77
parent55a8f34b5deaf20f6f81913a3beead8be1677690 (diff)
downloadqtwebengine-chromium-580c53c725c07e0e49b66812d3c0e9edca976ae6.tar.gz
[Backport] Fix for CVE-2020-6423
Use KeepSelfAlive on AudioContext to keep it alive until rendering stops When an ExecutionContext is abruptly/unexpectedly destroyed (e.g. shutting down of document or iframe), an AudioContext can also go away. This type of shutdown can be problematic because the render thread still might be touching resources in the AudioContext allocated by the main thread. This CL introduces a self-referencing pointer to the AudioContext, and it is cleared after the underlying render thread is stopped. In that way, the destruction of AudioContext can be done safely. (cherry picked from commit 85f708fa7ab898c7ae678c0b8a270105be6bbb4e) Test: Locally confirmed the repro case doesn't crash (UAP) after 1hr. Bug: 1043446 Change-Id: I2e40b7d58ca9d647eed8a5971fc69dc87ee3d1fe Reviewed-by: Raymond Toy <rtoy@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Hongchan Choi <hongchan@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#742338} Reviewed-by: Hongchan Choi <hongchan@chromium.org> Cr-Commit-Position: refs/branch-heads/4044@{#498} Cr-Branched-From: a6d9daf149a473ceea37f629c41d4527bf2055bd-refs/heads/master@{#737173} Reviewed-by: Kirill Burtsev <kirill.burtsev@qt.io>
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc20
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/audio_context.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h2
3 files changed, 27 insertions, 5 deletions
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
index f544a4658f3..6618c8d74bd 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc
@@ -132,7 +132,8 @@ AudioContext::AudioContext(Document& document,
const WebAudioLatencyHint& latency_hint,
base::Optional<float> sample_rate)
: BaseAudioContext(&document, kRealtimeContext),
- context_id_(g_context_id++) {
+ context_id_(g_context_id++),
+ keep_alive_(PERSISTENT_FROM_HERE, this) {
destination_node_ =
RealtimeAudioDestinationNode::Create(this, latency_hint, sample_rate);
@@ -169,13 +170,14 @@ AudioContext::AudioContext(Document& document,
destination()->GetAudioDestinationHandler());
base_latency_ = destination_handler.GetFramesPerBuffer() /
static_cast<double>(sampleRate());
+
}
void AudioContext::Uninitialize() {
DCHECK(IsMainThread());
DCHECK_NE(g_hardware_context_count, 0u);
--g_hardware_context_count;
-
+ StopRendering();
DidClose();
RecordAutoplayMetrics();
BaseAudioContext::Uninitialize();
@@ -358,14 +360,26 @@ bool AudioContext::IsContextClosed() const {
return close_resolver_ || BaseAudioContext::IsContextClosed();
}
+void AudioContext::StartRendering() {
+ DCHECK(IsMainThread());
+
+ if (!keep_alive_)
+ keep_alive_ = this;
+ BaseAudioContext::StartRendering();
+}
+
void AudioContext::StopRendering() {
DCHECK(IsMainThread());
DCHECK(destination());
- if (ContextState() == kRunning) {
+ // It is okay to perform the following on a suspended AudioContext because
+ // this method gets called from ExecutionContext::ContextDestroyed() meaning
+ // the AudioContext is already unreachable from the user code.
+ if (ContextState() != kClosed) {
destination()->GetAudioDestinationHandler().StopRendering();
SetContextState(kClosed);
GetDeferredTaskHandler().ClearHandlersToBeDeleted();
+ keep_alive_.Clear();
}
}
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
index 6e3455921f5..d3e521f1291 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/modules/webaudio/audio_context_options.h"
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
namespace blink {
@@ -133,8 +134,13 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
// Record the current autoplay metrics.
void RecordAutoplayMetrics();
+ // Starts rendering via AudioDestinationNode. This sets the self-referencing
+ // pointer to this object.
+ void StartRendering() override;
+
// Called when the context is being closed to stop rendering audio and clean
- // up handlers.
+ // up handlers. This clears the self-referencing pointer, making this object
+ // available for the potential GC.
void StopRendering();
// Called when suspending the context to stop reundering audio, but don't
@@ -196,6 +202,8 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext {
// determine audibility on render quantum boundaries, so counting quanta is
// all that's needed.
size_t total_audible_renders_ = 0;
+
+ SelfKeepAlive<AudioContext> keep_alive_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
index a99b2dddad4..051890e2742 100644
--- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
+++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h
@@ -285,7 +285,7 @@ class MODULES_EXPORT BaseAudioContext
DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange)
- void StartRendering();
+ virtual void StartRendering();
void NotifyStateChange();