High chrome UAF 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Media
DescriptionUse after free in Media
ComponentMedia
Bug ClassUAF
Tracker566824998
Fix commit61ef27611dc6 (chromium/src) +50/-0
CISA KEVNot listed
Creditedweihengqiuu
Disclosed2026-10-06

Changed Functions

FunctionChangeNotes
if
third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
modified
TEST_F
third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
modified

Files Changed

  • third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
  • third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
From 61ef27611dc69f16b6fe899c8b90a80330ac88df Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Wed, 30 Sep 2026 10:29:21 -0700
Subject: [PATCH] Fix bugs in ResourceMultiBufferDataProvider::DidReceiveResponse

In ResourceMultiBufferDataProvider::DidReceiveResponse(), check a
WeakPtr across old_url_data->RedirectTo(destination_url_data).

RedirectTo() synchronously notifies MultiBufferDataSource, which can
reset reader_ and delete the active ResourceMultiBufferDataProvider when
the redirect destination already has sufficient cached data and
cancel_on_defer_ is set.

Fixed: 566824998
Change-Id: I193b4ffd5427aa0673773a5ec0747adad7fc3953
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8488169
Commit-Queue: Thomas Guilbert <tguilbert@chromium.org>
Auto-Submit: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Thomas Guilbert <tguilbert@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1708261}
---
diff --git a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
index bac246c..778dc39 100644
--- a/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
+++ b/third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.cc
@@ -382,7 +382,11 @@
     // Call callback to let upstream users know about the transfer.
     // This will merge the data from the two multibuffers and
     // cause clients to start using the new UrlData.
+    auto weak_this = weak_factory_.GetWeakPtr();
     old_url_data->RedirectTo(destination_url_data);
+    if (!weak_this) {
+      return;  // "this" may be deleted now.
+    }
   }
 
   if (do_fail) {
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
index 03aabf4..b7883a3 100644
--- a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
+++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
@@ -2242,4 +2242,50 @@
                                                   UrlData::kNormal));
 }
 
+TEST_F(MultiBufferDataSourceTest, Http_RedirectToCachedUrlWithStopPreloading) {
+  // Populate the cache for `kHttpDifferentPathUrl` with 2 blocks (64KB), which
+  // exceeds the METADATA preload_high threshold (48KB).
+  Initialize(kHttpDifferentPathUrl, true);
+  EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
+  Respond(response_generator_->Generate206(0));
+  EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize));
+  ReceiveData(kDataSize);
+  EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 2));
+  ReceiveData(kDataSize);
+  Stop();
+
+  // Initialize a new data source for `kHttpUrl` with METADATA preload and
+  // receive less than one full block (1024 bytes) so `init_cb_` stays pending
+  // while `loading_` becomes true. Calling `StopPreloading()` then sets
+  // `cancel_on_defer_` without resetting `reader_`. When the partial-data retry
+  // redirects to the already-cached `kHttpDifferentPathUrl`, `RedirectTo()`
+  // synchronously resets `reader_` and deletes
+  // `ResourceMultiBufferDataProvider` while `DidReceiveResponse` is still on
+  // the stack.
+  set_preload(MultiBufferDataSource::METADATA);
+  Initialize(kHttpUrl, false);
+  Respond(response_generator_->Generate206(0));
+  EXPECT_CALL(host_, AddBufferedByteRange(0, 1024));
+  ReceiveData(1024);
+  data_source_->StopPreloading();
+  ASSERT_TRUE(active_loader());
+
+  base::RunLoop run_loop;
+  data_provider()->DidFinishLoading();
+  data_provider()->RunOnStart(run_loop.QuitClosure());
+  run_loop.Run();
+
+  WebURL redir_url{KURL(kHttpDifferentPathUrl)};
+  WebURLResponse redirect_response{KURL(kHttpUrl)};
+  redirect_response.SetHttpStatusCode(307);
+  data_provider()->WillFollowRedirect(redir_url, redirect_response);
+
+  EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 2))
+      .Times(testing::AtLeast(1));
+  Respond(response_generator_->Generate206(0));
+
+  EXPECT_FALSE(loading());
+  Stop();
+}
+
 }  // namespace blink
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
index 03aabf4..b7883a3 100644
--- a/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
+++ b/third_party/blink/renderer/platform/media/multi_buffer_data_source_unittest.cc
@@ -2242,4 +2242,50 @@
                                                   UrlData::kNormal));
 }
 
+TEST_F(MultiBufferDataSourceTest, Http_RedirectToCachedUrlWithStopPreloading) {
+  // Populate the cache for `kHttpDifferentPathUrl` with 2 blocks (64KB), which
+  // exceeds the METADATA preload_high threshold (48KB).
+  Initialize(kHttpDifferentPathUrl, true);
+  EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
+  Respond(response_generator_->Generate206(0));
+  EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize));
+  ReceiveData(kDataSize);
+  EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 2));
+  ReceiveData(kDataSize);
+  Stop();
+
+  // Initialize a new data source for `kHttpUrl` with METADATA preload and
+  // receive less than one full block (1024 bytes) so `init_cb_` stays pending
+  // while `loading_` becomes true. Calling `StopPreloading()` then sets
+  // `cancel_on_defer_` without resetting `reader_`. When the partial-data retry
+  // redirects to the already-cached `kHttpDifferentPathUrl`, `RedirectTo()`
+  // synchronously resets `reader_` and deletes
+  // `ResourceMultiBufferDataProvider` while `DidReceiveResponse` is still on
+  // the stack.
+  set_preload(MultiBufferDataSource::METADATA);
+  Initialize(kHttpUrl, false);
+  Respond(response_generator_->Generate206(0));
+  EXPECT_CALL(host_, AddBufferedByteRange(0, 1024));
+  ReceiveData(1024);
+  data_source_->StopPreloading();
+  ASSERT_TRUE(active_loader());
+
+  base::RunLoop run_loop;
+  data_provider()->DidFinishLoading();
+  data_provider()->RunOnStart(run_loop.QuitClosure());
+  run_loop.Run();
+
+  WebURL redir_url{KURL(kHttpDifferentPathUrl)};
+  WebURLResponse redirect_response{KURL(kHttpUrl)};
+  redirect_response.SetHttpStatusCode(307);
+  data_provider()->WillFollowRedirect(redir_url, redirect_response);
+
+  EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 2))
+      .Times(testing::AtLeast(1));
+  Respond(response_generator_->Generate206(0));
+
+  EXPECT_FALSE(loading());
+  Stop();
+}
+
 }  // 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.