From ebefb9e6b7e7440ab6bb29452f4ac6350bd8b975 Mon Sep 17 00:00:00 2001
From: Yijia Huang <yijia_huang@apple.com>
Date: Tue, 26 Sep 2023 09:23:31 +0000
Subject: [PATCH] Cherry-pick 263909@main (52fe95e5805c).
 https://bugs.webkit.org/show_bug.cgi?id=256567

    EnumeratorNextUpdateIndexAndMode and HasIndexedProperty should have different heap location kinds
    https://bugs.webkit.org/show_bug.cgi?id=256567
    rdar://109089013

    Reviewed by Yusuke Suzuki.

    EnumeratorNextUpdateIndexAndMode and HasIndexedProperty are different DFG nodes. However,
    they might introduce the same heap location kind in DFGClobberize.h which might lead to
    hash collision. We should introduce a new locationn kind for EnumeratorNextUpdateIndexAndMode.

    * JSTests/stress/heap-location-collision-dfg-clobberize.js: Added.
    (foo):
    * Source/JavaScriptCore/dfg/DFGClobberize.h:
    (JSC::DFG::clobberize):
    * Source/JavaScriptCore/dfg/DFGHeapLocation.cpp:
    (WTF::printInternal):
    * Source/JavaScriptCore/dfg/DFGHeapLocation.h:

    Canonical link: https://commits.webkit.org/263909@main

Canonical link: https://commits.webkit.org/260527.376@webkitglib/2.40

CVE: CVE-2023-32439

Upstream-Status: Backport [https://github.com/WebKit/WebKit/commit/ebefb9e]

Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
 .../stress/heap-location-collision-dfg-clobberize.js | 12 ++++++++++++
 Source/JavaScriptCore/dfg/DFGClobberize.h            |  7 ++++---
 Source/JavaScriptCore/dfg/DFGHeapLocation.cpp        |  4 ++++
 Source/JavaScriptCore/dfg/DFGHeapLocation.h          |  1 +
 4 files changed, 21 insertions(+), 3 deletions(-)
 create mode 100644 JSTests/stress/heap-location-collision-dfg-clobberize.js

diff --git a/JSTests/stress/heap-location-collision-dfg-clobberize.js b/JSTests/stress/heap-location-collision-dfg-clobberize.js
new file mode 100644
index 00000000..ed40601e
--- /dev/null
+++ b/JSTests/stress/heap-location-collision-dfg-clobberize.js
@@ -0,0 +1,12 @@
+//@ runDefault("--watchdog=300", "--watchdog-exception-ok")
+const arr = [0];
+
+function foo() {
+    for (let _ in arr) {
+        0 in arr;
+        while(1);
+    }
+}
+
+
+foo();
diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h
index f96e21d2..af3e864b 100644
--- a/Source/JavaScriptCore/dfg/DFGClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h
@@ -371,6 +371,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu

         read(JSObject_butterfly);
         ArrayMode mode = node->arrayMode();
+        LocationKind locationKind = node->op() == EnumeratorNextUpdateIndexAndMode ? EnumeratorNextUpdateIndexAndModeLoc : HasIndexedPropertyLoc;
         switch (mode.type()) {
         case Array::ForceExit: {
             write(SideState);
@@ -380,7 +381,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
             if (mode.isInBounds()) {
                 read(Butterfly_publicLength);
                 read(IndexedInt32Properties);
-                def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
+                def(HeapLocation(locationKind, IndexedInt32Properties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
                 return;
             }
             break;
@@ -390,7 +391,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
             if (mode.isInBounds()) {
                 read(Butterfly_publicLength);
                 read(IndexedDoubleProperties);
-                def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
+                def(HeapLocation(locationKind, IndexedDoubleProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
                 return;
             }
             break;
@@ -400,7 +401,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
             if (mode.isInBounds()) {
                 read(Butterfly_publicLength);
                 read(IndexedContiguousProperties);
-                def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
+                def(HeapLocation(locationKind, IndexedContiguousProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
                 return;
             }
             break;
diff --git a/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp b/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
index 0661e5b8..698a6d4b 100644
--- a/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
+++ b/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp
@@ -134,6 +134,10 @@ void printInternal(PrintStream& out, LocationKind kind)
         out.print("HasIndexedPorpertyLoc");
         return;

+    case EnumeratorNextUpdateIndexAndModeLoc:
+        out.print("EnumeratorNextUpdateIndexAndModeLoc");
+        return;
+
     case IndexedPropertyDoubleLoc:
         out.print("IndexedPropertyDoubleLoc");
         return;
diff --git a/Source/JavaScriptCore/dfg/DFGHeapLocation.h b/Source/JavaScriptCore/dfg/DFGHeapLocation.h
index 40fb7167..7238491b 100644
--- a/Source/JavaScriptCore/dfg/DFGHeapLocation.h
+++ b/Source/JavaScriptCore/dfg/DFGHeapLocation.h
@@ -46,6 +46,7 @@ enum LocationKind {
     DirectArgumentsLoc,
     GetterLoc,
     GlobalVariableLoc,
+    EnumeratorNextUpdateIndexAndModeLoc,
     HasIndexedPropertyLoc,
     IndexedPropertyDoubleLoc,
     IndexedPropertyDoubleSaneChainLoc,
--
2.40.0
