From 4a32da87e931ba54393d465bb77c40b5c33d343b Mon Sep 17 00:00:00 2001 From: Rhodri James 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. Upstream-Status: Backport [https://github.com/libexpat/libexpat/commit/4a32da87e931ba54393d465bb77c40b5c33d343b] CVE: CVE-2022-40674 Signed-off-by: Virendra Thakur --- expat/lib/xmlparse.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) Index: expat/lib/xmlparse.c =================================================================== --- a/lib/xmlparse.c +++ b/lib/xmlparse.c @@ -5657,10 +5657,15 @@ internalEntityProcessor(XML_Parser parse { parser->m_processor = contentProcessor; /* see externalEntityContentProcessor vs contentProcessor */ - return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, - s, end, nextPtr, - (XML_Bool)! parser->m_parsingStatus.finalBuffer, - XML_ACCOUNT_DIRECT); + result = doContent(parser, parser->m_parentParser ? 1 : 0, + parser->m_encoding, s, end, nextPtr, + (XML_Bool)! parser->m_parsingStatus.finalBuffer, + XML_ACCOUNT_DIRECT); + if (result == XML_ERROR_NONE) { + if (! storeRawNames(parser)) + return XML_ERROR_NO_MEMORY; + } + return result; } }