From c91cfb24fba741254d7b044d83fa5200d50662b3 Mon Sep 17 00:00:00 2001 From: Funda Wang Date: Wed, 30 Oct 2024 00:23:16 +0800 Subject: [PATCH] fix CVE-2024-50602 --- backport-CVE-2024-50602.patch | 161 ++++++++++++++++++++++++++++++++++ expat.spec | 8 +- 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 backport-CVE-2024-50602.patch diff --git a/backport-CVE-2024-50602.patch b/backport-CVE-2024-50602.patch new file mode 100644 index 0000000..cd564ba --- /dev/null +++ b/backport-CVE-2024-50602.patch @@ -0,0 +1,161 @@ +From 51c7019069b862e88d94ed228659e70bddd5de09 Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Mon, 21 Oct 2024 01:42:54 +0200 +Subject: [PATCH 1/3] lib: Make XML_StopParser refuse to stop/suspend an + unstarted parser + +--- + expat/lib/expat.h | 4 +++- + expat/lib/xmlparse.c | 6 ++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/expat/lib/expat.h b/expat/lib/expat.h +index d0d6015a6..3ba613042 100644 +--- a/expat/lib/expat.h ++++ b/expat/lib/expat.h +@@ -130,7 +130,9 @@ enum XML_Error { + /* Added in 2.3.0. */ + XML_ERROR_NO_BUFFER, + /* Added in 2.4.0. */ +- XML_ERROR_AMPLIFICATION_LIMIT_BREACH ++ XML_ERROR_AMPLIFICATION_LIMIT_BREACH, ++ /* Added in 2.6.4. */ ++ XML_ERROR_NOT_STARTED, + }; + + enum XML_Content_Type { +diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c +index d9285b213..fa02537f8 100644 +--- a/expat/lib/xmlparse.c ++++ b/expat/lib/xmlparse.c +@@ -2234,6 +2234,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { + if (parser == NULL) + return XML_STATUS_ERROR; + switch (parser->m_parsingStatus.parsing) { ++ case XML_INITIALIZED: ++ parser->m_errorCode = XML_ERROR_NOT_STARTED; ++ return XML_STATUS_ERROR; + case XML_SUSPENDED: + if (resumable) { + parser->m_errorCode = XML_ERROR_SUSPENDED; +@@ -2519,6 +2522,9 @@ XML_ErrorString(enum XML_Error code) { + case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: + return XML_L( + "limit on input amplification factor (from DTD and entities) breached"); ++ /* Added in 2.6.4. */ ++ case XML_ERROR_NOT_STARTED: ++ return XML_L("parser not started"); + } + return NULL; + } + +From 5fb89e7b3afa1c314b34834fe729cd063f65a4d4 Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Mon, 21 Oct 2024 01:46:11 +0200 +Subject: [PATCH 2/3] lib: Be explicit about XML_PARSING in XML_StopParser + +--- + expat/lib/xmlparse.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c +index fa02537f8..983f6df03 100644 +--- a/expat/lib/xmlparse.c ++++ b/expat/lib/xmlparse.c +@@ -2247,7 +2247,7 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { + case XML_FINISHED: + parser->m_errorCode = XML_ERROR_FINISHED; + return XML_STATUS_ERROR; +- default: ++ case XML_PARSING: + if (resumable) { + #ifdef XML_DTD + if (parser->m_isParamEntity) { +@@ -2258,6 +2258,9 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { + parser->m_parsingStatus.parsing = XML_SUSPENDED; + } else + parser->m_parsingStatus.parsing = XML_FINISHED; ++ break; ++ default: ++ assert(0); + } + return XML_STATUS_OK; + } + +From b3836ff534c7cc78128fe7b935aad3d4353814ed Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Sun, 20 Oct 2024 23:24:27 +0200 +Subject: [PATCH 3/3] tests: Cover XML_StopParser's new handling of status + XML_INITIALIZED + +Prior to the fix to XML_StopParser, test test_misc_resumeparser_not_crashing +would crash with a NULL pointer dereference in function normal_updatePosition. +This was the AddressSanitizer output: + +> AddressSanitizer:DEADLYSIGNAL +> ================================================================= +> ==19700==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5623e07ad85f bp 0x7ffcf40da650 sp 0x7ffcf40da590 T0) +> ==19700==The signal is caused by a READ memory access. +> ==19700==Hint: address points to the zero page. +> #0 0x5623e07ad85f in normal_updatePosition [..]/lib/xmltok_impl.c:1781:13 +> #1 0x5623e07a52ff in initUpdatePosition [..]/lib/xmltok.c:1031:3 +> #2 0x5623e0762760 in XML_ResumeParser [..]/lib/xmlparse.c:2297:3 +> #3 0x5623e074f7c1 in test_misc_resumeparser_not_crashing() misc_tests_cxx.cpp +> #4 0x5623e074e228 in srunner_run_all ([..]/build_asan_fuzzers/tests/runtests_cxx+0x136228) +> #5 0x5623e0753d2d in main ([..]/build_asan_fuzzers/tests/runtests_cxx+0x13bd2d) +> #6 0x7f802a39af79 (/lib64/libc.so.6+0x25f79) +> #7 0x7f802a39b034 in __libc_start_main (/lib64/libc.so.6+0x26034) +> #8 0x5623e064f340 in _start ([..]/build_asan_fuzzers/tests/runtests_cxx+0x37340) +> +> AddressSanitizer can not provide additional info. +> SUMMARY: AddressSanitizer: SEGV [..]/lib/xmltok_impl.c:1781:13 in normal_updatePosition +> ==19700==ABORTING + +And this the UndefinedBehaviorSanitizer output: + +> [..]/lib/xmltok_impl.c:1781:13: runtime error: load of null pointer of type 'const char' +> SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior [..]/lib/xmltok_impl.c:1781:13 in +--- + expat/tests/misc_tests.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/expat/tests/misc_tests.c b/expat/tests/misc_tests.c +index bf2983b4b..46e0354c1 100644 +--- a/expat/tests/misc_tests.c ++++ b/expat/tests/misc_tests.c +@@ -496,6 +496,28 @@ START_TEST(test_misc_char_handler_stop_without_leak) { + } + END_TEST + ++START_TEST(test_misc_resumeparser_not_crashing) { ++ XML_Parser parser = XML_ParserCreate(NULL); ++ XML_GetBuffer(parser, 1); ++ XML_StopParser(parser, /*resumable=*/XML_TRUE); ++ XML_ResumeParser(parser); // could crash here, previously ++ XML_ParserFree(parser); ++} ++END_TEST ++ ++START_TEST(test_misc_stopparser_rejects_unstarted_parser) { ++ const XML_Bool cases[] = {XML_TRUE, XML_FALSE}; ++ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { ++ const XML_Bool resumable = cases[i]; ++ XML_Parser parser = XML_ParserCreate(NULL); ++ assert_true(XML_GetErrorCode(parser) == XML_ERROR_NONE); ++ assert_true(XML_StopParser(parser, resumable) == XML_STATUS_ERROR); ++ assert_true(XML_GetErrorCode(parser) == XML_ERROR_NOT_STARTED); ++ XML_ParserFree(parser); ++ } ++} ++END_TEST ++ + void + make_miscellaneous_test_case(Suite *s) { + TCase *tc_misc = tcase_create("miscellaneous tests"); +@@ -520,4 +542,6 @@ make_miscellaneous_test_case(Suite *s) { + test_misc_create_external_entity_parser_with_null_context); + tcase_add_test(tc_misc, test_misc_general_entities_support); + tcase_add_test(tc_misc, test_misc_char_handler_stop_without_leak); ++ tcase_add_test(tc_misc, test_misc_resumeparser_not_crashing); ++ tcase_add_test(tc_misc, test_misc_stopparser_rejects_unstarted_parser); + } diff --git a/expat.spec b/expat.spec index 6ebbc08..c31dbda 100644 --- a/expat.spec +++ b/expat.spec @@ -1,11 +1,12 @@ %define Rversion %(echo %{version} | sed -e 's/\\./_/g' -e 's/^/R_/') Name: expat Version: 2.6.3 -Release: 1 +Release: 2 Summary: An XML parser library License: MIT URL: https://libexpat.github.io/ Source0: https://github.com/libexpat/libexpat/releases/download/%{Rversion}/expat-%{version}.tar.xz +Patch0: backport-CVE-2024-50602.patch BuildRequires: sed,autoconf,automake,gcc-c++,libtool,xmlto,make BuildRequires: cmake-rpm-macros @@ -27,7 +28,7 @@ This package provides with static libraries and header files for developing wit %package_help %prep -%autosetup -p1 +%autosetup -p2 %build export CFLAGS="$RPM_OPT_FLAGS -fPIC" @@ -62,6 +63,9 @@ rm -fv %{buildroot}%{_datadir}/doc/%{name}/changelog %{_mandir}/man1/* %changelog +* Wed Oct 30 2024 Funda Wang - 2.6.3-2 +- fix CVE-2024-50602 + * Wed Sep 04 2024 Funda Wang - 2.6.3-1 - update to 2.6.3 -- Gitee