CVE-2026-64783

Overview

Advisory: Apple Security Advisory

Impact:

Description: Processing maliciously crafted web content may lead to an unexpected Safari crash

Researchers: 杉山 壮太, lattice, Behzad Najjarpour Jabbari (@G4ru), Junyeong Lee, Mooth.ai, OGINOME Tomohito, Using GLM From Z.AI, Gia Bui (@yabeow) from Calif.io

Attribute Value
CVE CVE-2026-64783
Bugzilla 313521
Component WebCore
Bug Class UAF
Severity medium
Commit be08720593705c04…
Advisory Apple Advisory

Root Cause Analysis

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

Files Changed

Source Files

  • Source/WebCore/html/TextFieldInputType.cpp
  • Source/WebCore/html/shadow/DataListButtonElement.cpp
  • Source/WebCore/html/shadow/DataListButtonElement.h

Test Files

  • LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash-expected.txt
  • LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash.html

Patch Preview

diff --git a/LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash-expected.txt b/LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash-expected.txt
new file mode 100644
index 000000000000..e1f00b8f5f64
--- /dev/null
+++ b/LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash-expected.txt
@@ -0,0 +1,5 @@
+PASS if no crash.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash.html b/LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash.html
new file mode 100644
index 000000000000..cfb0e901651f
--- /dev/null
+++ b/LayoutTests/fast/forms/datalist/datalist-button-change-input-type-on-click-crash.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<style>
+input {
+    width: 300px;
+    height: 50px;
+}
+</style>
+</head>
+<body>
+<input id="input" type="text" list="list">
+<datalist id="list"><option value="a"><option value="b"></datalist>
+<script>
+
+jsTestIsAsync = true;
+
+addEventListener("load", async () => {
+    input.addEventListener('click', (e) => {
+        input.type = 'button';
+        gc();
+    }, { once: true });
+
+    if (window.internals) {
+        let shadow = internals.shadowRoot(input);
+        let listButton = shadow.querySelector("div[useragentpart='-webkit-list-button']");
+
+        await UIHelper.activateElement(listButton);
+    }
+
+    debug("PASS if no crash.");
+    finishJSTest();
+});
+
+</script>
+</body>
+</html>
diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp
index e07626ba7197..a1e8fa815c81 100644
--- a/Source/WebCore/html/TextFieldInputType.cpp
+++ b/Source/WebCore/html/TextFieldInputType.cpp
@@ -428,6 +428,8 @@ void TextFieldInputType::removeShadowSubtree()
     if (RefPtr autoFillButton = m_autoFillButton.get())
         autoFillButton->removeOwner();
     m_autoFillButton = nullptr;
+    if (RefPtr dataListDropdownIndicator = m_dataListDropdownIndicator)
+        dataListDropdownIndicator->removeOwner();
     m_dataListDropdownIndicator = nullptr;
     m_container = nullptr;
 }
diff --git a/Source/WebCore/html/shadow/DataListButtonElement.cpp b/Source/WebCore/html/shadow/DataListButtonElement.cpp
index be70a35cbf4c..71e15afbe7d4 100644
--- a/Source/WebCore/html/shadow/DataListButtonElement.cpp
+++ b/Source/WebCore/html/shadow/DataListButtonElement.cpp
@@ -61,7 +61,8 @@ void DataListButtonElement::defaultEventHandler(Event& event)
     }
 
     if (isAnyClick(*mouseEvent)) {
-        m_owner.dataListButtonElementWasClicked();
+        if (RefPtr owner = m_owner)
+            owner->dataListButtonElementWasClicked();
         event.setDefaultHandled();
     }
 
diff --git a/Source/WebCore/html/shadow/DataListButtonElement.h b/Source/WebCore/html/shadow/DataListButtonElement.h
index 1b483b651c07..75fefd1dae14 100644
--- a/Source/WebCore/html/shadow/DataListButtonElement.h
+++ b/Source/WebCore/html/shadow/DataListButtonElement.h
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "HTMLDivElement.h"
+#include <wtf/AbstractRefCountedAndCanMakeWeakPtr.h>
 
 namespace WebCore {
 
@@ -35,7 +36,7 @@ class DataListButtonElement final : public HTMLDivElement {
     WTF_MAKE_TZONE_ALLOCATED(DataListButtonElement);
     WTF_OVERRIDE_DELETE_FOR_CHECKED_PTR(DataListButtonElement);
 public:
-    class DataListButtonOwner {
+    class DataListButtonOwner : public AbstractRefCountedAndCanMakeWeakPtr<DataListButtonOwner> {
     public:
         virtual ~DataListButtonOwner() = default;
         virtual void dataListButtonElementWasClicked() = 0;
@@ -47,6 +48,8 @@ class DataListButtonElement final : public HTMLDivElement {
 
     bool canAdjustStyleForAppearance() const { return m_canAdjustStyleForAppearance; }
 
+    void removeOwner() { m_owner = nullptr; }
+
 private:
     explicit DataListButtonElement(Document&, DataListButtonOwner&);
 
@@ -56,7 +59,7 @@ class DataListButtonElement final : public HTMLDivElement {
     void defaultEventHandler(Event&) final;
     bool isDisabledFormControl() const final;
 
-    DataListButtonOwner& m_owner;
+    WeakPtr<DataListButtonOwner> m_owner;
     bool m_canAdjustStyleForAppearance { true };
 };