Chrome · MediaCapture
CVE-2026-84348
Logic Error in MediaCapture
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
MediaStreamPowerLoggercontent/browser/renderer_host/media/media_stream_power_logger.cc |
modified | |
MediaStreamPowerLoggercontent/browser/renderer_host/media/media_stream_power_logger.h |
modified | |
CONTENT_EXPORTcontent/browser/renderer_host/media/media_stream_power_logger.h |
modified | |
MediaStreamPowerLoggerTestcontent/browser/renderer_host/media/media_stream_power_logger_unittest.cc |
modified | |
TEST_Fcontent/browser/renderer_host/media/media_stream_power_logger_unittest.cc |
modified | |
ASSERT_TRUEcontent/browser/renderer_host/media/media_stream_power_logger_unittest.cc |
modified |
Files Changed
content/browser/renderer_host/media/media_stream_power_logger.cccontent/browser/renderer_host/media/media_stream_power_logger.hcontent/browser/renderer_host/media/media_stream_power_logger_unittest.cccontent/test/BUILD.gn
Patch
From caf99694b721dc79d25341d6d3b975e4ef32966c Mon Sep 17 00:00:00 2001
From: henrika <henrika@google.com>
Date: Tue, 21 Jul 2026 00:38:45 -0700
Subject: [PATCH] webrtc: Replace raw pointer logging with tokens in MediaStreamPowerLogger
Bug: 518100026
Change-Id: I8b442d5648f2cab333a07a60093defd15c11975f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8124755
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
Commit-Queue: Henrik Andreasson <henrika@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1665243}
---
diff --git a/content/browser/renderer_host/media/media_stream_power_logger.cc b/content/browser/renderer_host/media/media_stream_power_logger.cc
index 6e92929..30f3f632 100644
--- a/content/browser/renderer_host/media/media_stream_power_logger.cc
+++ b/content/browser/renderer_host/media/media_stream_power_logger.cc
@@ -17,7 +17,8 @@
}
} // namespace
-MediaStreamPowerLogger::MediaStreamPowerLogger() {
+MediaStreamPowerLogger::MediaStreamPowerLogger()
+ : id_(base::UnguessableToken::Create()) {
auto* power_monitor = base::PowerMonitor::GetInstance();
power_monitor->AddPowerSuspendObserver(this);
power_monitor->AddPowerThermalObserver(this);
@@ -30,24 +31,28 @@
}
void MediaStreamPowerLogger::OnSuspend() {
- SendLogMessage(base::StringPrintf("OnSuspend([this=%p])", this));
+ SendLogMessage(
+ base::StringPrintf("OnSuspend([id=%s])", id_.ToString().c_str()));
}
void MediaStreamPowerLogger::OnResume() {
- SendLogMessage(base::StringPrintf("OnResume([this=%p])", this));
+ SendLogMessage(
+ base::StringPrintf("OnResume([id=%s])", id_.ToString().c_str()));
}
void MediaStreamPowerLogger::OnThermalStateChange(
base::PowerThermalObserver::DeviceThermalState new_state) {
const char* state_name =
base::PowerMonitorSource::DeviceThermalStateToString(new_state);
- SendLogMessage(base::StringPrintf(
- "OnThermalStateChange({this=%p}, {new_state=%s})", this, state_name));
+ SendLogMessage(
+ base::StringPrintf("OnThermalStateChange({id=%s}, {new_state=%s})",
+ id_.ToString().c_str(), state_name));
}
void MediaStreamPowerLogger::OnSpeedLimitChange(int new_limit) {
- SendLogMessage(base::StringPrintf(
- "OnSpeedLimitChange({this=%p}, {new_limit=%d})", this, new_limit));
+ SendLogMessage(
+ base::StringPrintf("OnSpeedLimitChange({id=%s}, {new_limit=%d})",
+ id_.ToString().c_str(), new_limit));
}
} // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_power_logger.h b/content/browser/renderer_host/media/media_stream_power_logger.h
index e268a57..d990629 100644
--- a/content/browser/renderer_host/media/media_stream_power_logger.h
+++ b/content/browser/renderer_host/media/media_stream_power_logger.h
@@ -6,14 +6,17 @@
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_POWER_LOGGER_H_
#include "base/power_monitor/power_observer.h"
+#include "base/unguessable_token.h"
+#include "content/common/content_export.h"
namespace content {
// Injects system power event log entries into the WebRTC text logs, for
// debugging of unexpected call ending and performance changes eg when calls end
// due to a laptop's lid being closed.
-class MediaStreamPowerLogger : public base::PowerSuspendObserver,
- public base::PowerThermalObserver {
+class CONTENT_EXPORT MediaStreamPowerLogger
+ : public base::PowerSuspendObserver,
+ public base::PowerThermalObserver {
public:
MediaStreamPowerLogger();
~MediaStreamPowerLogger() override;
@@ -26,6 +29,9 @@
void OnThermalStateChange(
base::PowerThermalObserver::DeviceThermalState new_state) override;
void OnSpeedLimitChange(int new_limit) override;
+
+ private:
+ const base::UnguessableToken id_;
};
} // namespace content
diff --git a/content/browser/renderer_host/media/media_stream_power_logger_unittest.cc b/content/browser/renderer_host/media/media_stream_power_logger_unittest.cc
new file mode 100644
index 0000000..648ad08
--- /dev/null
+++ b/content/browser/renderer_host/media/media_stream_power_logger_unittest.cc
@@ -0,0 +1,86 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/media_stream_power_logger.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/functional/bind.h"
+#include "base/test/run_until.h"
+#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/browser/renderer_host/media/mock_video_capture_provider.h"
+#include "content/public/test/browser_task_environment.h"
+#include "media/audio/audio_system_impl.h"
+#include "media/audio/mock_audio_manager.h"
+#include "media/audio/test_audio_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+using ::testing::Contains;
+using ::testing::Each;
+using ::testing::HasSubstr;
+using ::testing::Not;
+
+constexpr int kRenderProcessId = 1;
+
+class MediaStreamPowerLoggerTest : public ::testing::Test {
+ public:
+ MediaStreamPowerLoggerTest()
+ : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {
+ audio_manager_ = std::make_unique<media::MockAudioManager>(
+ std::make_unique<media::TestAudioThread>());
+ audio_system_ =
+ std::make_unique<media::AudioSystemImpl>(audio_manager_.get());
+ media_stream_manager_ = std::make_unique<MediaStreamManager>(
+ audio_system_.get(), std::make_unique<MockVideoCaptureProvider>());
+
+ MediaStreamManager::RegisterNativeLogCallback(
+ kRenderProcessId,
+ base::BindRepeating(&MediaStreamPowerLoggerTest::OnLogMessage,
+ base::Unretained(this)));
+ }
+
+ ~MediaStreamPowerLoggerTest() override {
+ MediaStreamManager::UnregisterNativeLogCallback(kRenderProcessId);
+ audio_manager_->Shutdown();
+ }
+
+ protected:
+ void OnLogMessage(const std::string& message) {
+ messages_.push_back(message);
+ }
+
+ std::vector<std::string> messages_;
+ std::unique_ptr<media::MockAudioManager> audio_manager_;
+ std::unique_ptr<media::AudioSystem> audio_system_;
+ // `media_stream_manager_` must outlive `task_environment_` because it is a
+ // CurrentThread::DestructionObserver.
+ std::unique_ptr<MediaStreamManager> media_stream_manager_;
+ BrowserTaskEnvironment task_environment_;
+};
+
+TEST_F(MediaStreamPowerLoggerTest, LogMessagesDoNotContainPointers) {
+ MediaStreamPowerLogger logger;
+ logger.OnSuspend();
+ logger.OnResume();
+ logger.OnThermalStateChange(
+ base::PowerThermalObserver::DeviceThermalState::kNominal);
+ logger.OnSpeedLimitChange(50);
+ ASSERT_TRUE(base::test::RunUntil([&]() { return messages_.size() == 4; }));
+
+ EXPECT_THAT(messages_, Contains(HasSubstr("MSPL::OnSuspend([id=")));
+ EXPECT_THAT(messages_, Contains(HasSubstr("MSPL::OnResume([id=")));
+ EXPECT_THAT(messages_,
+ Contains(HasSubstr("MSPL::OnThermalStateChange({id=")));
+ EXPECT_THAT(messages_, Contains(HasSubstr("MSPL::OnSpeedLimitChange({id=")));
+ EXPECT_THAT(messages_, Each(Not(HasSubstr("0x"))));
+}
+
+} // namespace
+} // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 3c13273..c5596ac 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -2868,6 +2868,7 @@
"../browser/renderer_host/media/media_devices_manager_unittest.cc",
"../browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc",
"../browser/renderer_host/media/media_stream_manager_unittest.cc",
+ "../browser/renderer_host/media/media_stream_power_logger_unittest.cc",
"../browser/renderer_host/media/media_stream_ui_proxy_unittest.cc",
"../browser/renderer_host/media/mock_preferred_audio_output_device_manager.cc",
"../browser/renderer_host/media/mock_preferred_audio_output_device_manager.h",
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/content/browser/renderer_host/media/media_stream_power_logger_unittest.cc b/content/browser/renderer_host/media/media_stream_power_logger_unittest.cc
new file mode 100644
index 0000000..648ad08
--- /dev/null
+++ b/content/browser/renderer_host/media/media_stream_power_logger_unittest.cc
@@ -0,0 +1,86 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/media_stream_power_logger.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/functional/bind.h"
+#include "base/test/run_until.h"
+#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/browser/renderer_host/media/mock_video_capture_provider.h"
+#include "content/public/test/browser_task_environment.h"
+#include "media/audio/audio_system_impl.h"
+#include "media/audio/mock_audio_manager.h"
+#include "media/audio/test_audio_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+using ::testing::Contains;
+using ::testing::Each;
+using ::testing::HasSubstr;
+using ::testing::Not;
+
+constexpr int kRenderProcessId = 1;
+
+class MediaStreamPowerLoggerTest : public ::testing::Test {
+ public:
+ MediaStreamPowerLoggerTest()
+ : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {
+ audio_manager_ = std::make_unique<media::MockAudioManager>(
+ std::make_unique<media::TestAudioThread>());
+ audio_system_ =
+ std::make_unique<media::AudioSystemImpl>(audio_manager_.get());
+ media_stream_manager_ = std::make_unique<MediaStreamManager>(
+ audio_system_.get(), std::make_unique<MockVideoCaptureProvider>());
+
+ MediaStreamManager::RegisterNativeLogCallback(
+ kRenderProcessId,
+ base::BindRepeating(&MediaStreamPowerLoggerTest::OnLogMessage,
+ base::Unretained(this)));
+ }
+
+ ~MediaStreamPowerLoggerTest() override {
+ MediaStreamManager::UnregisterNativeLogCallback(kRenderProcessId);
+ audio_manager_->Shutdown();
+ }
+
+ protected:
+ void OnLogMessage(const std::string& message) {
+ messages_.push_back(message);
+ }
+
+ std::vector<std::string> messages_;
+ std::unique_ptr<media::MockAudioManager> audio_manager_;
+ std::unique_ptr<media::AudioSystem> audio_system_;
+ // `media_stream_manager_` must outlive `task_environment_` because it is a
+ // CurrentThread::DestructionObserver.
+ std::unique_ptr<MediaStreamManager> media_stream_manager_;
+ BrowserTaskEnvironment task_environment_;
+};
+
+TEST_F(MediaStreamPowerLoggerTest, LogMessagesDoNotContainPointers) {
+ MediaStreamPowerLogger logger;
+ logger.OnSuspend();
+ logger.OnResume();
+ logger.OnThermalStateChange(
+ base::PowerThermalObserver::DeviceThermalState::kNominal);
+ logger.OnSpeedLimitChange(50);
+ ASSERT_TRUE(base::test::RunUntil([&]() { return messages_.size() == 4; }));
+
+ EXPECT_THAT(messages_, Contains(HasSubstr("MSPL::OnSuspend([id=")));
+ EXPECT_THAT(messages_, Contains(HasSubstr("MSPL::OnResume([id=")));
+ EXPECT_THAT(messages_,
+ Contains(HasSubstr("MSPL::OnThermalStateChange({id=")));
+ EXPECT_THAT(messages_, Contains(HasSubstr("MSPL::OnSpeedLimitChange({id=")));
+ EXPECT_THAT(messages_, Each(Not(HasSubstr("0x"))));
+}
+
+} // namespace
+} // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 3c13273..c5596ac 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -2868,6 +2868,7 @@
"../browser/renderer_host/media/media_devices_manager_unittest.cc",
"../browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc",
"../browser/renderer_host/media/media_stream_manager_unittest.cc",
+ "../browser/renderer_host/media/media_stream_power_logger_unittest.cc",
"../browser/renderer_host/media/media_stream_ui_proxy_unittest.cc",
"../browser/renderer_host/media/mock_preferred_audio_output_device_manager.cc",
"../browser/renderer_host/media/mock_preferred_audio_output_device_manager.h",
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page