diff options
author | Marek Vasut <marex@denx.de> | 2023-10-10 16:11:57 +0200 |
---|---|---|
committer | Martin Jansa <martin.jansa@gmail.com> | 2023-10-11 14:18:48 +0200 |
commit | a77ea02371242d391dcccad4d97af3a685dc8a9d (patch) | |
tree | 56572fe47863b4a58542876e07b3c7edceee74c5 /recipes-qt/qt5 | |
parent | 7c405994e572ccdf1e03253c5065a3d484277f68 (diff) |
qtbase: Pick CVE-2023-38197 fix
An issue was discovered in Qt before 5.15.15, 6.x before 6.2.10,
and 6.3.x through 6.5.x before 6.5.3. There are infinite loops
in recursive entity expansion.
Advisory:
https://nvd.nist.gov/vuln/detail/CVE-2023-38197
Patch:
https://download.qt.io/official_releases/qt/5.15/CVE-2023-38197-qtbase-5.15.diff
Signed-off-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'recipes-qt/qt5')
-rw-r--r-- | recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff | 219 | ||||
-rw-r--r-- | recipes-qt/qt5/qtbase_git.bb | 1 |
2 files changed, 220 insertions, 0 deletions
diff --git a/recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff b/recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff new file mode 100644 index 00000000..e9e622bc --- /dev/null +++ b/recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff @@ -0,0 +1,219 @@ +diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp +index bf8a2a9..6ab5d49 100644 +--- a/src/corelib/serialization/qxmlstream.cpp ++++ b/src/corelib/serialization/qxmlstream.cpp +@@ -160,7 +160,7 @@ + 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. + + */ + +@@ -295,13 +295,34 @@ + + 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 +@@ -620,6 +641,7 @@ + d->token = -1; + return readNext(); + } ++ d->checkToken(); + return d->type; + } + +@@ -740,6 +762,14 @@ + }; + + ++static const char QXmlStreamReader_XmlContextString[] = ++ "Prolog\0" ++ "Body\0"; ++ ++static const short QXmlStreamReader_XmlContextString_indices[] = { ++ 0, 7 ++}; ++ + /*! + \property QXmlStreamReader::namespaceProcessing + The namespace-processing flag of the stream reader +@@ -775,6 +805,16 @@ + QXmlStreamReader_tokenTypeString_indices[d->type]); + } + ++/*! ++ \internal ++ \return \param ctxt (Prolog/Body) as a string. ++ */ ++QString contextString(QXmlStreamReaderPrivate::XmlContext ctxt) ++{ ++ return QLatin1String(QXmlStreamReader_XmlContextString + ++ QXmlStreamReader_XmlContextString_indices[static_cast<int>(ctxt)]); ++} ++ + #endif // QT_NO_XMLSTREAMREADER + + QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack() +@@ -866,6 +906,8 @@ + + type = QXmlStreamReader::NoToken; + error = QXmlStreamReader::NoError; ++ currentContext = XmlContext::Prolog; ++ foundDTD = false; + } + + /* +@@ -4061,6 +4103,92 @@ + } + } + ++static bool isTokenAllowedInContext(QXmlStreamReader::TokenType type, ++ QXmlStreamReaderPrivate::XmlContext loc) ++{ ++ switch (type) { ++ case QXmlStreamReader::StartDocument: ++ case QXmlStreamReader::DTD: ++ return loc == QXmlStreamReaderPrivate::XmlContext::Prolog; ++ ++ case QXmlStreamReader::StartElement: ++ case QXmlStreamReader::EndElement: ++ case QXmlStreamReader::Characters: ++ case QXmlStreamReader::EntityReference: ++ case QXmlStreamReader::EndDocument: ++ return loc == QXmlStreamReaderPrivate::XmlContext::Body; ++ ++ case QXmlStreamReader::Comment: ++ case QXmlStreamReader::ProcessingInstruction: ++ return true; ++ ++ case QXmlStreamReader::NoToken: ++ case QXmlStreamReader::Invalid: ++ return false; ++ default: ++ 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 == XmlContext::Body) ++ return result; ++ ++ // First non-Prolog token observed => switch context to body and check again. ++ currentContext = XmlContext::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. ++ const XmlContext 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::Error::NoError) ++ return; ++ ++ if (!ok) { ++ raiseError(QXmlStreamReader::UnexpectedElementError, ++ QLatin1String("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, ++ QLatin1String("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/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h +index 8f7c9e0..708059b 100644 +--- a/src/corelib/serialization/qxmlstream_p.h ++++ b/src/corelib/serialization/qxmlstream_p.h +@@ -804,6 +804,17 @@ + #endif + bool atEnd; + ++ enum class XmlContext ++ { ++ Prolog, ++ Body, ++ }; ++ ++ XmlContext currentContext = XmlContext::Prolog; ++ bool foundDTD = false; ++ bool isValidToken(QXmlStreamReader::TokenType type); ++ void checkToken(); ++ + /*! + \sa setType() + */ diff --git a/recipes-qt/qt5/qtbase_git.bb b/recipes-qt/qt5/qtbase_git.bb index e076e66d..a2785617 100644 --- a/recipes-qt/qt5/qtbase_git.bb +++ b/recipes-qt/qt5/qtbase_git.bb @@ -44,6 +44,7 @@ SRC_URI += "\ file://CVE-2023-33285-qtbase-5.15.diff \ file://CVE-2023-34410-qtbase-5.15.diff \ file://CVE-2023-37369-qtbase-5.15.diff \ + file://CVE-2023-38197-qtbase-5.15.diff \ " # Disable LTO for now, QT5 patches are being worked upstream, perhaps revisit with |