summaryrefslogtreecommitdiffstats
path: root/meta/recipes-sato/webkit/webkitgtk/CVE-2022-46699.patch
blob: 0752b9c0e235c7f96ebebe0590529507135eab79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
From 28686e63de0d3d7270a49b0d6b656467bc4fbf68 Mon Sep 17 00:00:00 2001
From: Justin Michaud <justin_michaud@apple.com>
Date: Wed, 9 Nov 2022 19:20:41 -0800
Subject: [PATCH] Error() ICs should not cache special properties.
 https://bugs.webkit.org/show_bug.cgi?id=247699

Reviewed by Yusuke Suzuki.

HasOwnProperty/DeleteProperty are not always cacheable for special Error()
properties like column. These special properties are materialized on-demand
in materializeErrorInfoIfNeeded, but this function's behaviour can be changed
by Error.stackTraceLimit without causing a structure transition or firing watchpoints.

That is, we cannot cache property misses, and we cannot assume HasOwnProperty is deterministic
for a given structure if we are using one of these properties.

* Source/JavaScriptCore/runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::deleteProperty):
* Source/JavaScriptCore/runtime/ErrorInstance.h:

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

CVE: CVE-2022-46699

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

Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
 JSTests/stress/delete-cache-error.js          | 19 ++++++++++++++++++
 .../get-own-property-slot-cache-error.js      |  6 ++++++
 JSTests/stress/get-property-cache-error.js    | 20 +++++++++++++++++++
 .../JavaScriptCore/runtime/ErrorInstance.cpp  |  4 +++-
 Source/JavaScriptCore/runtime/ErrorInstance.h |  3 ++-
 5 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 JSTests/stress/delete-cache-error.js
 create mode 100644 JSTests/stress/get-own-property-slot-cache-error.js
 create mode 100644 JSTests/stress/get-property-cache-error.js

diff --git a/JSTests/stress/delete-cache-error.js b/JSTests/stress/delete-cache-error.js
new file mode 100644
index 000000000000..d77c09185a13
--- /dev/null
+++ b/JSTests/stress/delete-cache-error.js
@@ -0,0 +1,19 @@
+delete Error.stackTraceLimit
+
+// sourceURL is not materialized
+function cacheColumn(o) {
+    delete o.sourceURL
+}
+noInline(cacheColumn)
+
+for (let i = 0; i < 200; ++i) {
+    let e = Error()
+    cacheColumn(e)
+    if (e.sourceURL !== undefined)
+        throw "Test failed on iteration " + i + " " + e.sourceURL
+
+    if (i == 197) {
+        // now it is
+        Error.stackTraceLimit = 10
+    }
+}
\ No newline at end of file
diff --git a/JSTests/stress/get-own-property-slot-cache-error.js b/JSTests/stress/get-own-property-slot-cache-error.js
new file mode 100644
index 000000000000..f8202213bf79
--- /dev/null
+++ b/JSTests/stress/get-own-property-slot-cache-error.js
@@ -0,0 +1,6 @@
+delete Error.stackTraceLimit
+// GetOwnPropertySlot does not materializeErrorInfoIfNeeded because stackString is null.
+Object.hasOwn(Error(), "column")
+Error.stackTraceLimit = 10
+// Now it does
+Object.hasOwn(Error(), "column")
\ No newline at end of file
diff --git a/JSTests/stress/get-property-cache-error.js b/JSTests/stress/get-property-cache-error.js
new file mode 100644
index 000000000000..b35272ea6fe2
--- /dev/null
+++ b/JSTests/stress/get-property-cache-error.js
@@ -0,0 +1,20 @@
+// GetOwnPropertySlot does not materializeErrorInfoIfNeeded because stackString is null.
+delete Error.stackTraceLimit
+expected = undefined
+
+function cacheColumn(o) {
+    return o.column
+}
+noInline(cacheColumn)
+
+for (let i = 0; i < 1000; ++i) {
+    let val = cacheColumn(Error())
+    if (val !== expected)
+        throw "Test failed on iteration " + i + ": " + val
+
+    if (i == 900) {
+        // now it does
+        Error.stackTraceLimit = 10
+        expected = 32
+    }
+}
\ No newline at end of file
diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
index ddf96869e84a..8e5373257d34 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp
@@ -303,7 +303,9 @@ bool ErrorInstance::deleteProperty(JSCell* cell, JSGlobalObject* globalObject, P
 {
     VM& vm = globalObject->vm();
     ErrorInstance* thisObject = jsCast<ErrorInstance*>(cell);
-    thisObject->materializeErrorInfoIfNeeded(vm, propertyName);
+    bool materializedProperties = thisObject->materializeErrorInfoIfNeeded(vm, propertyName);
+    if (materializedProperties)
+        slot.disableCaching();
     return Base::deleteProperty(thisObject, globalObject, propertyName, slot);
 }

diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.h b/Source/JavaScriptCore/runtime/ErrorInstance.h
index 28807b4ea33e..2afb153a7442 100644
--- a/Source/JavaScriptCore/runtime/ErrorInstance.h
+++ b/Source/JavaScriptCore/runtime/ErrorInstance.h
@@ -30,7 +30,8 @@ namespace JSC {
 class ErrorInstance : public JSNonFinalObject {
 public:
     using Base = JSNonFinalObject;
-    static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetOwnSpecialPropertyNames | OverridesPut;
+
+    static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetOwnSpecialPropertyNames | OverridesPut | GetOwnPropertySlotIsImpureForPropertyAbsence;
     static constexpr bool needsDestruction = true;

     static void destroy(JSCell* cell)
--
2.40.0