diff options
-rw-r--r-- | meta/recipes-core/expat/expat/CVE-2022-25236-1.patch | 116 | ||||
-rw-r--r-- | meta/recipes-core/expat/expat/CVE-2022-25236-2.patch | 232 | ||||
-rw-r--r-- | meta/recipes-core/expat/expat_2.2.10.bb | 2 |
3 files changed, 350 insertions, 0 deletions
diff --git a/meta/recipes-core/expat/expat/CVE-2022-25236-1.patch b/meta/recipes-core/expat/expat/CVE-2022-25236-1.patch new file mode 100644 index 0000000000..ab53d99c8f --- /dev/null +++ b/meta/recipes-core/expat/expat/CVE-2022-25236-1.patch | |||
@@ -0,0 +1,116 @@ | |||
1 | Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/2cc97e87] | ||
2 | CVE: CVE-2022-25236 | ||
3 | |||
4 | The commit is a merge commit, and this patch is created by: | ||
5 | |||
6 | $ git diff -p --stat 2cc97e87~ 2cc97e87 | ||
7 | |||
8 | Remove modification for expat/Changes which fails to be applied. | ||
9 | |||
10 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
11 | |||
12 | commit 2cc97e875ef84da4bcf55156c83599116f7523b4 (from d477fdd284468f2ab822024e75702f2c1b254f42) | ||
13 | Merge: d477fdd2 e4d7e497 | ||
14 | Author: Sebastian Pipping <sebastian@pipping.org> | ||
15 | Date: Fri Feb 18 18:01:27 2022 +0100 | ||
16 | |||
17 | Merge pull request #561 from libexpat/namesep-security | ||
18 | |||
19 | [CVE-2022-25236] lib: Protect against insertion of namesep characters into namespace URIs | ||
20 | |||
21 | --- | ||
22 | expat/Changes | 16 ++++++++++++++++ | ||
23 | expat/lib/xmlparse.c | 17 +++++++++++++---- | ||
24 | expat/tests/runtests.c | 30 ++++++++++++++++++++++++++++++ | ||
25 | 3 files changed, 59 insertions(+), 4 deletions(-) | ||
26 | |||
27 | diff --git a/lib/xmlparse.c b/lib/xmlparse.c | ||
28 | index 7376aab1..c98e2e9f 100644 | ||
29 | --- a/lib/xmlparse.c | ||
30 | +++ b/lib/xmlparse.c | ||
31 | @@ -718,8 +718,7 @@ XML_ParserCreate(const XML_Char *encodingName) { | ||
32 | |||
33 | XML_Parser XMLCALL | ||
34 | XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { | ||
35 | - XML_Char tmp[2]; | ||
36 | - *tmp = nsSep; | ||
37 | + XML_Char tmp[2] = {nsSep, 0}; | ||
38 | return XML_ParserCreate_MM(encodingName, NULL, tmp); | ||
39 | } | ||
40 | |||
41 | @@ -1344,8 +1343,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, | ||
42 | would be otherwise. | ||
43 | */ | ||
44 | if (parser->m_ns) { | ||
45 | - XML_Char tmp[2]; | ||
46 | - *tmp = parser->m_namespaceSeparator; | ||
47 | + XML_Char tmp[2] = {parser->m_namespaceSeparator, 0}; | ||
48 | parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); | ||
49 | } else { | ||
50 | parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); | ||
51 | @@ -3761,6 +3759,17 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, | ||
52 | if (! mustBeXML && isXMLNS | ||
53 | && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) | ||
54 | isXMLNS = XML_FALSE; | ||
55 | + | ||
56 | + // NOTE: While Expat does not validate namespace URIs against RFC 3986, | ||
57 | + // we have to at least make sure that the XML processor on top of | ||
58 | + // Expat (that is splitting tag names by namespace separator into | ||
59 | + // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused | ||
60 | + // by an attacker putting additional namespace separator characters | ||
61 | + // into namespace declarations. That would be ambiguous and not to | ||
62 | + // be expected. | ||
63 | + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { | ||
64 | + return XML_ERROR_SYNTAX; | ||
65 | + } | ||
66 | } | ||
67 | isXML = isXML && len == xmlLen; | ||
68 | isXMLNS = isXMLNS && len == xmlnsLen; | ||
69 | diff --git a/tests/runtests.c b/tests/runtests.c | ||
70 | index d07203f2..bc5344b1 100644 | ||
71 | --- a/tests/runtests.c | ||
72 | +++ b/tests/runtests.c | ||
73 | @@ -7220,6 +7220,35 @@ START_TEST(test_ns_double_colon_doctype) { | ||
74 | } | ||
75 | END_TEST | ||
76 | |||
77 | +START_TEST(test_ns_separator_in_uri) { | ||
78 | + struct test_case { | ||
79 | + enum XML_Status expectedStatus; | ||
80 | + const char *doc; | ||
81 | + }; | ||
82 | + struct test_case cases[] = { | ||
83 | + {XML_STATUS_OK, "<doc xmlns='one_two' />"}, | ||
84 | + {XML_STATUS_ERROR, "<doc xmlns='one
two' />"}, | ||
85 | + }; | ||
86 | + | ||
87 | + size_t i = 0; | ||
88 | + size_t failCount = 0; | ||
89 | + for (; i < sizeof(cases) / sizeof(cases[0]); i++) { | ||
90 | + XML_Parser parser = XML_ParserCreateNS(NULL, '\n'); | ||
91 | + XML_SetElementHandler(parser, dummy_start_element, dummy_end_element); | ||
92 | + if (XML_Parse(parser, cases[i].doc, (int)strlen(cases[i].doc), | ||
93 | + /*isFinal*/ XML_TRUE) | ||
94 | + != cases[i].expectedStatus) { | ||
95 | + failCount++; | ||
96 | + } | ||
97 | + XML_ParserFree(parser); | ||
98 | + } | ||
99 | + | ||
100 | + if (failCount) { | ||
101 | + fail("Namespace separator handling is broken"); | ||
102 | + } | ||
103 | +} | ||
104 | +END_TEST | ||
105 | + | ||
106 | /* Control variable; the number of times duff_allocator() will successfully | ||
107 | * allocate */ | ||
108 | #define ALLOC_ALWAYS_SUCCEED (-1) | ||
109 | @@ -11905,6 +11934,7 @@ make_suite(void) { | ||
110 | tcase_add_test(tc_namespace, test_ns_utf16_doctype); | ||
111 | tcase_add_test(tc_namespace, test_ns_invalid_doctype); | ||
112 | tcase_add_test(tc_namespace, test_ns_double_colon_doctype); | ||
113 | + tcase_add_test(tc_namespace, test_ns_separator_in_uri); | ||
114 | |||
115 | suite_add_tcase(s, tc_misc); | ||
116 | tcase_add_checked_fixture(tc_misc, NULL, basic_teardown); | ||
diff --git a/meta/recipes-core/expat/expat/CVE-2022-25236-2.patch b/meta/recipes-core/expat/expat/CVE-2022-25236-2.patch new file mode 100644 index 0000000000..0f14c9631b --- /dev/null +++ b/meta/recipes-core/expat/expat/CVE-2022-25236-2.patch | |||
@@ -0,0 +1,232 @@ | |||
1 | Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/f178826b] | ||
2 | CVE: CVE-2022-25236 | ||
3 | |||
4 | The commit is a merge commit, and this patch is created by: | ||
5 | |||
6 | $ git show -m -p --stat f178826b | ||
7 | |||
8 | Remove changes for expat/Changes and reference.html which fail to be applied. | ||
9 | |||
10 | Signed-off-by: Kai Kang <kai.kang@windriver.com> | ||
11 | |||
12 | commit f178826bb1e9c8ee23202f1be55ad4ac7b649e84 (from c99e0e7f2b15b48848038992ecbb4480f957cfe9) | ||
13 | Merge: c99e0e7f 9579f7ea | ||
14 | Author: Sebastian Pipping <sebastian@pipping.org> | ||
15 | Date: Fri Mar 4 18:43:39 2022 +0100 | ||
16 | |||
17 | Merge pull request #577 from libexpat/namesep | ||
18 | |||
19 | lib: Relax fix to CVE-2022-25236 with regard to RFC 3986 URI characters (fixes #572) | ||
20 | --- | ||
21 | expat/Changes | 16 ++++++ | ||
22 | expat/doc/reference.html | 8 +++ | ||
23 | expat/lib/expat.h | 11 ++++ | ||
24 | expat/lib/xmlparse.c | 139 ++++++++++++++++++++++++++++++++++++++++++++--- | ||
25 | expat/tests/runtests.c | 8 ++- | ||
26 | 5 files changed, 171 insertions(+), 11 deletions(-) | ||
27 | |||
28 | diff --git a/lib/expat.h b/lib/expat.h | ||
29 | index 5ab493f7..181fc960 100644 | ||
30 | --- a/lib/expat.h | ||
31 | +++ b/lib/expat.h | ||
32 | @@ -239,6 +239,17 @@ XML_ParserCreate(const XML_Char *encoding); | ||
33 | and the local part will be concatenated without any separator. | ||
34 | It is a programming error to use the separator '\0' with namespace | ||
35 | triplets (see XML_SetReturnNSTriplet). | ||
36 | + If a namespace separator is chosen that can be part of a URI or | ||
37 | + part of an XML name, splitting an expanded name back into its | ||
38 | + 1, 2 or 3 original parts on application level in the element handler | ||
39 | + may end up vulnerable, so these are advised against; sane choices for | ||
40 | + a namespace separator are e.g. '\n' (line feed) and '|' (pipe). | ||
41 | + | ||
42 | + Note that Expat does not validate namespace URIs (beyond encoding) | ||
43 | + against RFC 3986 today (and is not required to do so with regard to | ||
44 | + the XML 1.0 namespaces specification) but it may start doing that | ||
45 | + in future releases. Before that, an application using Expat must | ||
46 | + be ready to receive namespace URIs containing non-URI characters. | ||
47 | */ | ||
48 | XMLPARSEAPI(XML_Parser) | ||
49 | XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); | ||
50 | diff --git a/lib/xmlparse.c b/lib/xmlparse.c | ||
51 | index 59da19c8..6fe2cf1e 100644 | ||
52 | --- a/lib/xmlparse.c | ||
53 | +++ b/lib/xmlparse.c | ||
54 | @@ -3705,6 +3705,117 @@ storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, | ||
55 | return XML_ERROR_NONE; | ||
56 | } | ||
57 | |||
58 | +static XML_Bool | ||
59 | +is_rfc3986_uri_char(XML_Char candidate) { | ||
60 | + // For the RFC 3986 ANBF grammar see | ||
61 | + // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A | ||
62 | + | ||
63 | + switch (candidate) { | ||
64 | + // From rule "ALPHA" (uppercase half) | ||
65 | + case 'A': | ||
66 | + case 'B': | ||
67 | + case 'C': | ||
68 | + case 'D': | ||
69 | + case 'E': | ||
70 | + case 'F': | ||
71 | + case 'G': | ||
72 | + case 'H': | ||
73 | + case 'I': | ||
74 | + case 'J': | ||
75 | + case 'K': | ||
76 | + case 'L': | ||
77 | + case 'M': | ||
78 | + case 'N': | ||
79 | + case 'O': | ||
80 | + case 'P': | ||
81 | + case 'Q': | ||
82 | + case 'R': | ||
83 | + case 'S': | ||
84 | + case 'T': | ||
85 | + case 'U': | ||
86 | + case 'V': | ||
87 | + case 'W': | ||
88 | + case 'X': | ||
89 | + case 'Y': | ||
90 | + case 'Z': | ||
91 | + | ||
92 | + // From rule "ALPHA" (lowercase half) | ||
93 | + case 'a': | ||
94 | + case 'b': | ||
95 | + case 'c': | ||
96 | + case 'd': | ||
97 | + case 'e': | ||
98 | + case 'f': | ||
99 | + case 'g': | ||
100 | + case 'h': | ||
101 | + case 'i': | ||
102 | + case 'j': | ||
103 | + case 'k': | ||
104 | + case 'l': | ||
105 | + case 'm': | ||
106 | + case 'n': | ||
107 | + case 'o': | ||
108 | + case 'p': | ||
109 | + case 'q': | ||
110 | + case 'r': | ||
111 | + case 's': | ||
112 | + case 't': | ||
113 | + case 'u': | ||
114 | + case 'v': | ||
115 | + case 'w': | ||
116 | + case 'x': | ||
117 | + case 'y': | ||
118 | + case 'z': | ||
119 | + | ||
120 | + // From rule "DIGIT" | ||
121 | + case '0': | ||
122 | + case '1': | ||
123 | + case '2': | ||
124 | + case '3': | ||
125 | + case '4': | ||
126 | + case '5': | ||
127 | + case '6': | ||
128 | + case '7': | ||
129 | + case '8': | ||
130 | + case '9': | ||
131 | + | ||
132 | + // From rule "pct-encoded" | ||
133 | + case '%': | ||
134 | + | ||
135 | + // From rule "unreserved" | ||
136 | + case '-': | ||
137 | + case '.': | ||
138 | + case '_': | ||
139 | + case '~': | ||
140 | + | ||
141 | + // From rule "gen-delims" | ||
142 | + case ':': | ||
143 | + case '/': | ||
144 | + case '?': | ||
145 | + case '#': | ||
146 | + case '[': | ||
147 | + case ']': | ||
148 | + case '@': | ||
149 | + | ||
150 | + // From rule "sub-delims" | ||
151 | + case '!': | ||
152 | + case '$': | ||
153 | + case '&': | ||
154 | + case '\'': | ||
155 | + case '(': | ||
156 | + case ')': | ||
157 | + case '*': | ||
158 | + case '+': | ||
159 | + case ',': | ||
160 | + case ';': | ||
161 | + case '=': | ||
162 | + return XML_TRUE; | ||
163 | + | ||
164 | + default: | ||
165 | + return XML_FALSE; | ||
166 | + } | ||
167 | +} | ||
168 | + | ||
169 | /* addBinding() overwrites the value of prefix->binding without checking. | ||
170 | Therefore one must keep track of the old value outside of addBinding(). | ||
171 | */ | ||
172 | @@ -3763,14 +3874,26 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, | ||
173 | && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) | ||
174 | isXMLNS = XML_FALSE; | ||
175 | |||
176 | - // NOTE: While Expat does not validate namespace URIs against RFC 3986, | ||
177 | - // we have to at least make sure that the XML processor on top of | ||
178 | - // Expat (that is splitting tag names by namespace separator into | ||
179 | - // 2- or 3-tuples (uri-local or uri-local-prefix)) cannot be confused | ||
180 | - // by an attacker putting additional namespace separator characters | ||
181 | - // into namespace declarations. That would be ambiguous and not to | ||
182 | - // be expected. | ||
183 | - if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)) { | ||
184 | + // NOTE: While Expat does not validate namespace URIs against RFC 3986 | ||
185 | + // today (and is not REQUIRED to do so with regard to the XML 1.0 | ||
186 | + // namespaces specification) we have to at least make sure, that | ||
187 | + // the application on top of Expat (that is likely splitting expanded | ||
188 | + // element names ("qualified names") of form | ||
189 | + // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces | ||
190 | + // in its element handler code) cannot be confused by an attacker | ||
191 | + // putting additional namespace separator characters into namespace | ||
192 | + // declarations. That would be ambiguous and not to be expected. | ||
193 | + // | ||
194 | + // While the HTML API docs of function XML_ParserCreateNS have been | ||
195 | + // advising against use of a namespace separator character that can | ||
196 | + // appear in a URI for >20 years now, some widespread applications | ||
197 | + // are using URI characters (':' (colon) in particular) for a | ||
198 | + // namespace separator, in practice. To keep these applications | ||
199 | + // functional, we only reject namespaces URIs containing the | ||
200 | + // application-chosen namespace separator if the chosen separator | ||
201 | + // is a non-URI character with regard to RFC 3986. | ||
202 | + if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) | ||
203 | + && ! is_rfc3986_uri_char(uri[len])) { | ||
204 | return XML_ERROR_SYNTAX; | ||
205 | } | ||
206 | } | ||
207 | diff --git a/tests/runtests.c b/tests/runtests.c | ||
208 | index 60da868e..712706c4 100644 | ||
209 | --- a/tests/runtests.c | ||
210 | +++ b/tests/runtests.c | ||
211 | @@ -7406,16 +7406,18 @@ START_TEST(test_ns_separator_in_uri) { | ||
212 | struct test_case { | ||
213 | enum XML_Status expectedStatus; | ||
214 | const char *doc; | ||
215 | + XML_Char namesep; | ||
216 | }; | ||
217 | struct test_case cases[] = { | ||
218 | - {XML_STATUS_OK, "<doc xmlns='one_two' />"}, | ||
219 | - {XML_STATUS_ERROR, "<doc xmlns='one
two' />"}, | ||
220 | + {XML_STATUS_OK, "<doc xmlns='one_two' />", XCS('\n')}, | ||
221 | + {XML_STATUS_ERROR, "<doc xmlns='one
two' />", XCS('\n')}, | ||
222 | + {XML_STATUS_OK, "<doc xmlns='one:two' />", XCS(':')}, | ||
223 | }; | ||
224 | |||
225 | size_t i = 0; | ||
226 | size_t failCount = 0; | ||
227 | for (; i < sizeof(cases) / sizeof(cases[0]); i++) { | ||
228 | - XML_Parser parser = XML_ParserCreateNS(NULL, '\n'); | ||
229 | + XML_Parser parser = XML_ParserCreateNS(NULL, cases[i].namesep); | ||
230 | XML_SetElementHandler(parser, dummy_start_element, dummy_end_element); | ||
231 | if (XML_Parse(parser, cases[i].doc, (int)strlen(cases[i].doc), | ||
232 | /*isFinal*/ XML_TRUE) | ||
diff --git a/meta/recipes-core/expat/expat_2.2.10.bb b/meta/recipes-core/expat/expat_2.2.10.bb index 0b3331981c..f99fa7edb6 100644 --- a/meta/recipes-core/expat/expat_2.2.10.bb +++ b/meta/recipes-core/expat/expat_2.2.10.bb | |||
@@ -18,6 +18,8 @@ SRC_URI = "https://github.com/libexpat/libexpat/releases/download/R_${VERSION_TA | |||
18 | file://CVE-2022-23852.patch \ | 18 | file://CVE-2022-23852.patch \ |
19 | file://CVE-2022-23990.patch \ | 19 | file://CVE-2022-23990.patch \ |
20 | file://CVE-2022-25235.patch \ | 20 | file://CVE-2022-25235.patch \ |
21 | file://CVE-2022-25236-1.patch \ | ||
22 | file://CVE-2022-25236-2.patch \ | ||
21 | " | 23 | " |
22 | 24 | ||
23 | UPSTREAM_CHECK_URI = "https://github.com/libexpat/libexpat/releases/" | 25 | UPSTREAM_CHECK_URI = "https://github.com/libexpat/libexpat/releases/" |