Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in Frame
DescriptionInappropriate implementation in Frame
ComponentFrame
Bug ClassLogic Error
Tracker518815075
Fix commitb93fe74ce139 (chromium/src) +73/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-07-29

Changed Functions

FunctionChangeNotes
if
third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html
modified

Files Changed

  • third_party/blink/renderer/core/frame/local_frame.cc
  • third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html
  • third_party/blink/web_tests/printing/resources/remove-iframe-beforeprint-crash-child.html
From b93fe74ce13916f57acd73148d2ec8e5aa7b7ed0 Mon Sep 17 00:00:00 2001
From: Mason Freed <[email protected]>
Date: Tue, 09 Jun 2026 09:37:38 -0700
Subject: [PATCH] Null-check GetFrameScheduler() in LocalFrame::SetHadUserInteraction()

Calling SetHadUserInteraction() on a frame that gets detached during
unwinding or inside synchronous print events can encounter a null
FrameScheduler. This adds a check for GetFrameScheduler() before
calling SetHadUserActivation().

Fixed: 518815075
Change-Id: I783b20ebcb682c648fd907d170895b787dbe40d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7905327
Reviewed-by: Joey Arhar <[email protected]>
Commit-Queue: Mason Freed <[email protected]>
Auto-Submit: Mason Freed <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1644040}
---

diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 20ff202..7b016194 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2927,7 +2927,9 @@
   DomWindow()->closewatcher_stack()->SetHadUserInteraction(
       had_user_interaction);
 
-  GetFrameScheduler()->SetHadUserActivation(had_user_interaction);
+  if (auto* scheduler = GetFrameScheduler()) {
+    scheduler->SetHadUserActivation(had_user_interaction);
+  }
 }
 
 namespace {
diff --git a/third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html b/third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html
new file mode 100644
index 0000000..3a612ae
--- /dev/null
+++ b/third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:[email protected]">
+<link rel="help" href="https://crbug.com/518815075">
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/testdriver.js"></script>
+<script src="../resources/testdriver-actions.js"></script>
+<script src="../resources/testdriver-vendor.js"></script>
+
+<!-- This test passes if it doesn't crash. -->
+
+<iframe src="resources/remove-iframe-beforeprint-crash-child.html"></iframe>
+
+<script>
+async_test(t => {
+  window.finishTest = t.step_func_done(() => {});
+
+  window.addEventListener('beforeprint', t.step_func(() => {
+    let f = document.querySelector('iframe');
+    if (f) {
+      f.remove();
+    }
+  }), { once: true });
+}, "This is a crash test and it passes if it doesn't crash.");
+</script>
+
diff --git a/third_party/blink/web_tests/printing/resources/remove-iframe-beforeprint-crash-child.html b/third_party/blink/web_tests/printing/resources/remove-iframe-beforeprint-crash-child.html
new file mode 100644
index 0000000..f682ec1
--- /dev/null
+++ b/third_party/blink/web_tests/printing/resources/remove-iframe-beforeprint-crash-child.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:[email protected]">
+<link rel="help" href="https://crbug.com/518815075">
+
+<body style="margin:0">
+
+<div id="clicktarget">CLICK HERE</div>
+
+<form id="login" action="/login" method="post"
+      style="position:absolute;left:0;top:0;opacity:0.01;pointer-events:none">
+  <input type="text" id="username" name="username" autocomplete="username">
+  <input type="password" id="password" name="password" autocomplete="current-password">
+  <input type="submit" value="go">
+</form>
+
+<script>
+let armed = false;
+
+function trigger() {
+  if (!armed) return;
+  armed = false;
+  top.print();
+  top.finishTest();
+}
+
+username.addEventListener('input', trigger);
+username.addEventListener('change', trigger);
+password.addEventListener('input', trigger);
+clicktarget.addEventListener('mousedown', trigger);
+
+window.addEventListener('load', () => {
+  setTimeout(() => {
+    armed = true;
+    new top.test_driver.Actions()
+        .pointerMove(0, 0, {origin: clicktarget})
+        .pointerDown()
+        .pointerUp()
+        .send();
+  }, 0);
+});
+</script>
+</body>
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html b/third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html
new file mode 100644
index 0000000..3a612ae
--- /dev/null
+++ b/third_party/blink/web_tests/printing/remove-iframe-beforeprint-crash.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:[email protected]">
+<link rel="help" href="https://crbug.com/518815075">
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/testdriver.js"></script>
+<script src="../resources/testdriver-actions.js"></script>
+<script src="../resources/testdriver-vendor.js"></script>
+
+<!-- This test passes if it doesn't crash. -->
+
+<iframe src="resources/remove-iframe-beforeprint-crash-child.html"></iframe>
+
+<script>
+async_test(t => {
+  window.finishTest = t.step_func_done(() => {});
+
+  window.addEventListener('beforeprint', t.step_func(() => {
+    let f = document.querySelector('iframe');
+    if (f) {
+      f.remove();
+    }
+  }), { once: true });
+}, "This is a crash test and it passes if it doesn't crash.");
+</script>
+
diff --git a/third_party/blink/web_tests/printing/resources/remove-iframe-beforeprint-crash-child.html b/third_party/blink/web_tests/printing/resources/remove-iframe-beforeprint-crash-child.html
new file mode 100644
index 0000000..f682ec1
--- /dev/null
+++ b/third_party/blink/web_tests/printing/resources/remove-iframe-beforeprint-crash-child.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:[email protected]">
+<link rel="help" href="https://crbug.com/518815075">
+
+<body style="margin:0">
+
+<div id="clicktarget">CLICK HERE</div>
+
+<form id="login" action="/login" method="post"
+      style="position:absolute;left:0;top:0;opacity:0.01;pointer-events:none">
+  <input type="text" id="username" name="username" autocomplete="username">
+  <input type="password" id="password" name="password" autocomplete="current-password">
+  <input type="submit" value="go">
+</form>
+
+<script>
+let armed = false;
+
+function trigger() {
+  if (!armed) return;
+  armed = false;
+  top.print();
+  top.finishTest();
+}
+
+username.addEventListener('input', trigger);
+username.addEventListener('change', trigger);
+password.addEventListener('input', trigger);
+clicktarget.addEventListener('mousedown', trigger);
+
+window.addEventListener('load', () => {
+  setTimeout(() => {
+    armed = true;
+    new top.test_driver.Actions()
+        .pointerMove(0, 0, {origin: clicktarget})
+        .pointerDown()
+        .pointerUp()
+        .send();
+  }, 0);
+});
+</script>
+</body>
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.