Skip to content

Commit

Permalink
expat: fix CVE-2022-40674
Browse files Browse the repository at this point in the history
Change-Id: I0a2813acce86f0190f723d9df88fb5d22986d81c
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/17899
Tested-by: gerrit-photon <[email protected]>
Reviewed-by: Tapas Kundu <[email protected]>
  • Loading branch information
HarinadhD authored and tapakund committed Sep 21, 2022
1 parent fdd7f62 commit 0ecbf8c
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 1 deletion.
136 changes: 136 additions & 0 deletions SPECS/expat/expat-CVE-2022-40674.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
From 4a32da87e931ba54393d465bb77c40b5c33d343b Mon Sep 17 00:00:00 2001
From: Rhodri James <[email protected]>
Date: Wed, 17 Aug 2022 18:26:18 +0100
Subject: [PATCH] Ensure raw tagnames are safe exiting internalEntityParser

It is possible to concoct a situation in which parsing is
suspended while substituting in an internal entity, so that
XML_ResumeParser directly uses internalEntityProcessor as
its processor. If the subsequent parse includes some unclosed
tags, this will return without calling storeRawNames to ensure
that the raw versions of the tag names are stored in memory other
than the parse buffer itself. If the parse buffer is then changed
or reallocated (for example if processing a file line by line),
badness will ensue.

This patch ensures storeRawNames is always called when needed
after calling doContent. The earlier call do doContent does
not need the same protection; it only deals with entity
substitution, which cannot leave unbalanced tags, and in any
case the raw names will be pointing into the stored entity
value not the parse buffer.
---
expat/lib/xmlparse.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/lib/xmlparse.c b/lib/xmlparse.c
index 3aaf35b..244c1ee 100644
--- a/lib/xmlparse.c
+++ b/lib/xmlparse.c
@@ -5258,9 +5258,14 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
{
parser->m_processor = contentProcessor;
/* see externalEntityContentProcessor vs contentProcessor */
- return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
+ result = doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
s, end, nextPtr,
(XML_Bool)! parser->m_parsingStatus.finalBuffer);
+ if (result == XML_ERROR_NONE) {
+ if (! storeRawNames(parser))
+ return XML_ERROR_NO_MEMORY;
+ }
+ return result;
}
}

diff --git a/tests/runtests.c b/tests/runtests.c
index b7411e9..bee898f 100644
--- a/tests/runtests.c
+++ b/tests/runtests.c
@@ -4890,6 +4890,78 @@ START_TEST(test_suspend_resume_internal_entity) {
}
END_TEST

+void
+suspending_comment_handler(void *userData, const XML_Char *data) {
+ UNUSED_P(data);
+ XML_Parser parser = (XML_Parser)userData;
+ XML_StopParser(parser, XML_TRUE);
+}
+
+START_TEST(test_suspend_resume_internal_entity_issue_629) {
+ const char *const text
+ = "<!DOCTYPE a [<!ENTITY e '<!--COMMENT-->a'>]><a>&e;<b>\n"
+ "<"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "/>"
+ "</b></a>";
+ const size_t firstChunkSizeBytes = 54;
+
+ XML_Parser parser = XML_ParserCreate(NULL);
+ XML_SetUserData(parser, parser);
+ XML_SetCommentHandler(parser, suspending_comment_handler);
+
+ if (XML_Parse(parser, text, (int)firstChunkSizeBytes, XML_FALSE)
+ != XML_STATUS_SUSPENDED)
+ xml_failure(parser);
+ if (XML_ResumeParser(parser) != XML_STATUS_OK)
+ xml_failure(parser);
+ if (XML_Parse(parser, text + firstChunkSizeBytes,
+ (int)(strlen(text) - firstChunkSizeBytes), XML_TRUE)
+ != XML_STATUS_OK)
+ xml_failure(parser);
+ XML_ParserFree(parser);
+}
+END_TEST
+
/* Test syntax error is caught at parse resumption */
START_TEST(test_resume_entity_with_syntax_error) {
const char *text = "<!DOCTYPE doc [\n"
@@ -11209,6 +11281,7 @@ make_suite(void) {
suite_add_tcase(s, tc_basic);
tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
tcase_add_test(tc_basic, test_nul_byte);
+ tcase_add_test__ifdef_xml_dtd(tc_basic,test_suspend_resume_internal_entity_issue_629);
tcase_add_test(tc_basic, test_u0000_char);
tcase_add_test(tc_basic, test_siphash_self);
tcase_add_test(tc_basic, test_siphash_spec);
6 changes: 5 additions & 1 deletion SPECS/expat/expat.spec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Summary: An XML parser library
Name: expat
Version: 2.2.9
Release: 8%{?dist}
Release: 9%{?dist}
License: MIT
URL: http://expat.sourceforge.net/
Group: System Environment/GeneralLibraries
Expand All @@ -17,6 +17,7 @@ Patch3: CVE-2022-23990.patch
Patch4: CVE-2022-25235_25236.patch
Patch5: CVE-2022-25314_25315.patch
Patch6: CVE-2022-25313.patch
Patch7: expat-CVE-2022-40674.patch

Requires: expat-libs = %{version}-%{release}
%description
Expand Down Expand Up @@ -44,6 +45,7 @@ This package contains minimal set of shared expat libraries.
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1

%build
sh ./configure \
Expand Down Expand Up @@ -90,6 +92,8 @@ rm -rf %{buildroot}/*
%{_libdir}/libexpat.so.*

%changelog
* Mon Sep 19 2022 Harinadh D <[email protected]> 2.2.9-9
- Fix CVE-2022-40674
* Fri Mar 04 2022 Tapas Kundu <[email protected]> 2.2.9-8
- Fix CVE-2022-25313
* Mon Feb 28 2022 Tapas Kundu <[email protected]> 2.2.9-7
Expand Down

0 comments on commit 0ecbf8c

Please sign in to comment.