From 895a8e08c37637ecad2ace515c4b38a250d61c5c Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Fri, 1 Sep 2023 11:02:11 +0800 Subject: [PATCH] Fix CVE-2023-37369 --- CVE-2023-37369-pre.patch | 32 ++++++ CVE-2023-37369.patch | 203 +++++++++++++++++++++++++++++++++++++++ qt5-qtbase.spec | 11 ++- 3 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 CVE-2023-37369-pre.patch create mode 100644 CVE-2023-37369.patch diff --git a/CVE-2023-37369-pre.patch b/CVE-2023-37369-pre.patch new file mode 100644 index 0000000..c806d4d --- /dev/null +++ b/CVE-2023-37369-pre.patch @@ -0,0 +1,32 @@ +From d76b11a0d55f40e964686564bac512e5895147b6 Mon Sep 17 00:00:00 2001 +From: Allan Sandfeld Jensen +Date: Wed, 14 Apr 2021 22:13:32 +0200 +Subject: [PATCH] Don't parse XML symbols longer than 4096 characters + +It is slow and will use too much memory. + +Fixes: QTBUG-91889 +Change-Id: I45c5e6038357c87bbb85b1ace17ef39a2a814ea0 +Reviewed-by: Thiago Macieira +(cherry picked from commit 38e111158a38507c63fd70f9ee18b9116b537976) +Reviewed-by: Qt Cherry-pick Bot +--- + src/corelib/serialization/qxmlstream.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp +index 9a3e306f424..a38720b370f 100644 +--- a/src/corelib/serialization/qxmlstream.cpp ++++ b/src/corelib/serialization/qxmlstream.cpp +@@ -1307,6 +1307,11 @@ inline int QXmlStreamReaderPrivate::fastScanName(int *prefix) + 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; ++ } + switch (c) { + case '\n': + case ' ': diff --git a/CVE-2023-37369.patch b/CVE-2023-37369.patch new file mode 100644 index 0000000..ad2984f --- /dev/null +++ b/CVE-2023-37369.patch @@ -0,0 +1,203 @@ +diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp +index 7cd457ba3a..11d162cb79 100644 +--- a/src/corelib/serialization/qxmlstream.cpp ++++ b/src/corelib/serialization/qxmlstream.cpp +@@ -1302,15 +1302,18 @@ inline int QXmlStreamReaderPrivate::fastScanContentCharList() + 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': +@@ -1339,23 +1342,23 @@ inline int QXmlStreamReaderPrivate::fastScanName(int *prefix) + 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: +@@ -1364,12 +1367,12 @@ inline int QXmlStreamReaderPrivate::fastScanName(int *prefix) + } + } + +- 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 }; +@@ -1878,6 +1881,14 @@ void QXmlStreamReaderPrivate::raiseWellFormedError(const QString &message) + 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 --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g +index 4321fed68a..8c6a1a5887 100644 +--- a/src/corelib/serialization/qxmlstream.g ++++ b/src/corelib/serialization/qxmlstream.g +@@ -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 --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h +index e5bde7b98e..b01484cac3 100644 +--- a/src/corelib/serialization/qxmlstream_p.h ++++ b/src/corelib/serialization/qxmlstream_p.h +@@ -1005,7 +1005,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(); + + +@@ -1014,6 +1023,7 @@ public: + + void raiseError(QXmlStreamReader::Error error, const QString& message = QString()); + void raiseWellFormedError(const QString &message); ++ void raiseNamePrefixTooLongError(); + + QXmlStreamEntityResolver *entityResolver; + +@@ -1939,7 +1949,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; +@@ -1947,7 +1962,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/qt5-qtbase.spec b/qt5-qtbase.spec index e8316dc..13ef052 100644 --- a/qt5-qtbase.spec +++ b/qt5-qtbase.spec @@ -34,7 +34,7 @@ BuildRequires: pkgconfig(libsystemd) Name: qt5-qtbase Summary: Qt5 - QtBase components Version: 5.15.2 -Release: 7 +Release: 8 # See LGPL_EXCEPTIONS.txt, for exception details @@ -118,6 +118,10 @@ Patch0022: add-loongarch64-support.patch Patch0023: CVE-2023-24607.patch Patch0024: CVE-2023-32762.patch Patch0025: CVE-2023-32763.patch +# https://github.com/qt/qtbase/commit/d76b11a +# https://download.qt.io/official_releases/qt/5.15/CVE-2023-37369-qtbase-5.15.diff +Patch0026: CVE-2023-37369-pre.patch +Patch0027: CVE-2023-37369.patch # Do not check any files in %%{_qt5_plugindir}/platformthemes/ for requires. # Those themes are there for platform integration. If the required libraries are # not there, the platform to integrate with isn't either. Then Qt will just @@ -378,6 +382,8 @@ Qt5 libraries used for drawing widgets and OpenGL items. %patch0023 -p1 %patch0024 -p1 %patch0025 -p1 +%patch0026 -p1 +%patch0027 -p1 # move some bundled libs to ensure they're not accidentally used pushd src/3rdparty @@ -1020,6 +1026,9 @@ fi %changelog +* Fri Sep 01 2023 wangkai <13474090681@163.com> - 5.15.2-8 +- Fix CVE-2023-37369 + * Wed Jun 28 2023 yaoxin - 5.15.2-7 - Fix CVE-2023-32762 and CVE-2023-32763 -- Gitee