CVE-2026-8511
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifcomponents/system_media_controls/win/system_media_controls_win.cc |
modified |
Files Changed
components/system_media_controls/win/system_media_controls_win.cc
Patch
From 411ebd37c1e01416a7db2dd2adfa5d7aad888a44 Mon Sep 17 00:00:00 2001 From: Tommy Steimel <[email protected]> Date: Tue, 24 Mar 2026 11:57:15 -0700 Subject: [PATCH] [SMTC] Use weak ptr in SystemMediaControlsWin callback We currently capture a raw `this` pointer in a SystemMediaControlsWin callback for writing image data. This could be problematic as it's possible the SystemMediaControlsWin doesn't outlive the operation. This CL updates the callback to capture and use a weak pointer instead. Bug: 495108488 Change-Id: I8698af5cf5d828ee5064793d35a6c33b6072ce53 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7694234 Commit-Queue: Tommy Steimel <[email protected]> Reviewed-by: Frank Liberato <[email protected]> Cr-Commit-Position: refs/heads/main@{#1604285} --- diff --git a/components/system_media_controls/win/system_media_controls_win.cc b/components/system_media_controls/win/system_media_controls_win.cc index 052f0397..0bbfd11a 100644 --- a/components/system_media_controls/win/system_media_controls_win.cc +++ b/components/system_media_controls/win/system_media_controls_win.cc @@ -308,10 +308,16 @@ // Make a callback that gives the icon to the SMTC once the bits make it into // |icon_stream_| + auto weak_ptr = weak_factory_.GetWeakPtr(); auto store_async_callback = Microsoft::WRL::Callback< ABI::Windows::Foundation::IAsyncOperationCompletedHandler<unsigned int>>( - [this](ABI::Windows::Foundation::IAsyncOperation<unsigned int>* async_op, - ABI::Windows::Foundation::AsyncStatus status) mutable { + [weak_ptr]( + ABI::Windows::Foundation::IAsyncOperation<unsigned int>* async_op, + ABI::Windows::Foundation::AsyncStatus status) mutable { + if (!weak_ptr) { + return S_OK; + } + // Check the async operation completed successfully. ABI::Windows::Foundation::IAsyncInfo* async_info; HRESULT hr = async_op->QueryInterface( @@ -328,15 +334,15 @@ &reference_statics); DCHECK(SUCCEEDED(result)); - result = reference_statics->CreateFromStream(icon_stream_.Get(), - &icon_stream_reference_); + result = reference_statics->CreateFromStream( + weak_ptr->icon_stream_.Get(), &weak_ptr->icon_stream_reference_); DCHECK(SUCCEEDED(result)); - result = - display_updater_->put_Thumbnail(icon_stream_reference_.Get()); + result = weak_ptr->display_updater_->put_Thumbnail( + weak_ptr->icon_stream_reference_.Get()); DCHECK(SUCCEEDED(result)); - result = display_updater_->Update(); + result = weak_ptr->display_updater_->Update(); DCHECK(SUCCEEDED(result)); } return hr;
Original Bug Report
Potential Use-After-Free in SystemMediaControlsWin::SetThumbnail via raw 'this' capture
Project Fortify, an experimental security project, has identified the following potential security issue.
Overview: A potential Use-After-Free (UAF) vulnerability exists in the browser process due to a raw this pointer capture in a WinRT asynchronous callback within SystemMediaControlsWin::SetThumbnail. If the object is destroyed while a media artwork update is pending, the callback will execute on a WinRT thread-pool thread and dereference the freed memory, potentially leading to arbitrary code execution.
Affected files:
components/system_media_controls/win/system_media_controls_win.cc
Estimated timestamp from git blame: 2021-09-08
Description
A potential Use-After-Free (UAF) vulnerability has been identified in the browser process within SystemMediaControlsWin::SetThumbnail on Windows. The issue stems from capturing a raw C++ this pointer in a Microsoft::WRL::Callback that handles the completion of an asynchronous WinRT operation.
In components/system_media_controls/win/system_media_controls_win.cc, the SetThumbnail method initiates an asynchronous write to an icon stream using icon_data_writer_->StoreAsync. A completion handler is registered via store_async_operation->put_Completed():
// components/system_media_controls/win/system_media_controls_win.cc:311
auto store_async_callback = Microsoft::WRL::Callback<
ABI::Windows::Foundation::IAsyncOperationCompletedHandler<unsigned int>>(
[this](ABI::Windows::Foundation::IAsyncOperation<unsigned int>* async_op,
ABI::Windows::Foundation::AsyncStatus status) mutable {
// ...
result = display_updater_->put_Thumbnail(icon_stream_reference_.Get());
// ...
});
The lambda captures this as a raw pointer. However, the SystemMediaControlsWin destructor does not cancel or synchronize with this pending asynchronous operation.
If the SystemMediaControlsWin object is destroyed while the write is still in flight, the WinRT runtime will eventually execute the callback, dereferencing the freed this pointer to access member variables like display_updater_ (which is a ComPtr). Because the capture is a raw pointer and no base::raw_ptr references keep the memory in MiraclePtr’s quarantine, the memory is fully freed and can be reclaimed by an attacker.
Reachability and Impact
This code path is reachable via the Media Session API. When a Progressive Web App (PWA) or an app popup window plays media, Chrome creates an instanced SystemMediaControlsWin object for that specific WebContents, managed by WebAppSystemMediaControlsManager.
If an attacker’s PWA sets media artwork (triggering SetThumbnail) and then immediately closes its own window (e.g., via window.close()), the underlying WebContents and its MediaSession are destroyed. This causes WebAppSystemMediaControlsManager to delete the SystemMediaControlsWin object while the WinRT async operation is still pending.
When the callback eventually runs, it attempts to make a virtual method call on the display_updater_ member of the freed object (display_updater_->put_Thumbnail(...)). By using standard heap spraying techniques in the browser process to control the freed memory chunk, an attacker could point display_updater_ to a forged vtable, achieving arbitrary Remote Code Execution (RCE) and a full Sandbox Escape.
Suggested Steps to Reproduce
Note: These are potential steps as we have not yet developed a working exploit.
- An attacker convinces a user to install a malicious website as a PWA, or opens an app popup window.
- The user launches the PWA, fulfilling
Browser::ShouldUseInstancedSystemMediaControls(). - The PWA’s JavaScript starts playing an audio track (e.g.,
<audio autoplay src="...">), creating aMediaSessionand requesting audio focus. - The browser creates a
WebAppSystemMediaControlsinstance, which allocates aSystemMediaControlsWinobject. - The JavaScript updates the Media Session metadata with a large artwork image to delay the WinRT processing:
navigator.mediaSession.metadata = new MediaMetadata({ artwork: [{ src: "large.png" }] }); SystemMediaControlsWin::SetThumbnailis called, initiating the asynchronousStoreAsyncoperation and registering the vulnerable callback.- Immediately after setting the metadata (allowing ~10-20ms for debounce timers to fire), the JavaScript executes
window.close(). - The window closes, destroying the
WebContentsand causing theSystemMediaControlsWinobject to be freed. - The attacker performs a heap spray in the browser process to reclaim the freed memory with a controlled payload.
- The WinRT async operation completes, the callback executes, and the dangling
thispointer is dereferenced, leading to a virtual call on the attacker’s sprayed data.
Suggested Fix
To prevent this Use-After-Free, the callback should use a base::WeakPtr instead of a raw this pointer, similar to how the ButtonPressed handler is implemented in SystemMediaControlsWin::Initialize (lines 113-125).
auto weak_ptr = weak_factory_.GetWeakPtr();
auto store_async_callback = Microsoft::WRL::Callback<
ABI::Windows::Foundation::IAsyncOperationCompletedHandler<unsigned int>>(
[weak_ptr](ABI::Windows::Foundation::IAsyncOperation<unsigned int>* async_op,
ABI::Windows::Foundation::AsyncStatus status) mutable {
if (!weak_ptr) return S_OK;
// ... safe to access weak_ptr->display_updater_ ...
});
Evaluated with Chrome root at commit: 9760e6c70cd33a320713361f17c6dcca85648c0f
Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. Please feel free to reach out to me if you have concerns or feedback.