summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer
diff options
context:
space:
mode:
authorCorentin Pescheloche <cpescheloche@fb.com>2022-05-10 14:05:53 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2022-05-20 15:37:06 +0000
commitb45abe6aea361b9041969b0479bbbef294a08ec4 (patch)
tree27bf14101104405aa040402ee174aa5607e586e3 /chromium/third_party/blink/renderer
parent7f926451f3c633f416b6054a2bb378443ef96f7a (diff)
downloadqtwebengine-chromium-b45abe6aea361b9041969b0479bbbef294a08ec4.tar.gz
[Backport] CVE-2022-1636: Use after free in Performance APIs
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/3620956: Cleanup profiler group detached profilers ProfilerGroup keeps track of detached profilers to be able to gracefully stop leaked profilers when the corresponding ExecutionContext is destroyed. (cherry picked from commit 9f9d5fd2f3085414fc8776bf556fb5c4fa2dac2c) Change-Id: I4fdbbc3a5208819397d742c9ecbff117f839691c Bug: chromium:1297283 Commit-Queue: Corentin Pescheloche <cpescheloche@fb.com> Cr-Original-Commit-Position: refs/heads/main@{#994316} Reviewed-by: Oleh Lamzin <lamzin@google.com> Owners-Override: Oleh Lamzin <lamzin@google.com> Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com> Auto-Submit: Roger Felipe Zanoni da Silva <rzanoni@google.com> Cr-Commit-Position: refs/branch-heads/4664@{#1629} Cr-Branched-From: 24dc4ee75e01a29d390d43c9c264372a169273a7-refs/heads/main@{#929512} Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer')
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group.cc38
-rw-r--r--chromium/third_party/blink/renderer/core/timing/profiler_group.h8
2 files changed, 42 insertions, 4 deletions
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group.cc b/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
index 090068ee1dc..466e4f76fce 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group.cc
@@ -110,8 +110,7 @@ ProfilerGroup::ProfilerGroup(v8::Isolate* isolate)
: isolate_(isolate),
cpu_profiler_(nullptr),
next_profiler_id_(0),
- num_active_profilers_(0) {
-}
+ num_active_profilers_(0) {}
void DiscardedSamplesDelegate::Notify() {
if (profiler_group_) {
@@ -234,6 +233,8 @@ void ProfilerGroup::WillBeDestroyed() {
DCHECK(!profilers_.Contains(profiler));
}
+ StopDetachedProfilers();
+
if (cpu_profiler_)
TeardownV8Profiler();
}
@@ -304,18 +305,49 @@ void ProfilerGroup::CancelProfiler(Profiler* profiler) {
void ProfilerGroup::CancelProfilerAsync(ScriptState* script_state,
Profiler* profiler) {
+ DCHECK(IsMainThread());
DCHECK(cpu_profiler_);
DCHECK(!profiler->stopped());
profilers_.erase(profiler);
+ // register the profiler to be cleaned up in case its associated context
+ // gets destroyed before the cleanup task is executed.
+ detached_profiler_ids_.push_back(profiler->ProfilerId());
+
// Since it's possible for the profiler to get destructed along with its
// associated context, dispatch a task to cleanup context-independent isolate
// resources (rather than use the context's task runner).
ThreadScheduler::Current()->V8TaskRunner()->PostTask(
- FROM_HERE, WTF::Bind(&ProfilerGroup::CancelProfilerImpl,
+ FROM_HERE, WTF::Bind(&ProfilerGroup::StopDetachedProfiler,
WrapPersistent(this), profiler->ProfilerId()));
}
+void ProfilerGroup::StopDetachedProfiler(String profiler_id) {
+ DCHECK(IsMainThread());
+
+ // we use a vector instead of a map because the expected number of profiler
+ // is expected to be very small
+ auto* it = std::find(detached_profiler_ids_.begin(),
+ detached_profiler_ids_.end(), profiler_id);
+
+ if (it == detached_profiler_ids_.end()) {
+ // Profiler already stopped
+ return;
+ }
+
+ CancelProfilerImpl(profiler_id);
+ detached_profiler_ids_.erase(it);
+}
+
+void ProfilerGroup::StopDetachedProfilers() {
+ DCHECK(IsMainThread());
+
+ for (auto& detached_profiler_id : detached_profiler_ids_) {
+ CancelProfilerImpl(detached_profiler_id);
+ }
+ detached_profiler_ids_.clear();
+}
+
void ProfilerGroup::CancelProfilerImpl(String profiler_id) {
if (!cpu_profiler_)
return;
diff --git a/chromium/third_party/blink/renderer/core/timing/profiler_group.h b/chromium/third_party/blink/renderer/core/timing/profiler_group.h
index d673d0d6ec6..8c27d41b160 100644
--- a/chromium/third_party/blink/renderer/core/timing/profiler_group.h
+++ b/chromium/third_party/blink/renderer/core/timing/profiler_group.h
@@ -81,6 +81,10 @@ class CORE_EXPORT ProfilerGroup
// Internal implementation of cancel.
void CancelProfilerImpl(String profiler_id);
+ // Clean context independent resources for leaked profilers
+ void StopDetachedProfiler(String profiler_id);
+ void StopDetachedProfilers();
+
// Generates an unused string identifier to use for a new profiling session.
String NextProfilerId();
@@ -88,9 +92,11 @@ class CORE_EXPORT ProfilerGroup
v8::CpuProfiler* cpu_profiler_;
int next_profiler_id_;
int num_active_profilers_;
-
HeapHashSet<WeakMember<Profiler>> profilers_;
+ // Store the ids of leaked collected profilers that needs to be stopped
+ Vector<String> detached_profiler_ids_;
+
// A set of observers, one for each ExecutionContext that has profiling
// enabled.
HeapHashSet<Member<ProfilingContextObserver>> context_observers_;