aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff')
-rw-r--r--recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff231
1 files changed, 231 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..cb631519
--- /dev/null
+++ b/recipes-qt/qt5/qtbase/CVE-2023-38197-qtbase-5.15.diff
@@ -0,0 +1,231 @@
+From ae3946f38904b626a73a64f2829f60c911e2943b Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Tue, 10 Oct 2023 16:11:57 +0200
+Subject: [PATCH] qtbase: Pick CVE-2023-38197 fix
+
+CVE: CVE-2023-38197
+Upstream-Status: Backport [https://download.qt.io/official_releases/qt/5.15/CVE-2023-38197-qtbase-5.15.diff]
+---
+ src/corelib/serialization/qxmlstream.cpp | 144 +++++++++++++++++++++--
+ src/corelib/serialization/qxmlstream_p.h | 11 ++
+ 2 files changed, 147 insertions(+), 8 deletions(-)
+
+diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
+index 6c98e7c013..2553d3e09a 100644
+--- a/src/corelib/serialization/qxmlstream.cpp
++++ b/src/corelib/serialization/qxmlstream.cpp
+@@ -160,7 +160,7 @@ enum { StreamEOF = ~0U };
+ 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 @@ 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
+@@ -620,6 +641,7 @@ QXmlStreamReader::TokenType QXmlStreamReader::readNext()
+ d->token = -1;
+ return readNext();
+ }
++ d->checkToken();
+ return d->type;
+ }
+
+@@ -740,6 +762,14 @@ static const short QXmlStreamReader_tokenTypeString_indices[] = {
+ };
+
+
++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 @@ QString QXmlStreamReader::tokenString() const
+ 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 @@ void QXmlStreamReaderPrivate::init()
+
+ type = QXmlStreamReader::NoToken;
+ error = QXmlStreamReader::NoError;
++ currentContext = XmlContext::Prolog;
++ foundDTD = false;
+ }
+
+ /*
+@@ -4061,6 +4103,92 @@ void QXmlStreamWriter::writeCurrentToken(const QXmlStreamReader &reader)
+ }
+ }
+
++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 80e7f74080..6db58386db 100644
+--- a/src/corelib/serialization/qxmlstream_p.h
++++ b/src/corelib/serialization/qxmlstream_p.h
+@@ -804,6 +804,17 @@ public:
+ #endif
+ bool atEnd;
+
++ enum class XmlContext
++ {
++ Prolog,
++ Body,
++ };
++
++ XmlContext currentContext = XmlContext::Prolog;
++ bool foundDTD = false;
++ bool isValidToken(QXmlStreamReader::TokenType type);
++ void checkToken();
++
+ /*!
+ \sa setType()
+ */