summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Kang <kai.kang@windriver.com>2022-03-11 21:58:35 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-03-22 22:18:51 +0000
commitb60e2e5a5d3273b2affcaa7581d8e8530f3e3889 (patch)
treee496bef7e4e4e6e9c356af4070ac9a4ba59ef76a
parent37a86b19585fefbb83bc94572c5742c2a60c4490 (diff)
downloadpoky-b60e2e5a5d3273b2affcaa7581d8e8530f3e3889.tar.gz
expat: fix CVE-2022-25236
Backport patches to fix CVE-2022-25236 for expat. CVE: CVE-2022-25236 (From OE-Core rev: fd0271ee4ff3a45f7c04219fc7571db66fcefb10) Signed-off-by: Kai Kang <kai.kang@windriver.com> Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-core/expat/expat/CVE-2022-25236-1.patch116
-rw-r--r--meta/recipes-core/expat/expat/CVE-2022-25236-2.patch232
-rw-r--r--meta/recipes-core/expat/expat_2.2.10.bb2
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 @@
1Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/2cc97e87]
2CVE: CVE-2022-25236
3
4The commit is a merge commit, and this patch is created by:
5
6$ git diff -p --stat 2cc97e87~ 2cc97e87
7
8Remove modification for expat/Changes which fails to be applied.
9
10Signed-off-by: Kai Kang <kai.kang@windriver.com>
11
12commit 2cc97e875ef84da4bcf55156c83599116f7523b4 (from d477fdd284468f2ab822024e75702f2c1b254f42)
13Merge: d477fdd2 e4d7e497
14Author: Sebastian Pipping <sebastian@pipping.org>
15Date: 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
27diff --git a/lib/xmlparse.c b/lib/xmlparse.c
28index 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;
69diff --git a/tests/runtests.c b/tests/runtests.c
70index 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&#x0A;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 @@
1Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/f178826b]
2CVE: CVE-2022-25236
3
4The commit is a merge commit, and this patch is created by:
5
6$ git show -m -p --stat f178826b
7
8Remove changes for expat/Changes and reference.html which fail to be applied.
9
10Signed-off-by: Kai Kang <kai.kang@windriver.com>
11
12commit f178826bb1e9c8ee23202f1be55ad4ac7b649e84 (from c99e0e7f2b15b48848038992ecbb4480f957cfe9)
13Merge: c99e0e7f 9579f7ea
14Author: Sebastian Pipping <sebastian@pipping.org>
15Date: 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
28diff --git a/lib/expat.h b/lib/expat.h
29index 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);
50diff --git a/lib/xmlparse.c b/lib/xmlparse.c
51index 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 }
207diff --git a/tests/runtests.c b/tests/runtests.c
208index 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&#x0A;two' />"},
220+ {XML_STATUS_OK, "<doc xmlns='one_two' />", XCS('\n')},
221+ {XML_STATUS_ERROR, "<doc xmlns='one&#x0A;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
23UPSTREAM_CHECK_URI = "https://github.com/libexpat/libexpat/releases/" 25UPSTREAM_CHECK_URI = "https://github.com/libexpat/libexpat/releases/"