CVE-2025-43529

Overview

Advisory: Apple Security Advisory

Impact:

Description: Processing maliciously crafted web content may lead to arbitrary code execution. Apple is aware of a report that this issue may have been exploited in an extremely sophisticated attack against specific targeted individuals on versions of iOS before iOS 26. CVE-2025-14174 was also issued in response to this report.

Researchers: Google Threat Analysis Group

Attribute Value
CVE CVE-2025-43529
Bugzilla 302502
Component JSC
Bug Class UAF
Severity critical
Commit b21a503b579a8ab1…
Advisory Apple Advisory

Root Cause Analysis

A use-after-free issue was addressed with improved memory management.

Files Changed

Source Files

  • Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp

Patch Preview

diff --git a/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
index 88cb74d592c3..29b9a17175b7 100644
--- a/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStoreBarrierInsertionPhase.cpp
@@ -204,7 +204,17 @@ class StoreBarrierInsertionPhase : public Phase {
         bool result = true;
 
         UncheckedKeyHashMap<AbstractHeap, Node*> potentialStackEscapes;
-        
+        auto escape = [&](Node* node) {
+            if (mode == PhaseMode::Global) {
+                m_interpreter->phiChildren()->forAllTransitiveIncomingValues(
+                    node,
+                    [&](Node* incoming) {
+                        incoming->setEpoch(Epoch());
+                    });
+            } else
+                node->setEpoch(Epoch());
+        };
+
         for (m_nodeIndex = 0; m_nodeIndex < block->size(); ++m_nodeIndex) {
             m_node = block->at(m_nodeIndex);
             
@@ -460,7 +470,7 @@ class StoreBarrierInsertionPhase : public Phase {
                         return;
                     potentialStackEscapes.removeIf([&] (const auto& entry) {
                         if (entry.key.overlaps(heap)) {
-                            entry.value->setEpoch(Epoch());
+                            escape(entry.value);
                             return true;
                         }
                         return false;
@@ -480,10 +490,6 @@ class StoreBarrierInsertionPhase : public Phase {
                 clobberize(m_graph, m_node, readFunc, writeFunc, NoOpClobberize());
 
                 if (wroteHeapOrStack) {
-                    auto escape = [&] (Node* node) {
-                        node->setEpoch(Epoch());
-                    };
-
                     auto escapeToTheStack = [&] (Node* node) {
                         if (node->epoch() == m_currentEpoch) {
                             RELEASE_ASSERT(!!preciseStackWrite);
@@ -549,7 +555,7 @@ class StoreBarrierInsertionPhase : public Phase {
 
         {
             for (auto* node : potentialStackEscapes.values())
-                node->setEpoch(Epoch());
+                escape(node);
             potentialStackEscapes.clear();
         }