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 <dalecurtis@chromium.org>
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 <eugene@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Eugene Zemtsov <eugene@chromium.org>
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