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 <[email protected]> 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 <[email protected]> Commit-Queue: Henrik Andreasson <[email protected]> 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