summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Meyer <tmathmeyer@chromium.org>2022-02-23 01:34:20 +0000
committerMichael Brüning <michael.bruning@qt.io>2022-06-03 11:39:16 +0000
commitecc2bb74f1f7140fc52650042299be18e826b27b (patch)
tree1a8ba9ec0a7dcf9617a0ad1f7f979543819b66c3
parenta7a23ccc69e6756e02583e6871cc37151d89a7c2 (diff)
[Backport] CVE-2022-0796: Use after free in Media
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/3482463: Guard BatchingMediaLog::event_handlers_ with lock It seems that despite MediaLog::OnWebMediaPlayerDestroyed and MediaLog::AddLogRecord both grabbing a lock, BatchingMediaLog::AddLogRecordLocked can escape the lock handle by posting BatchingMediaLog::SendQueuedMediaEvents, causing a race. When the addition of an event is interrupted by the deletion of a player due to player culling in MediaInspectorContextImpl, a UAF can occur. R=​dalecurtis (cherry picked from commit 34526c3d0a857a22618e4d77c7f63b5ca6f8d3d2) Bug: 1295786 Change-Id: I77df94988f806e4d98924669d27860e50455299d Reviewed-by: Dale Curtis <dalecurtis@chromium.org> Commit-Queue: Ted (Chromium) Meyer <tmathmeyer@chromium.org> Cr-Original-Commit-Position: refs/heads/main@{#970815} Auto-Submit: Ted (Chromium) Meyer <tmathmeyer@chromium.org> Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Cr-Commit-Position: refs/branch-heads/4758@{#1192} Cr-Branched-From: 4a2cf4baf90326df19c3ee70ff987960d59a386e-refs/heads/main@{#950365} Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/content/renderer/media/batching_media_log.cc29
-rw-r--r--chromium/content/renderer/media/batching_media_log.h16
2 files changed, 22 insertions, 23 deletions
diff --git a/chromium/content/renderer/media/batching_media_log.cc b/chromium/content/renderer/media/batching_media_log.cc
index 76ebdf6f7a1..d345a23ccd3 100644
--- a/chromium/content/renderer/media/batching_media_log.cc
+++ b/chromium/content/renderer/media/batching_media_log.cc
@@ -56,9 +56,9 @@ BatchingMediaLog::BatchingMediaLog(
std::vector<std::unique_ptr<EventHandler>> event_handlers)
: security_origin_(security_origin),
task_runner_(std::move(task_runner)),
- event_handlers_(std::move(event_handlers)),
tick_clock_(base::DefaultTickClock::GetInstance()),
last_ipc_send_time_(tick_clock_->NowTicks()),
+ event_handlers_(std::move(event_handlers)),
ipc_send_pending_(false) {
DCHECK(RenderThread::Get())
<< "BatchingMediaLog must be constructed on the render thread";
@@ -81,6 +81,7 @@ BatchingMediaLog::~BatchingMediaLog() {
}
void BatchingMediaLog::OnWebMediaPlayerDestroyedLocked() {
+ base::AutoLock lock(lock_);
for (const auto& handler : event_handlers_)
handler->OnWebMediaPlayerDestroyed();
}
@@ -200,27 +201,25 @@ std::string BatchingMediaLog::MediaEventToMessageString(
void BatchingMediaLog::SendQueuedMediaEvents() {
DCHECK(task_runner_->BelongsToCurrentThread());
+ base::AutoLock auto_lock(lock_);
- std::vector<media::MediaLogRecord> events_to_send;
- {
- base::AutoLock auto_lock(lock_);
- DCHECK(ipc_send_pending_);
- ipc_send_pending_ = false;
-
- if (last_duration_changed_event_) {
- queued_media_events_.push_back(*last_duration_changed_event_);
- last_duration_changed_event_.reset();
- }
+ DCHECK(ipc_send_pending_);
+ ipc_send_pending_ = false;
- queued_media_events_.swap(events_to_send);
- last_ipc_send_time_ = tick_clock_->NowTicks();
+ if (last_duration_changed_event_) {
+ queued_media_events_.push_back(*last_duration_changed_event_);
+ last_duration_changed_event_.reset();
}
- if (events_to_send.empty())
+ last_ipc_send_time_ = tick_clock_->NowTicks();
+
+ if (queued_media_events_.empty())
return;
for (const auto& handler : event_handlers_)
- handler->SendQueuedMediaEvents(events_to_send);
+ handler->SendQueuedMediaEvents(queued_media_events_);
+
+ queued_media_events_.clear();
}
void BatchingMediaLog::SetTickClockForTesting(
diff --git a/chromium/content/renderer/media/batching_media_log.h b/chromium/content/renderer/media/batching_media_log.h
index 32e2bbb87ec..b68535aea42 100644
--- a/chromium/content/renderer/media/batching_media_log.h
+++ b/chromium/content/renderer/media/batching_media_log.h
@@ -65,9 +65,6 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- // impl for sending queued events.
- std::vector<std::unique_ptr<EventHandler>> event_handlers_;
-
// |lock_| protects access to all of the following member variables. It
// allows any render process thread to AddEvent(), while preserving their
// sequence for throttled send on |task_runner_| and coherent retrieval by
@@ -75,15 +72,18 @@ class CONTENT_EXPORT BatchingMediaLog : public media::MediaLog {
// guarantees provided by MediaLog, since SendQueuedMediaEvents must also
// be synchronized with respect to AddEvent.
mutable base::Lock lock_;
- const base::TickClock* tick_clock_;
- base::TimeTicks last_ipc_send_time_;
- std::vector<media::MediaLogRecord> queued_media_events_;
+ const base::TickClock* tick_clock_ GUARDED_BY(LOCK);
+ base::TimeTicks last_ipc_send_time_ GUARDED_BY(LOCK);
+ std::vector<media::MediaLogRecord> queued_media_events_ GUARDED_BY(LOCK);
+
+ // impl for sending queued events.
+ std::vector<std::unique_ptr<EventHandler>> event_handlers_ GUARDED_BY(LOCK);
// For enforcing max 1 pending send.
- bool ipc_send_pending_;
+ bool ipc_send_pending_ GUARDED_BY(LOCK);
// Limits the number of events we send over IPC to one.
- std::unique_ptr<media::MediaLogRecord> last_duration_changed_event_;
+ std::unique_ptr<media::MediaLogRecord> last_duration_changed_event_ GUARDED_BY(LOCK);
// Holds the earliest MEDIA_ERROR_LOG_ENTRY event added to this log. This is
// most likely to contain the most specific information available describing