diff --git a/CVE-2023-37369.diff b/CVE-2023-37369.diff new file mode 100644 index 0000000..053a873 --- /dev/null +++ b/CVE-2023-37369.diff @@ -0,0 +1,200 @@ +diff -rupN qtbase-everywhere-src-5.15.10/src/corelib/serialization/qxmlstream.cpp qtbase-everywhere-src-5.15.10-new/src/corelib/serialization/qxmlstream.cpp +--- qtbase-everywhere-src-5.15.10/src/corelib/serialization/qxmlstream.cpp 2023-08-16 20:50:25.911939568 +0200 ++++ qtbase-everywhere-src-5.15.10-new/src/corelib/serialization/qxmlstream.cpp 2023-08-16 20:51:01.258352373 +0200 +@@ -1341,15 +1341,18 @@ inline int QXmlStreamReaderPrivate::fast + return n; + } + +-inline int QXmlStreamReaderPrivate::fastScanName(int *prefix) ++// Fast scan an XML attribute name (e.g. "xml:lang"). ++inline QXmlStreamReaderPrivate::FastScanNameResult ++QXmlStreamReaderPrivate::fastScanName(Value *val) + { + int n = 0; + uint c; + while ((c = getChar()) != StreamEOF) { + if (n >= 4096) { + // This is too long to be a sensible name, and +- // can exhaust memory +- return 0; ++ // can exhaust memory, or the range of decltype(*prefix) ++ raiseNamePrefixTooLongError(); ++ return {}; + } + switch (c) { + case '\n': +@@ -1378,23 +1381,23 @@ inline int QXmlStreamReaderPrivate::fast + case '+': + case '*': + putChar(c); +- if (prefix && *prefix == n+1) { +- *prefix = 0; ++ if (val && val->prefix == n + 1) { ++ val->prefix = 0; + putChar(':'); + --n; + } +- return n; ++ return FastScanNameResult(n); + case ':': +- if (prefix) { +- if (*prefix == 0) { +- *prefix = n+2; ++ if (val) { ++ if (val->prefix == 0) { ++ val->prefix = n + 2; + } else { // only one colon allowed according to the namespace spec. + putChar(c); +- return n; ++ return FastScanNameResult(n); + } + } else { + putChar(c); +- return n; ++ return FastScanNameResult(n); + } + Q_FALLTHROUGH(); + default: +@@ -1403,12 +1406,12 @@ inline int QXmlStreamReaderPrivate::fast + } + } + +- if (prefix) +- *prefix = 0; ++ if (val) ++ val->prefix = 0; + int pos = textBuffer.size() - n; + putString(textBuffer, pos); + textBuffer.resize(pos); +- return 0; ++ return FastScanNameResult(0); + } + + enum NameChar { NameBeginning, NameNotBeginning, NotName }; +@@ -1917,6 +1920,14 @@ void QXmlStreamReaderPrivate::raiseWellF + raiseError(QXmlStreamReader::NotWellFormedError, message); + } + ++void QXmlStreamReaderPrivate::raiseNamePrefixTooLongError() ++{ ++ // TODO: add a ImplementationLimitsExceededError and use it instead ++ raiseError(QXmlStreamReader::NotWellFormedError, ++ QXmlStream::tr("Length of XML attribute name exceeds implemnetation limits (4KiB " ++ "characters).")); ++} ++ + void QXmlStreamReaderPrivate::parseError() + { + +diff -rupN qtbase-everywhere-src-5.15.10/src/corelib/serialization/qxmlstream.g qtbase-everywhere-src-5.15.10-new/src/corelib/serialization/qxmlstream.g +--- qtbase-everywhere-src-5.15.10/src/corelib/serialization/qxmlstream.g 2023-04-24 15:43:14.000000000 +0200 ++++ qtbase-everywhere-src-5.15.10-new/src/corelib/serialization/qxmlstream.g 2023-08-16 20:51:01.259352384 +0200 +@@ -516,7 +516,16 @@ public: + int fastScanLiteralContent(); + int fastScanSpace(); + int fastScanContentCharList(); +- int fastScanName(int *prefix = nullptr); ++ ++ struct FastScanNameResult { ++ FastScanNameResult() : ok(false) {} ++ explicit FastScanNameResult(int len) : addToLen(len), ok(true) { } ++ operator bool() { return ok; } ++ int operator*() { Q_ASSERT(ok); return addToLen; } ++ int addToLen; ++ bool ok; ++ }; ++ FastScanNameResult fastScanName(Value *val = nullptr); + inline int fastScanNMTOKEN(); + + +@@ -525,6 +534,7 @@ public: + + void raiseError(QXmlStreamReader::Error error, const QString& message = QString()); + void raiseWellFormedError(const QString &message); ++ void raiseNamePrefixTooLongError(); + + QXmlStreamEntityResolver *entityResolver; + +@@ -1811,7 +1821,12 @@ space_opt ::= space; + qname ::= LETTER; + /. + case $rule_number: { +- sym(1).len += fastScanName(&sym(1).prefix); ++ Value &val = sym(1); ++ if (auto res = fastScanName(&val)) ++ val.len += *res; ++ else ++ return false; ++ + if (atEnd) { + resume($rule_number); + return false; +@@ -1822,7 +1837,11 @@ qname ::= LETTER; + name ::= LETTER; + /. + case $rule_number: +- sym(1).len += fastScanName(); ++ if (auto res = fastScanName()) ++ sym(1).len += *res; ++ else ++ return false; ++ + if (atEnd) { + resume($rule_number); + return false; +diff -rupN qtbase-everywhere-src-5.15.10/src/corelib/serialization/qxmlstream_p.h qtbase-everywhere-src-5.15.10-new/src/corelib/serialization/qxmlstream_p.h +--- qtbase-everywhere-src-5.15.10/src/corelib/serialization/qxmlstream_p.h 2023-08-16 20:50:25.911939568 +0200 ++++ qtbase-everywhere-src-5.15.10-new/src/corelib/serialization/qxmlstream_p.h 2023-08-16 20:51:01.259352384 +0200 +@@ -1016,7 +1016,16 @@ public: + int fastScanLiteralContent(); + int fastScanSpace(); + int fastScanContentCharList(); +- int fastScanName(int *prefix = nullptr); ++ ++ struct FastScanNameResult { ++ FastScanNameResult() : ok(false) {} ++ explicit FastScanNameResult(int len) : addToLen(len), ok(true) { } ++ operator bool() { return ok; } ++ int operator*() { Q_ASSERT(ok); return addToLen; } ++ int addToLen; ++ bool ok; ++ }; ++ FastScanNameResult fastScanName(Value *val = nullptr); + inline int fastScanNMTOKEN(); + + +@@ -1025,6 +1034,7 @@ public: + + void raiseError(QXmlStreamReader::Error error, const QString& message = QString()); + void raiseWellFormedError(const QString &message); ++ void raiseNamePrefixTooLongError(); + + QXmlStreamEntityResolver *entityResolver; + +@@ -1950,7 +1960,12 @@ bool QXmlStreamReaderPrivate::parse() + break; + + case 262: { +- sym(1).len += fastScanName(&sym(1).prefix); ++ Value &val = sym(1); ++ if (auto res = fastScanName(&val)) ++ val.len += *res; ++ else ++ return false; ++ + if (atEnd) { + resume(262); + return false; +@@ -1958,7 +1973,11 @@ bool QXmlStreamReaderPrivate::parse() + } break; + + case 263: +- sym(1).len += fastScanName(); ++ if (auto res = fastScanName()) ++ sym(1).len += *res; ++ else ++ return false; ++ + if (atEnd) { + resume(263); + return false; diff --git a/mingw-qt5-qtbase.spec b/mingw-qt5-qtbase.spec index ff73cc4..80e06cf 100644 --- a/mingw-qt5-qtbase.spec +++ b/mingw-qt5-qtbase.spec @@ -25,7 +25,7 @@ Name: mingw-qt5-qtbase Version: 5.15.10 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Qt5 for Windows - QtBase component # See LGPL_EXCEPTIONS.txt, for exception details @@ -103,6 +103,9 @@ Patch19: qtbase-5.15.8-fix-missing-qtsan-include.patch # Backport fix for CVE-2023-38197 Patch20: CVE-2023-38197.patch +# Backport fix for CVE-2023-37369 +Patch21: CVE-2023-37369.diff + ## KDE 5.15 branch patches # https://invent.kde.org/qt/qt/qtbase, kde/5.15 branch # git diff v5.15.10..HEAD | gzip > kde-5.15-rollup-$(date +%Y%m%d).patch.gz @@ -816,6 +819,9 @@ ln -s %{mingw64_target}-qmake-qt5 %{buildroot}%{_bindir}/mingw64-qmake-qt5 %changelog +* Wed Aug 16 2023 Sandro Mani - 5.15.10-4 +- Backport fix for CVE-2023-37369 + * Thu Jul 20 2023 Fedora Release Engineering - 5.15.10-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild