CVE-2026-14148
Overview
Files Changed
third_party/blink/renderer/core/css/resolver/style_resolver.ccthird_party/blink/web_tests/external/wpt/css/css-cascade/inline-style-revert-layer-crash.html
Patch
From ab8797fc9f3b99c90ef35837bb2ee5daa1230797 Mon Sep 17 00:00:00 2001
From: Steinar H. Gunderson <sesse@chromium.org>
Date: Fri, 22 May 2026 01:48:35 -0700
Subject: [PATCH] Fix a CHECK when using revert-layer together with MISU.
Fixed: 515426873
Change-Id: Ic71a72fa6a8e32f615b754f1ea2cdc988c8c8190
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7870930
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Steinar H Gunderson <sesse@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1634799}
---
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 4559080..b86d42a 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -1655,8 +1655,7 @@
// in this path; thus, we cannot support them.
if (property.Value().IsUnparsedDeclaration() ||
property.Value().IsPendingSubstitutionValue() ||
- property.Value().IsRevertValue() ||
- property.Value().IsRevertLayerValue()) {
+ property.Value().IsCascadeDependentKeyword()) {
return false;
}
// Even though they are not substitution functions (and therefore not
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/inline-style-revert-layer-crash.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/inline-style-revert-layer-crash.html
new file mode 100644
index 0000000..f1a900e6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/inline-style-revert-layer-crash.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<head>
+ <title>Crash with inline style being changed to revert-rule</title>
+ <link rel="help" href="https://crbug.com/515426873">
+</head>
+<body>
+ <div id="d">Test passes if there is no crash.</div>
+ <script>
+ const d = document.getElementById('d');
+ d.style.color = 'green';
+ d.offsetTop;
+ d.style.color = 'revert-rule';
+ </script>
+</body>
Regression Test / PoC
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/inline-style-revert-layer-crash.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/inline-style-revert-layer-crash.html
new file mode 100644
index 0000000..f1a900e6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/inline-style-revert-layer-crash.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<head>
+ <title>Crash with inline style being changed to revert-rule</title>
+ <link rel="help" href="https://crbug.com/515426873">
+</head>
+<body>
+ <div id="d">Test passes if there is no crash.</div>
+ <script>
+ const d = document.getElementById('d');
+ d.style.color = 'green';
+ d.offsetTop;
+ d.style.color = 'revert-rule';
+ </script>
+</body>
Original Bug Report
Type confusion in Blink style resolution fast path via 'revert-rule' keyword
Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: The Modified Independent Style Update (MISU) fast path in Blink fails to filter the ‘revert-rule’ keyword, leading to a type confusion in color resolution. This allows a ‘revert-rule’ value to be incorrectly cast to a light-dark pair, resulting in an out-of-bounds read. On certain platforms, this could potentially lead to renderer memory disclosure.
Affected files:
third_party/blink/renderer/core/css/resolver/style_resolver.ccthird_party/blink/renderer/core/css/resolver/style_builder_converter.ccthird_party/blink/renderer/core/css/resolver/style_builder.cc
Estimated timestamp from git blame: 2026-03-18
Description
Blink uses an optimization called Modified Independent Style Update (MISU) to efficiently update styles when only independent properties are changed. This path bypasses the full StyleCascade for performance. To ensure correctness, the function CanApplyInlineStyleIncrementally in third_party/blink/renderer/core/css/resolver/style_resolver.cc must filter out any values that are cascade-dependent.
While this function correctly rejects keywords like revert and revert-layer, it does not currently filter the revert-rule keyword. Consequently, when an inline style is updated to revert-rule, it proceeds through the MISU fast path and is applied directly via StyleBuilder::ApplyProperty.
For properties using the color style builder template (e.g., background-color, border-color, outline-color), this eventually reaches ResolveColorValueImpl in third_party/blink/renderer/core/css/resolver/style_builder_converter.cc. This function performs a series of type checks but lacks a check for CSSRevertRuleValue. When it encounters an unrecognized value, it performs a To<CSSLightDarkValuePair>(value) cast (which is a static_cast in release builds):
// third_party/blink/renderer/core/css/resolver/style_builder_converter.cc:2999
auto& light_dark_pair = To<CSSLightDarkValuePair>(value);
const CSSValue& color_value = ResolveLightDarkPair(light_dark_pair, context);
return ResolveColorValueImpl(color_value, context);
Since CSSRevertRuleValue is significantly smaller than CSSLightDarkValuePair and does not contain the expected Member<CSSValue> pointers, ResolveLightDarkPair performs an out-of-bounds read of memory following the CSSRevertRuleValue object on the heap.
Impact
In most environments, this will result in a near-null pointer dereference and a renderer process crash (Denial of Service). However, on 32-bit platforms without pointer compression (such as Android), an attacker may be able to exploit the predictable memory layout of the CSSValuePool or perform heap grooming to read pointers from adjacent objects. This could potentially allow arbitrary renderer heap data to be leaked into the computed style, where it can be read back via JavaScript.
Potential Reproduction Steps
Note: These are suggested steps; this issue was identified through manual code review and has not yet been verified with a functional PoC.
- Create an element with an initial inline color:
<div id="test" style="background-color: blue"></div>. - Force a style calculation to ensure a cached
ComputedStyleexists:test.offsetTop;. - Update the inline style to use the
revert-rulekeyword:test.style.backgroundColor = 'revert-rule';. - Trigger a style recalculation to enter the MISU path:
window.getComputedStyle(test).backgroundColor;. - In a Debug build, a
DCHECKfailure is expected. In a Release build, the process may crash or return incorrect color data.
Suggested Fix
Update CanApplyInlineStyleIncrementally in third_party/blink/renderer/core/css/resolver/style_resolver.cc to include IsRevertRuleValue() in the cascade-dependent keyword filter:
if (property.Value().IsUnparsedDeclaration() ||
property.Value().IsPendingSubstitutionValue() ||
property.Value().IsRevertValue() ||
property.Value().IsRevertLayerValue() ||
property.Value().IsRevertRuleValue()) {
return false;
}
Alternatively, use the existing IsCascadeDependentKeyword() helper which covers all three keywords.
Evaluated with Chrome root at commit: 29093e11cf509e3593f6229e4b1b075cca356049
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.