diff options
| -rw-r--r-- | meta/recipes-core/expat/expat/CVE-2024-8176-03.patch | 35 | ||||
| -rw-r--r-- | meta/recipes-core/expat/expat/CVE-2024-8176-04.patch | 115 | ||||
| -rw-r--r-- | meta/recipes-core/expat/expat/CVE-2024-8176-05.patch | 78 | ||||
| -rw-r--r-- | meta/recipes-core/expat/expat_2.6.4.bb | 3 | 
4 files changed, 231 insertions, 0 deletions
| diff --git a/meta/recipes-core/expat/expat/CVE-2024-8176-03.patch b/meta/recipes-core/expat/expat/CVE-2024-8176-03.patch new file mode 100644 index 0000000000..c9990d5547 --- /dev/null +++ b/meta/recipes-core/expat/expat/CVE-2024-8176-03.patch | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | From ba80428c2207259103b73871d447dee34755340c Mon Sep 17 00:00:00 2001 | ||
| 2 | From: =?UTF-8?q?Berkay=20Eren=20=C3=9Cr=C3=BCn?= <berkay.ueruen@tum.de> | ||
| 3 | Date: Tue, 23 Sep 2025 11:22:14 +0200 | ||
| 4 | Subject: [PATCH] lib: Fix detection of asynchronous tags in entities | ||
| 5 | |||
| 6 | According to the XML standard, tags must be closed within the same | ||
| 7 | element in which they are opened. Since the change of the entity | ||
| 8 | processing method in version 2.7.0, violations of this rule have not | ||
| 9 | been handled correctly for entities. | ||
| 10 | |||
| 11 | This commit adds the required checks to detect any violations and | ||
| 12 | restores the correct behaviour. | ||
| 13 | |||
| 14 | CVE: CVE-2024-8176 | ||
| 15 | Upstream-Status: Backport [https://github.com/libexpat/libexpat/pull/1059] | ||
| 16 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 17 | --- | ||
| 18 | lib/xmlparse.c | 4 ++++ | ||
| 19 | 1 file changed, 4 insertions(+) | ||
| 20 | |||
| 21 | diff --git a/lib/xmlparse.c b/lib/xmlparse.c | ||
| 22 | index ce29ab6f..ba4e3c48 100644 | ||
| 23 | --- a/lib/xmlparse.c | ||
| 24 | +++ b/lib/xmlparse.c | ||
| 25 | @@ -6087,6 +6087,10 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end, | ||
| 26 | // process its possible inner entities (which are added to the | ||
| 27 | // m_openInternalEntities during doProlog or doContent calls above) | ||
| 28 | entity->hasMore = XML_FALSE; | ||
| 29 | + if (! entity->is_param | ||
| 30 | + && (openEntity->startTagLevel != parser->m_tagLevel)) { | ||
| 31 | + return XML_ERROR_ASYNC_ENTITY; | ||
| 32 | + } | ||
| 33 | triggerReenter(parser); | ||
| 34 | return result; | ||
| 35 | } // End of entity processing, "if" block will return here | ||
| diff --git a/meta/recipes-core/expat/expat/CVE-2024-8176-04.patch b/meta/recipes-core/expat/expat/CVE-2024-8176-04.patch new file mode 100644 index 0000000000..9623467698 --- /dev/null +++ b/meta/recipes-core/expat/expat/CVE-2024-8176-04.patch | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | From 81a114f7eebcd41a6993337128cda337986a26f4 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sebastian Pipping <sebastian@pipping.org> | ||
| 3 | Date: Mon, 15 Sep 2025 21:57:07 +0200 | ||
| 4 | Subject: [PATCH] tests: Cover XML_ERROR_ASYNC_ENTITY cases | ||
| 5 | |||
| 6 | CVE: CVE-2024-8176 | ||
| 7 | Upstream-Status: Backport [https://github.com/libexpat/libexpat/pull/1059] | ||
| 8 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 9 | --- | ||
| 10 | tests/misc_tests.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++ | ||
| 11 | 1 file changed, 87 insertions(+) | ||
| 12 | |||
| 13 | diff --git a/tests/misc_tests.c b/tests/misc_tests.c | ||
| 14 | index 3346bce6..19f41df7 100644 | ||
| 15 | --- a/tests/misc_tests.c | ||
| 16 | +++ b/tests/misc_tests.c | ||
| 17 | @@ -621,6 +621,91 @@ START_TEST(test_misc_expected_event_ptr_issue_980) { | ||
| 18 | } | ||
| 19 | END_TEST | ||
| 20 | |||
| 21 | +START_TEST(test_misc_sync_entity_tolerated) { | ||
| 22 | + const char *const doc = "<!DOCTYPE t0 [\n" | ||
| 23 | + " <!ENTITY a '<t1></t1>'>\n" | ||
| 24 | + " <!ENTITY b '<t2>two</t2>'>\n" | ||
| 25 | + " <!ENTITY c '<t3>three<t4>four</t4>three</t3>'>\n" | ||
| 26 | + " <!ENTITY d '<t5>&b;</t5>'>\n" | ||
| 27 | + "]>\n" | ||
| 28 | + "<t0>&a;&b;&c;&d;</t0>\n"; | ||
| 29 | + XML_Parser parser = XML_ParserCreate(NULL); | ||
| 30 | + | ||
| 31 | + assert_true(_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), | ||
| 32 | + /*isFinal=*/XML_TRUE) | ||
| 33 | + == XML_STATUS_OK); | ||
| 34 | + | ||
| 35 | + XML_ParserFree(parser); | ||
| 36 | +} | ||
| 37 | +END_TEST | ||
| 38 | + | ||
| 39 | +START_TEST(test_misc_async_entity_rejected) { | ||
| 40 | + struct test_case { | ||
| 41 | + const char *doc; | ||
| 42 | + enum XML_Status expectedStatusNoGE; | ||
| 43 | + enum XML_Error expectedErrorNoGE; | ||
| 44 | + }; | ||
| 45 | + const struct test_case cases[] = { | ||
| 46 | + // Opened by one entity, closed by another | ||
| 47 | + {"<!DOCTYPE t0 [\n" | ||
| 48 | + " <!ENTITY open '<t1>'>\n" | ||
| 49 | + " <!ENTITY close '</t1>'>\n" | ||
| 50 | + "]>\n" | ||
| 51 | + "<t0>&open;&close;</t0>\n", | ||
| 52 | + XML_STATUS_OK, XML_ERROR_NONE}, | ||
| 53 | + // Opened by tag, closed by entity (non-root case) | ||
| 54 | + {"<!DOCTYPE t0 [\n" | ||
| 55 | + " <!ENTITY g0 ''>\n" | ||
| 56 | + " <!ENTITY g1 '&g0;</t1>'>\n" | ||
| 57 | + "]>\n" | ||
| 58 | + "<t0><t1>&g1;</t0>\n", | ||
| 59 | + XML_STATUS_ERROR, XML_ERROR_TAG_MISMATCH}, | ||
| 60 | + // Opened by tag, closed by entity (root case) | ||
| 61 | + {"<!DOCTYPE t0 [\n" | ||
| 62 | + " <!ENTITY g0 ''>\n" | ||
| 63 | + " <!ENTITY g1 '&g0;</t0>'>\n" | ||
| 64 | + "]>\n" | ||
| 65 | + "<t0>&g1;\n", | ||
| 66 | + XML_STATUS_ERROR, XML_ERROR_NO_ELEMENTS}, | ||
| 67 | + // Opened by entity, closed by tag <-- regression from 2.7.0 | ||
| 68 | + {"<!DOCTYPE t0 [\n" | ||
| 69 | + " <!ENTITY g0 ''>\n" | ||
| 70 | + " <!ENTITY g1 '<t1>&g0;'>\n" | ||
| 71 | + "]>\n" | ||
| 72 | + "<t0>&g1;</t1></t0>\n", | ||
| 73 | + XML_STATUS_ERROR, XML_ERROR_TAG_MISMATCH}, | ||
| 74 | + // Opened by tag, closed by entity; then the other way around | ||
| 75 | + {"<!DOCTYPE t0 [\n" | ||
| 76 | + " <!ENTITY open '<t1>'>\n" | ||
| 77 | + " <!ENTITY close '</t1>'>\n" | ||
| 78 | + "]>\n" | ||
| 79 | + "<t0><t1>&close;&open;</t1></t0>\n", | ||
| 80 | + XML_STATUS_OK, XML_ERROR_NONE}, | ||
| 81 | + }; | ||
| 82 | + | ||
| 83 | + for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { | ||
| 84 | + const struct test_case testCase = cases[i]; | ||
| 85 | + set_subtest("cases[%d]", (int)i); | ||
| 86 | + | ||
| 87 | + const char *const doc = testCase.doc; | ||
| 88 | +#if XML_GE == 1 | ||
| 89 | + const enum XML_Status expectedStatus = XML_STATUS_ERROR; | ||
| 90 | + const enum XML_Error expectedError = XML_ERROR_ASYNC_ENTITY; | ||
| 91 | +#else | ||
| 92 | + const enum XML_Status expectedStatus = testCase.expectedStatusNoGE; | ||
| 93 | + const enum XML_Error expectedError = testCase.expectedErrorNoGE; | ||
| 94 | +#endif | ||
| 95 | + | ||
| 96 | + XML_Parser parser = XML_ParserCreate(NULL); | ||
| 97 | + assert_true(_XML_Parse_SINGLE_BYTES(parser, doc, (int)strlen(doc), | ||
| 98 | + /*isFinal=*/XML_TRUE) | ||
| 99 | + == expectedStatus); | ||
| 100 | + assert_true(XML_GetErrorCode(parser) == expectedError); | ||
| 101 | + XML_ParserFree(parser); | ||
| 102 | + } | ||
| 103 | +} | ||
| 104 | +END_TEST | ||
| 105 | + | ||
| 106 | void | ||
| 107 | make_miscellaneous_test_case(Suite *s) { | ||
| 108 | TCase *tc_misc = tcase_create("miscellaneous tests"); | ||
| 109 | @@ -649,4 +734,6 @@ make_miscellaneous_test_case(Suite *s) { | ||
| 110 | tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser); | ||
| 111 | tcase_add_test__if_xml_ge(tc_misc, test_renter_loop_finite_content); | ||
| 112 | tcase_add_test(tc_misc, test_misc_expected_event_ptr_issue_980); | ||
| 113 | + tcase_add_test(tc_misc, test_misc_sync_entity_tolerated); | ||
| 114 | + tcase_add_test(tc_misc, test_misc_async_entity_rejected); | ||
| 115 | } | ||
| diff --git a/meta/recipes-core/expat/expat/CVE-2024-8176-05.patch b/meta/recipes-core/expat/expat/CVE-2024-8176-05.patch new file mode 100644 index 0000000000..063a590a11 --- /dev/null +++ b/meta/recipes-core/expat/expat/CVE-2024-8176-05.patch | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | From a9aaf85cfc3025b7013b5adc4bef2ce32ecc7fb1 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: =?UTF-8?q?Berkay=20Eren=20=C3=9Cr=C3=BCn?= <berkay.ueruen@tum.de> | ||
| 3 | Date: Tue, 23 Sep 2025 12:12:50 +0200 | ||
| 4 | Subject: [PATCH] tests: Add line/column checks to async entity tests | ||
| 5 | |||
| 6 | CVE: CVE-2024-8176 | ||
| 7 | Upstream-Status: Backport [https://github.com/libexpat/libexpat/pull/1059] | ||
| 8 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 9 | --- | ||
| 10 | tests/misc_tests.c | 17 ++++++++++++----- | ||
| 11 | 1 file changed, 12 insertions(+), 5 deletions(-) | ||
| 12 | |||
| 13 | diff --git a/tests/misc_tests.c b/tests/misc_tests.c | ||
| 14 | index 19f41df7..7a4d2455 100644 | ||
| 15 | --- a/tests/misc_tests.c | ||
| 16 | +++ b/tests/misc_tests.c | ||
| 17 | @@ -644,6 +644,8 @@ START_TEST(test_misc_async_entity_rejected) { | ||
| 18 | const char *doc; | ||
| 19 | enum XML_Status expectedStatusNoGE; | ||
| 20 | enum XML_Error expectedErrorNoGE; | ||
| 21 | + XML_Size expectedErrorLine; | ||
| 22 | + XML_Size expectedErrorColumn; | ||
| 23 | }; | ||
| 24 | const struct test_case cases[] = { | ||
| 25 | // Opened by one entity, closed by another | ||
| 26 | @@ -652,35 +654,35 @@ START_TEST(test_misc_async_entity_rejected) { | ||
| 27 | " <!ENTITY close '</t1>'>\n" | ||
| 28 | "]>\n" | ||
| 29 | "<t0>&open;&close;</t0>\n", | ||
| 30 | - XML_STATUS_OK, XML_ERROR_NONE}, | ||
| 31 | + XML_STATUS_OK, XML_ERROR_NONE, 5, 4}, | ||
| 32 | // Opened by tag, closed by entity (non-root case) | ||
| 33 | {"<!DOCTYPE t0 [\n" | ||
| 34 | " <!ENTITY g0 ''>\n" | ||
| 35 | " <!ENTITY g1 '&g0;</t1>'>\n" | ||
| 36 | "]>\n" | ||
| 37 | "<t0><t1>&g1;</t0>\n", | ||
| 38 | - XML_STATUS_ERROR, XML_ERROR_TAG_MISMATCH}, | ||
| 39 | + XML_STATUS_ERROR, XML_ERROR_TAG_MISMATCH, 5, 8}, | ||
| 40 | // Opened by tag, closed by entity (root case) | ||
| 41 | {"<!DOCTYPE t0 [\n" | ||
| 42 | " <!ENTITY g0 ''>\n" | ||
| 43 | " <!ENTITY g1 '&g0;</t0>'>\n" | ||
| 44 | "]>\n" | ||
| 45 | "<t0>&g1;\n", | ||
| 46 | - XML_STATUS_ERROR, XML_ERROR_NO_ELEMENTS}, | ||
| 47 | + XML_STATUS_ERROR, XML_ERROR_NO_ELEMENTS, 5, 4}, | ||
| 48 | // Opened by entity, closed by tag <-- regression from 2.7.0 | ||
| 49 | {"<!DOCTYPE t0 [\n" | ||
| 50 | " <!ENTITY g0 ''>\n" | ||
| 51 | " <!ENTITY g1 '<t1>&g0;'>\n" | ||
| 52 | "]>\n" | ||
| 53 | "<t0>&g1;</t1></t0>\n", | ||
| 54 | - XML_STATUS_ERROR, XML_ERROR_TAG_MISMATCH}, | ||
| 55 | + XML_STATUS_ERROR, XML_ERROR_TAG_MISMATCH, 5, 4}, | ||
| 56 | // Opened by tag, closed by entity; then the other way around | ||
| 57 | {"<!DOCTYPE t0 [\n" | ||
| 58 | " <!ENTITY open '<t1>'>\n" | ||
| 59 | " <!ENTITY close '</t1>'>\n" | ||
| 60 | "]>\n" | ||
| 61 | "<t0><t1>&close;&open;</t1></t0>\n", | ||
| 62 | - XML_STATUS_OK, XML_ERROR_NONE}, | ||
| 63 | + XML_STATUS_OK, XML_ERROR_NONE, 5, 8}, | ||
| 64 | }; | ||
| 65 | |||
| 66 | for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { | ||
| 67 | @@ -701,6 +703,11 @@ START_TEST(test_misc_async_entity_rejected) { | ||
| 68 | /*isFinal=*/XML_TRUE) | ||
| 69 | == expectedStatus); | ||
| 70 | assert_true(XML_GetErrorCode(parser) == expectedError); | ||
| 71 | +#if XML_GE == 1 | ||
| 72 | + assert_true(XML_GetCurrentLineNumber(parser) == testCase.expectedErrorLine); | ||
| 73 | + assert_true(XML_GetCurrentColumnNumber(parser) | ||
| 74 | + == testCase.expectedErrorColumn); | ||
| 75 | +#endif | ||
| 76 | XML_ParserFree(parser); | ||
| 77 | } | ||
| 78 | } | ||
| diff --git a/meta/recipes-core/expat/expat_2.6.4.bb b/meta/recipes-core/expat/expat_2.6.4.bb index ab0b1d54c1..816beaa8a3 100644 --- a/meta/recipes-core/expat/expat_2.6.4.bb +++ b/meta/recipes-core/expat/expat_2.6.4.bb | |||
| @@ -13,6 +13,9 @@ SRC_URI = "${GITHUB_BASE_URI}/download/R_${VERSION_TAG}/expat-${PV}.tar.bz2 \ | |||
| 13 | file://0001-tests-Cover-indirect-entity-recursion.patch;striplevel=2 \ | 13 | file://0001-tests-Cover-indirect-entity-recursion.patch;striplevel=2 \ | 
| 14 | file://CVE-2024-8176-01.patch;striplevel=2 \ | 14 | file://CVE-2024-8176-01.patch;striplevel=2 \ | 
| 15 | file://CVE-2024-8176-02.patch;striplevel=2 \ | 15 | file://CVE-2024-8176-02.patch;striplevel=2 \ | 
| 16 | file://CVE-2024-8176-03.patch \ | ||
| 17 | file://CVE-2024-8176-04.patch \ | ||
| 18 | file://CVE-2024-8176-05.patch \ | ||
| 16 | " | 19 | " | 
| 17 | 20 | ||
| 18 | GITHUB_BASE_URI = "https://github.com/libexpat/libexpat/releases/" | 21 | GITHUB_BASE_URI = "https://github.com/libexpat/libexpat/releases/" | 
