Fix CVE-2023-37369
This commit is contained in:
parent
493e86957f
commit
895a8e08c3
32
CVE-2023-37369-pre.patch
Normal file
32
CVE-2023-37369-pre.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From d76b11a0d55f40e964686564bac512e5895147b6 Mon Sep 17 00:00:00 2001
|
||||
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
||||
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 <thiago.macieira@intel.com>
|
||||
(cherry picked from commit 38e111158a38507c63fd70f9ee18b9116b537976)
|
||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
||||
---
|
||||
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 ' ':
|
||||
203
CVE-2023-37369.patch
Normal file
203
CVE-2023-37369.patch
Normal file
@ -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;
|
||||
@ -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 <yao_xin001@hoperun.com> - 5.15.2-7
|
||||
- Fix CVE-2023-32762 and CVE-2023-32763
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user