Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Site Isolation
DescriptionUse after free in Site Isolation
ComponentSite Isolation
Bug ClassUAF
Tracker405140652
Fix commit94ec04ec6bd8 (chromium/src) +6/-3
CISA KEVNot listed
CreditedSven Dysthe (@svn-dys)
Disclosed2025-04-08

Changed Functions

FunctionChangeNotes
if
content/browser/renderer_host/subframe_history_navigation_throttle.cc
modified

Files Changed

  • content/browser/renderer_host/subframe_history_navigation_throttle.cc
From 94ec04ec6bd89868fe9508a76d058243db8f0623 Mon Sep 17 00:00:00 2001
From: Takashi Toyoshima <[email protected]>
Date: Mon, 24 Mar 2025 23:28:14 -0700
Subject: [PATCH] SubframeHistoryNavigationThrottle: Update the state_ first

It's nice to update the `state_` before calling Resume()
to avoid an ordering issue.

Bug: 405140652
Change-Id: Ife607f8121eadcf30f86c5478a688bd7e61bccb1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6387055
Commit-Queue: Takashi Toyoshima <[email protected]>
Reviewed-by: Alex Moshchuk <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1437323}
---

diff --git a/content/browser/renderer_host/subframe_history_navigation_throttle.cc b/content/browser/renderer_host/subframe_history_navigation_throttle.cc
index 85377dac..2153c983 100644
--- a/content/browser/renderer_host/subframe_history_navigation_throttle.cc
+++ b/content/browser/renderer_host/subframe_history_navigation_throttle.cc
@@ -44,10 +44,13 @@
 }
 
 void SubframeHistoryNavigationThrottle::Resume() {
-  if (state_ == State::kDeferred) {
-    NavigationThrottle::Resume();
-  }
+  const bool should_resume = state_ == State::kDeferred;
   state_ = State::kRunningAfterResumeSignal;
+  if (should_resume) {
+    NavigationThrottle::Resume();
+    // `Resume()` can synchronously delete this navigation throttle, so no code
+    // after this call should reference the throttle instance.
+  }
 }
 
 void SubframeHistoryNavigationThrottle::Cancel() {
Loading diff…

Original Bug Report

reported by [email protected]

UAF when accessing member variable after destruction of throttle (SubframeHistoryNavigationThrottle)

Steps to reproduce the problem

I will provide a reproduction of the UAF soon. Bear with me, please. Though I think the UAF is trivial.

Problem Description

A SubframeHistoryNavigationThrottle is intended to defer subframe history navigations while the main frame commits main-frame same-document history navigations. When the Resume() method is called, it triggers a call to resume the current throttle 0. However, the call to NavigationThrottle::Resume() can synchronously delete this. This leads to a use-after-free when subsequently accessing the member variable state_ 1.

void SubframeHistoryNavigationThrottle::Resume() {
  if (state_ == State::kDeferred) {
    NavigationThrottle::Resume(); [0]
  }
  state_ = State::kRunningAfterResumeSignal; [1]
}

This issue resembles crbug.com/40063127.

Suggested Fix: Move the member variable assignment (state_ = State::kRunningAfterResumeSignal;) to before calling Resume():

void SubframeHistoryNavigationThrottle::Resume() {
  state_ = State::kRunningAfterResumeSignal;
  
  if (state_ == State::kDeferred) {
    NavigationThrottle::Resume();
    // `Resume()` can synchronously delete this navigation throttle, so no code
    // after this call should reference the throttle instance.
  }
}

Additional Comments

PoC soon.

Summary

UAF when accessing member variable after destruction of throttle (SubframeHistoryNavigationThrottle)

Custom Questions

Type of crash:

browser

Reporter credit:

Sven Dysthe @svn_dy

Additional Data

Category: Security
Chrome Channel: Canary
Regression: N/A

View on issue tracker