Chrome · Media
CVE-2026-106423
UAF in Media
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifthird_party/blink/renderer/platform/media/multi_buffer.cc |
modified |
Files Changed
third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.ccthird_party/blink/renderer/platform/media/multi_buffer.cc
Patch
From 79d7e8374c0056a4e55583ab5b836371cacfb12f Mon Sep 17 00:00:00 2001 From: Dale Curtis <[email protected]> Date: Wed, 30 Sep 2026 17:44:21 -0700 Subject: [PATCH] Fix bugs in MultiBuffer::OnDataProviderEvent when Prune empties UrlData In MultiBuffer::OnDataProviderEvent(), move Prune() after writer_index_ is updated and SuggestProviderState() is evaluated. Previously, Prune() could empty data_ and call UrlData::OnEmpty(), dropping UrlIndex's last reference to UrlData and destroying MultiBuffer before writer_index_.find(pos) was executed. Fixed: 566347711 Change-Id: I9389d473e0bc3c4523d6132ece32a74633c8cb76 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8489395 Commit-Queue: Eugene Zemtsov <[email protected]> Auto-Submit: Dale Curtis <[email protected]> Reviewed-by: Eugene Zemtsov <[email protected]> Cr-Commit-Position: refs/heads/main@{#1708523} --- diff --git a/third_party/blink/renderer/platform/media/multi_buffer.cc b/third_party/blink/renderer/platform/media/multi_buffer.cc index c5cf4b5..1846dce 100644 --- a/third_party/blink/renderer/platform/media/multi_buffer.cc +++ b/third_party/blink/renderer/platform/media/multi_buffer.cc @@ -427,7 +427,6 @@ present_.find(start_pos).interval(); NotifyAvailableRange(expanded_range, expanded_range); lru_->IncrementDataSize(blocks_added); - Prune(static_cast<size_t>(blocks_added) * kMaxFreesPerAdd + 1); } else { // Make sure to give progress reports even when there // aren't any new blocks yet. @@ -454,6 +453,13 @@ break; } } + + if (pos > start_pos) { + // Prune must run after writer_index_ is updated above, since ReleaseBlocks + // may invoke OnEmpty() and drop the UrlIndex reference to the owning + // UrlData. + Prune(static_cast<size_t>(blocks_added) * kMaxFreesPerAdd + 1); + } } void MultiBuffer::MergeFrom(MultiBuffer* other) { diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc index f27bc3a..67b08fdd 100644 --- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc +++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc @@ -490,4 +490,23 @@ StopWhenLoad(); } +TEST_F(ResourceMultiBufferDataProviderTest, + PruneEmptiesUrlDataDuringDidReceiveData) { + Initialize(kHttpUrl, 0); + url_data_->Use(); + Start(); + PartialResponse(0, 100, 1024); + + // Drop the test's reference so `url_index_` holds the sole reference to + // `UrlData`. Since there is no active `MultiBufferReader`, `GlobalLRU` max + // size is 0 and blocks are unpinned. Receiving a full block will cause + // `OnDataProviderEvent` to prune all blocks and invoke `UrlData::OnEmpty()`, + // which must not destroy `UrlData` / `MultiBuffer` while still on the stack. + ResourceMultiBufferDataProvider* loader = loader_.ExtractAsDangling(); + url_data_ = nullptr; + + std::string data_str(1, 'a'); + loader->DidReceiveData(data_str); +} + } // namespace blink
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
index f27bc3a..67b08fdd 100644
--- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
+++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider_unittest.cc
@@ -490,4 +490,23 @@
StopWhenLoad();
}
+TEST_F(ResourceMultiBufferDataProviderTest,
+ PruneEmptiesUrlDataDuringDidReceiveData) {
+ Initialize(kHttpUrl, 0);
+ url_data_->Use();
+ Start();
+ PartialResponse(0, 100, 1024);
+
+ // Drop the test's reference so `url_index_` holds the sole reference to
+ // `UrlData`. Since there is no active `MultiBufferReader`, `GlobalLRU` max
+ // size is 0 and blocks are unpinned. Receiving a full block will cause
+ // `OnDataProviderEvent` to prune all blocks and invoke `UrlData::OnEmpty()`,
+ // which must not destroy `UrlData` / `MultiBuffer` while still on the stack.
+ ResourceMultiBufferDataProvider* loader = loader_.ExtractAsDangling();
+ url_data_ = nullptr;
+
+ std::string data_str(1, 'a');
+ loader->DidReceiveData(data_str);
+}
+
} // namespace blink
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