From fc07871ed8c5a4f9928b81cb3dad940847cdefc0 Mon Sep 17 00:00:00 2001 From: hua_yadong Date: Fri, 24 Nov 2023 17:59:27 +0800 Subject: [PATCH] qt-CVE-2023-38197 (cherry picked from commit 082dd3331b40b7b62d23171f287ead523a250c6c) --- qt-CVE-2023-38197.patch | 227 ++++++++++++++++++++++++++++++++++++++++ qt.spec | 9 +- 2 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 qt-CVE-2023-38197.patch diff --git a/qt-CVE-2023-38197.patch b/qt-CVE-2023-38197.patch new file mode 100644 index 0000000..9b10cb5 --- /dev/null +++ b/qt-CVE-2023-38197.patch @@ -0,0 +1,227 @@ +From 2584638ae4a7824e988c68a8386a448460d82cdc Mon Sep 17 00:00:00 2001 +From: hua_yadong +Date: Fri, 24 Nov 2023 17:56:39 +0800 +Subject: [PATCH] qt-CVE-2023-38197 + +--- + src/corelib/xml/qxmlstream.cpp | 139 +++++++++++++++++++++++++++++++-- + src/corelib/xml/qxmlstream_p.h | 11 +++ + 2 files changed, 142 insertions(+), 8 deletions(-) + +diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp +index 919802f1..5ade4cf2 100644 +--- a/src/corelib/xml/qxmlstream.cpp ++++ b/src/corelib/xml/qxmlstream.cpp +@@ -162,7 +162,7 @@ QT_BEGIN_NAMESPACE + addData() or by waiting for it to arrive on the device(). + + \value UnexpectedElementError The parser encountered an element +- that was different to those it expected. ++ or token that was different to those it expected. + + */ + +@@ -296,13 +296,34 @@ QXmlStreamEntityResolver *QXmlStreamReader::entityResolver() const + + QXmlStreamReader is a well-formed XML 1.0 parser that does \e not + include external parsed entities. As long as no error occurs, the +- application code can thus be assured that the data provided by the +- stream reader satisfies the W3C's criteria for well-formed XML. For +- example, you can be certain that all tags are indeed nested and +- closed properly, that references to internal entities have been +- replaced with the correct replacement text, and that attributes have +- been normalized or added according to the internal subset of the +- DTD. ++ application code can thus be assured, that ++ \list ++ \li the data provided by the stream reader satisfies the W3C's ++ criteria for well-formed XML, ++ \li tokens are provided in a valid order. ++ \endlist ++ ++ Unless QXmlStreamReader raises an error, it guarantees the following: ++ \list ++ \li All tags are nested and closed properly. ++ \li References to internal entities have been replaced with the ++ correct replacement text. ++ \li Attributes have been normalized or added according to the ++ internal subset of the \l DTD. ++ \li Tokens of type \l StartDocument happen before all others, ++ aside from comments and processing instructions. ++ \li At most one DOCTYPE element (a token of type \l DTD) is present. ++ \li If present, the DOCTYPE appears before all other elements, ++ aside from StartDocument, comments and processing instructions. ++ \endlist ++ ++ In particular, once any token of type \l StartElement, \l EndElement, ++ \l Characters, \l EntityReference or \l EndDocument is seen, no ++ tokens of type StartDocument or DTD will be seen. If one is present in ++ the input stream, out of order, an error is raised. ++ ++ \note The token types \l Comment and \l ProcessingInstruction may appear ++ anywhere in the stream. + + If an error occurs while parsing, atEnd() and hasError() return + true, and error() returns the error that occurred. The functions +@@ -616,6 +637,7 @@ QXmlStreamReader::TokenType QXmlStreamReader::readNext() + d->token = -1; + return readNext(); + } ++ d->checkToken(); + return d->type; + } + +@@ -740,6 +762,9 @@ static const short QXmlStreamReader_tokenTypeString_indices[] = { + 0, 8, 16, 30, 42, 55, 66, 77, 85, 89, 105, 0 + }; + ++static const char QXmlStreamReader_XmlContextString[] = ++ "Prolog\0" ++ "Body\0"; + + /*! + \property QXmlStreamReader::namespaceProcessing +@@ -776,6 +801,16 @@ QString QXmlStreamReader::tokenString() const + QXmlStreamReader_tokenTypeString_indices[d->type]); + } + ++/*! ++ \internal ++ \return \param loc (Prolog/Body) as a string. ++ */ ++static const QLatin1String contextString(int ctxt) ++{ ++ return QLatin1String(QXmlStreamReader_XmlContextString + ++ QXmlStreamReader_XmlContextString[ctxt]); ++} ++ + #endif // QT_NO_XMLSTREAMREADER + + QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack() +@@ -860,6 +895,8 @@ void QXmlStreamReaderPrivate::init() + + type = QXmlStreamReader::NoToken; + error = QXmlStreamReader::NoError; ++ currentContext = QXmlStreamReaderPrivate::Prolog; ++ foundDTD = false; + } + + /* +@@ -3940,6 +3977,92 @@ void QXmlStreamWriter::writeCurrentToken(const QXmlStreamReader &reader) + } + } + ++static bool isTokenAllowedInContext(QXmlStreamReader::TokenType type, ++ int loc) ++{ ++ switch (type) { ++ case QXmlStreamReader::StartDocument: ++ case QXmlStreamReader::DTD: ++ return loc == QXmlStreamReaderPrivate::Prolog; ++ ++ case QXmlStreamReader::StartElement: ++ case QXmlStreamReader::EndElement: ++ case QXmlStreamReader::Characters: ++ case QXmlStreamReader::EntityReference: ++ case QXmlStreamReader::EndDocument: ++ return loc == QXmlStreamReaderPrivate::Body; ++ ++ case QXmlStreamReader::Comment: ++ case QXmlStreamReader::ProcessingInstruction: ++ return true; ++ ++ case QXmlStreamReader::NoToken: ++ case QXmlStreamReader::Invalid: ++ return false; ++ } ++ ++ return false; ++} ++ ++/*! ++ \internal ++ \brief QXmlStreamReader::isValidToken ++ \return \c true if \param type is a valid token type. ++ \return \c false if \param type is an unexpected token, ++ which indicates a non-well-formed or invalid XML stream. ++ */ ++bool QXmlStreamReaderPrivate::isValidToken(QXmlStreamReader::TokenType type) ++{ ++ // Don't change currentContext, if Invalid or NoToken occur in the prolog ++ if (type == QXmlStreamReader::Invalid || type == QXmlStreamReader::NoToken) ++ return false; ++ ++ // If a token type gets rejected in the body, there is no recovery ++ const bool result = isTokenAllowedInContext(type, currentContext); ++ if (result || currentContext == QXmlStreamReaderPrivate::Body) ++ return result; ++ ++ // First non-Prolog token observed => switch context to body and check again. ++ currentContext = QXmlStreamReaderPrivate::Body; ++ return isTokenAllowedInContext(type, currentContext); ++} ++ ++/*! ++ \internal ++ Checks token type and raises an error, if it is invalid ++ in the current context (prolog/body). ++ */ ++void QXmlStreamReaderPrivate::checkToken() ++{ ++ Q_Q(QXmlStreamReader); ++ ++ // The token type must be consumed, to keep track if the body has been reached. ++ int context = currentContext; ++ const bool ok = isValidToken(type); ++ ++ // Do nothing if an error has been raised already (going along with an unexpected token) ++ if (error != QXmlStreamReader::NoError) ++ return; ++ ++ if (!ok) { ++ raiseError(QXmlStreamReader::UnexpectedElementError, ++ QXmlStream::tr("Unexpected token type %1 in %2.") ++ .arg(q->tokenString(), contextString(context))); ++ return; ++ } ++ ++ if (type != QXmlStreamReader::DTD) ++ return; ++ ++ // Raise error on multiple DTD tokens ++ if (foundDTD) { ++ raiseError(QXmlStreamReader::UnexpectedElementError, ++ QXmlStream::tr("Found second DTD token in %1.").arg(contextString(context))); ++ } else { ++ foundDTD = true; ++ } ++} ++ + /*! + \fn bool QXmlStreamAttributes::hasAttribute(const QString &qualifiedName) const + \since 4.5 +diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h +index 3539e1b7..055902a1 100644 +--- a/src/corelib/xml/qxmlstream_p.h ++++ b/src/corelib/xml/qxmlstream_p.h +@@ -790,6 +790,17 @@ public: + #endif + bool atEnd; + ++ enum XmlContext ++ { ++ Prolog = 0, ++ Body, ++ }; ++ ++ int currentContext = Prolog; ++ bool foundDTD = false; ++ bool isValidToken(QXmlStreamReader::TokenType type); ++ void checkToken(); ++ + /*! + \sa setType() + */ +-- +2.41.0 + diff --git a/qt.spec b/qt.spec index 50f6b37..712ee34 100644 --- a/qt.spec +++ b/qt.spec @@ -13,7 +13,7 @@ Name: qt Epoch: 1 Version: 4.8.7 -Release: 52 +Release: 53 Summary: A software toolkit for developing applications License: (LGPLv2 with exceptions or GPLv3 with exceptions) and ASL 2.0 and BSD and FTL and MIT URL: http://qt-project.org/ @@ -81,6 +81,7 @@ Patch6005: CVE-2020-17507.patch Patch6006: CVE-2020-0570.patch Patch6007: CVE-2023-32573.patch Patch6008: qt-CVE-2023-34410.patch +Patch6009: qt-CVE-2023-38197.patch BuildRequires: cups-devel desktop-file-utils gcc-c++ libjpeg-devel findutils libmng-devel libtiff-devel pkgconfig pkgconfig(alsa) BuildRequires: pkgconfig(dbus-1) pkgconfig(fontconfig) pkgconfig(glib-2.0) pkgconfig(icu-i18n) openssl-devel pkgconfig(libpng) @@ -447,6 +448,12 @@ fi %{_qt4_prefix}/examples/ %changelog +* Fri Nov 24 2023 hua_yadong - 1:4.8.7-53 +- Type:cves +- ID:CVE-2023-38197 +- SUG:NA +- DESC:fix CVE-2023-38197 + * Thu Nov 02 2023 peijiankang - 1:4.8.7-52 - Type:cves - ID:CVE-2023-34410 -- Gitee