summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/expat/expat/CVE-2022-25236-2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/expat/expat/CVE-2022-25236-2.patch')
-rw-r--r--meta/recipes-core/expat/expat/CVE-2022-25236-2.patch232
1 files changed, 232 insertions, 0 deletions
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)