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/" |
