summaryrefslogtreecommitdiffstats
path: root/meta/recipes-sato/webkit/webkitgtk/CVE-2022-48503.patch
blob: b67751736d09f84993ef7699238a03891bc83ed8 (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
From 612c245823a515c8c70c2ad486957bd8a850f0f9 Mon Sep 17 00:00:00 2001
From: Yusuke Suzuki <ysuzuki@apple.com>
Date: Tue, 5 Sep 2023 08:40:19 +0000
Subject: [PATCH] [JSC] Refactor wasm section ordering code
 https://bugs.webkit.org/show_bug.cgi?id=241931 rdar://83326477

Reviewed by Keith Miller.

This patch refactors existing validateOrder code since it is too adhoc right now.

* Source/JavaScriptCore/wasm/WasmModuleInformation.h:
(JSC::Wasm::ModuleInformation::dataSegmentsCount const):
* Source/JavaScriptCore/wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseData):
(JSC::Wasm::SectionParser::parseDataCount):
* Source/JavaScriptCore/wasm/WasmSectionParser.h:
* Source/JavaScriptCore/wasm/WasmSections.h:
(JSC::Wasm::orderingNumber):
(JSC::Wasm::isKnownSection):
(JSC::Wasm::validateOrder):
(JSC::Wasm::makeString):
* Source/JavaScriptCore/wasm/WasmStreamingParser.cpp:
(JSC::Wasm::StreamingParser::parseSectionPayload):
(JSC::Wasm::StreamingParser::finalize):

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

CVE: CVE-2022-48503

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

Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
 .../wasm/WasmModuleInformation.h              |  4 +-
 .../JavaScriptCore/wasm/WasmSectionParser.cpp |  3 ++
 .../JavaScriptCore/wasm/WasmSectionParser.h   |  2 +-
 Source/JavaScriptCore/wasm/WasmSections.h     | 52 +++++++++++--------
 .../wasm/WasmStreamingParser.cpp              | 11 +++-
 5 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/Source/JavaScriptCore/wasm/WasmModuleInformation.h b/Source/JavaScriptCore/wasm/WasmModuleInformation.h
index ae6bbeed..f9f1baf7 100644
--- a/Source/JavaScriptCore/wasm/WasmModuleInformation.h
+++ b/Source/JavaScriptCore/wasm/WasmModuleInformation.h
@@ -86,7 +86,7 @@ struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
     uint32_t memoryCount() const { return memory ? 1 : 0; }
     uint32_t tableCount() const { return tables.size(); }
     uint32_t elementCount() const { return elements.size(); }
-    uint32_t dataSegmentsCount() const { return numberOfDataSegments; }
+    uint32_t dataSegmentsCount() const { return numberOfDataSegments.value_or(0); }

     const TableInformation& table(unsigned index) const { return tables[index]; }

@@ -131,7 +131,7 @@ struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
     Vector<CustomSection> customSections;
     Ref<NameSection> nameSection;
     BranchHints branchHints;
-    uint32_t numberOfDataSegments { 0 };
+    std::optional<uint32_t> numberOfDataSegments;

     BitVector m_declaredFunctions;
     BitVector m_declaredExceptions;
diff --git a/Source/JavaScriptCore/wasm/WasmSectionParser.cpp b/Source/JavaScriptCore/wasm/WasmSectionParser.cpp
index 5b511811..c55ee3c0 100644
--- a/Source/JavaScriptCore/wasm/WasmSectionParser.cpp
+++ b/Source/JavaScriptCore/wasm/WasmSectionParser.cpp
@@ -768,6 +768,8 @@ auto SectionParser::parseData() -> PartialResult
     uint32_t segmentCount;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(segmentCount), "can't get Data section's count");
     WASM_PARSER_FAIL_IF(segmentCount > maxDataSegments, "Data section's count is too big ", segmentCount, " maximum ", maxDataSegments);
+    if (m_info->numberOfDataSegments)
+        WASM_PARSER_FAIL_IF(segmentCount != m_info->numberOfDataSegments.value(), "Data section's count ", segmentCount, " is different from Data Count section's count ", m_info->numberOfDataSegments.value());
     WASM_PARSER_FAIL_IF(!m_info->data.tryReserveCapacity(segmentCount), "can't allocate enough memory for Data section's ", segmentCount, " segments");

     for (uint32_t segmentNumber = 0; segmentNumber < segmentCount; ++segmentNumber) {
@@ -847,6 +849,7 @@ auto SectionParser::parseDataCount() -> PartialResult
 {
     uint32_t numberOfDataSegments;
     WASM_PARSER_FAIL_IF(!parseVarUInt32(numberOfDataSegments), "can't get Data Count section's count");
+    WASM_PARSER_FAIL_IF(numberOfDataSegments > maxDataSegments, "Data Count section's count is too big ", numberOfDataSegments , " maximum ", maxDataSegments);

     m_info->numberOfDataSegments = numberOfDataSegments;
     return { };
diff --git a/Source/JavaScriptCore/wasm/WasmSectionParser.h b/Source/JavaScriptCore/wasm/WasmSectionParser.h
index 91fd3ed8..4d7dcbac 100644
--- a/Source/JavaScriptCore/wasm/WasmSectionParser.h
+++ b/Source/JavaScriptCore/wasm/WasmSectionParser.h
@@ -44,7 +44,7 @@ public:
     {
     }

-#define WASM_SECTION_DECLARE_PARSER(NAME, ID, DESCRIPTION) PartialResult WARN_UNUSED_RETURN parse ## NAME();
+#define WASM_SECTION_DECLARE_PARSER(NAME, ID, ORDERING, DESCRIPTION) PartialResult WARN_UNUSED_RETURN parse ## NAME();
     FOR_EACH_KNOWN_WASM_SECTION(WASM_SECTION_DECLARE_PARSER)
 #undef WASM_SECTION_DECLARE_PARSER

diff --git a/Source/JavaScriptCore/wasm/WasmSections.h b/Source/JavaScriptCore/wasm/WasmSections.h
index bef20701..b422a587 100644
--- a/Source/JavaScriptCore/wasm/WasmSections.h
+++ b/Source/JavaScriptCore/wasm/WasmSections.h
@@ -33,20 +33,21 @@ IGNORE_RETURN_TYPE_WARNINGS_BEGIN

 namespace JSC { namespace Wasm {

+// macro(Name, ID, OrderingNumber, Description).
 #define FOR_EACH_KNOWN_WASM_SECTION(macro) \
-    macro(Type,       1, "Function signature declarations") \
-    macro(Import,     2, "Import declarations") \
-    macro(Function,   3, "Function declarations") \
-    macro(Table,      4, "Indirect function table and other tables") \
-    macro(Memory,     5, "Memory attributes") \
-    macro(Global,     6, "Global declarations") \
-    macro(Export,     7, "Exports") \
-    macro(Start,      8, "Start function declaration") \
-    macro(Element,    9, "Elements section") \
-    macro(Code,      10, "Function bodies (code)") \
-    macro(Data,      11, "Data segments") \
-    macro(DataCount, 12, "Data count") \
-    macro(Exception, 13, "Exception declarations") \
+    macro(Type,       1,  1, "Function signature declarations") \
+    macro(Import,     2,  2, "Import declarations") \
+    macro(Function,   3,  3, "Function declarations") \
+    macro(Table,      4,  4, "Indirect function table and other tables") \
+    macro(Memory,     5,  5, "Memory attributes") \
+    macro(Global,     6,  7, "Global declarations") \
+    macro(Export,     7,  8, "Exports") \
+    macro(Start,      8,  9, "Start function declaration") \
+    macro(Element,    9, 10, "Elements section") \
+    macro(Code,      10, 12, "Function bodies (code)") \
+    macro(Data,      11, 13, "Data segments") \
+    macro(DataCount, 12, 11, "Data count") \
+    macro(Exception, 13,  6, "Exception declarations") \

 enum class Section : uint8_t {
     // It's important that Begin is less than every other section number and that Custom is greater.
@@ -54,18 +55,29 @@ enum class Section : uint8_t {
     // Also, Begin is not a real section but is used as a marker for validating the ordering
     // of sections.
     Begin = 0,
-#define DEFINE_WASM_SECTION_ENUM(NAME, ID, DESCRIPTION) NAME = ID,
+#define DEFINE_WASM_SECTION_ENUM(NAME, ID, ORDERING, DESCRIPTION) NAME = ID,
     FOR_EACH_KNOWN_WASM_SECTION(DEFINE_WASM_SECTION_ENUM)
 #undef DEFINE_WASM_SECTION_ENUM
     Custom
 };
 static_assert(static_cast<uint8_t>(Section::Begin) < static_cast<uint8_t>(Section::Type), "Begin should come before the first known section.");

+inline unsigned orderingNumber(Section section)
+{
+    switch (section) {
+#define ORDERING_OF_SECTION(NAME, ID, ORDERING, DESCRIPTION) case Section::NAME: return ORDERING;
+        FOR_EACH_KNOWN_WASM_SECTION(ORDERING_OF_SECTION)
+#undef VALIDATE_SECTION
+    default:
+        return static_cast<unsigned>(section);
+    }
+}
+
 template<typename Int>
 inline bool isKnownSection(Int section)
 {
     switch (section) {
-#define VALIDATE_SECTION(NAME, ID, DESCRIPTION) case static_cast<Int>(Section::NAME): return true;
+#define VALIDATE_SECTION(NAME, ID, ORDERING, DESCRIPTION) case static_cast<Int>(Section::NAME): return true;
         FOR_EACH_KNOWN_WASM_SECTION(VALIDATE_SECTION)
 #undef VALIDATE_SECTION
     default:
@@ -89,13 +101,7 @@ inline bool decodeSection(uint8_t sectionByte, Section& section)
 inline bool validateOrder(Section previousKnown, Section next)
 {
     ASSERT(isKnownSection(previousKnown) || previousKnown == Section::Begin);
-    if (previousKnown == Section::DataCount && next == Section::Code)
-        return true;
-    if (previousKnown == Section::Exception)
-        return next >= Section::Global;
-    if (next == Section::Exception)
-        return previousKnown <= Section::Memory;
-    return static_cast<uint8_t>(previousKnown) < static_cast<uint8_t>(next);
+    return orderingNumber(previousKnown) < orderingNumber(next);
 }

 inline const char* makeString(Section section)
@@ -105,7 +111,7 @@ inline const char* makeString(Section section)
         return "Begin";
     case Section::Custom:
         return "Custom";
-#define STRINGIFY_SECTION_NAME(NAME, ID, DESCRIPTION) case Section::NAME: return #NAME;
+#define STRINGIFY_SECTION_NAME(NAME, ID, ORDERING, DESCRIPTION) case Section::NAME: return #NAME;
         FOR_EACH_KNOWN_WASM_SECTION(STRINGIFY_SECTION_NAME)
 #undef STRINGIFY_SECTION_NAME
     }
diff --git a/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp b/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp
index fa552eff..25e7e32d 100644
--- a/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp
+++ b/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp
@@ -161,7 +161,7 @@ auto StreamingParser::parseSectionPayload(Vector<uint8_t>&& data) -> State
 {
     SectionParser parser(data.data(), data.size(), m_offset, m_info.get());
     switch (m_section) {
-#define WASM_SECTION_PARSE(NAME, ID, DESCRIPTION) \
+#define WASM_SECTION_PARSE(NAME, ID, ORDERING, DESCRIPTION) \
     case Section::NAME: { \
         WASM_STREAMING_PARSER_FAIL_IF_HELPER_FAILS(parser.parse ## NAME()); \
         break; \
@@ -393,9 +393,18 @@ auto StreamingParser::finalize() -> State
             m_state = fail("Number of functions parsed (", m_functionCount, ") does not match the number of declared functions (", m_info->functions.size(), ")");
             break;
         }
+
+        if (m_info->numberOfDataSegments) {
+            if (UNLIKELY(m_info->data.size() != m_info->numberOfDataSegments.value())) {
+                m_state = fail("Data section's count ", m_info->data.size(), " is different from Data Count section's count ", m_info->numberOfDataSegments.value());
+                break;
+            }
+        }
+
         if (m_remaining.isEmpty()) {
             if (UNLIKELY(Options::useEagerWebAssemblyModuleHashing()))
                 m_info->nameSection->setHash(m_hasher.computeHexDigest());
+
             m_state = State::Finished;
             m_client.didFinishParsing();
         } else
--
2.40.0