High chrome Race 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactRace condition in V8
DescriptionRace condition in V8
ComponentV8
Bug ClassRace
Tracker541837151
Fix commit81b2acf3bbfe (v8/v8) +19/-9
CISA KEVNot listed
CreditedSalvatore Gulizia (nickname: Serotav)
Disclosed2026-08-20

Files Changed

  • src/codegen/compiler.cc
  • src/objects/shared-function-info-inl.h
  • src/objects/shared-function-info.h
From 81b2acf3bbfecea934d5daed87c27da6347b3182 Mon Sep 17 00:00:00 2001
From: Leszek Swirski <leszeks@chromium.org>
Date: Fri, 07 Aug 2026 13:30:03 +0200
Subject: [PATCH] [compiler] Avoid race condition when reading ScopeInfo during background merge

RecordScopeInfos(Tagged<HeapObject> info) has a potential race condition
on accesses to both scope_info and OuterScopeInfo, which can both be
mutated if the function is concurrently compiled with a background merge.

Fix this by introducing SharedFunctionInfo::TryGetScopeInfoForMerge(),
which performs a single acquire load pass on name_or_scope_info and
raw_outer_scope_info_or_feedback_metadata, returning empty scope info
if neither contains a ScopeInfo.

TAG=agy
CONV=b92d625a-0a50-4a77-88a9-f6a53902a539

Bug: 541837151
Change-Id: Id342ee00ec85c8dc33475ea484e74ea243c5b5ec
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8219869
Commit-Queue: Patrick Thier <pthier@chromium.org>
Reviewed-by: Patrick Thier <pthier@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#109131}
---

diff --git a/src/codegen/compiler.cc b/src/codegen/compiler.cc
index 4ced00f..0b1e512 100644
--- a/src/codegen/compiler.cc
+++ b/src/codegen/compiler.cc
@@ -2082,15 +2082,11 @@
   void RecordScopeInfos(Tagged<HeapObject> info) {
     Tagged<ScopeInfo> scope_info;
     if (Is<SharedFunctionInfo>(info)) {
-      Tagged<SharedFunctionInfo> old_sfi = Cast<SharedFunctionInfo>(info);
-      // Also record own scope infos for SFIs.
-      if (!old_sfi->scope_info()->IsEmpty()) {
-        scope_info = old_sfi->scope_info();
-      } else if (old_sfi->HasOuterScopeInfo()) {
-        scope_info = old_sfi->GetOuterScopeInfo();
-      } else {
-        return;
-      }
+      // We can get an empty scope info here for a function that is racily
+      // getting compiled, which is ok because we will revisit it during
+      // foreground merging.
+      scope_info = Cast<SharedFunctionInfo>(info)->TryGetScopeInfoForMerge();
+      if (scope_info->IsEmpty()) return;
     } else {
       scope_info = Cast<ScopeInfo>(info);
     }
diff --git a/src/objects/shared-function-info-inl.h b/src/objects/shared-function-info-inl.h
index 588843f..617f3b1 100644
--- a/src/objects/shared-function-info-inl.h
+++ b/src/objects/shared-function-info-inl.h
@@ -728,6 +728,19 @@
   return info->OuterScopeInfo();
 }
 
+Tagged<ScopeInfo> SharedFunctionInfo::TryGetScopeInfoForMerge() const {
+  Tagged<Object> maybe_scope_info = name_or_scope_info(kAcquireLoad);
+  if (IsScopeInfo(maybe_scope_info)) {
+    return Cast<ScopeInfo>(maybe_scope_info);
+  }
+  Tagged<Object> maybe_outer_scope_info_or_feedback =
+      raw_outer_scope_info_or_feedback_metadata(kAcquireLoad);
+  if (IsScopeInfo(maybe_outer_scope_info_or_feedback)) {
+    return Cast<ScopeInfo>(maybe_outer_scope_info_or_feedback);
+  }
+  return GetReadOnlyRoots().empty_scope_info();
+}
+
 void SharedFunctionInfo::set_outer_scope_info(
     Tagged<UnionOf<ScopeInfo, TheHole>> value, WriteBarrierMode mode) {
   DCHECK(!is_compiled());
diff --git a/src/objects/shared-function-info.h b/src/objects/shared-function-info.h
index 1ea073e..841c586 100644
--- a/src/objects/shared-function-info.h
+++ b/src/objects/shared-function-info.h
@@ -408,6 +408,7 @@
   // Get the outer scope info whether this function is compiled or not.
   inline bool HasOuterScopeInfo() const;
   inline Tagged<ScopeInfo> GetOuterScopeInfo() const;
+  inline Tagged<ScopeInfo> TryGetScopeInfoForMerge() const;
 
   // [feedback metadata] Metadata template for feedback vectors of instances of
   // this function.
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.