diff --git a/CVE-2015-9541.patch b/CVE-2015-9541.patch new file mode 100644 index 0000000000000000000000000000000000000000..44a727ab168c741e8352694ee2aa29e6950c4fe4 --- /dev/null +++ b/CVE-2015-9541.patch @@ -0,0 +1,158 @@ +From fd4be84d23a0db4186cb42e736a9de3af722c7f7 Mon Sep 17 00:00:00 2001 +From: Lars Knoll +Date: Wed, 26 Feb 2020 10:42:10 +0100 +Subject: Add an expansion limit for entities + +Recursively defined entities can easily exhaust all available +memory. Limit entity expansion to a default of 4096 characters to +avoid DoS attacks when a user loads untrusted content. + +Added a setter and getter to allow modifying the expansion limit. + +[ChangeLog][QtCore][QXmlStream] QXmlStreamReader does now by default +limit the expansion of entities to 4096 characters. Documents where +a single entity expands to more characters than the limit are not +considered well formed. The limit is there to avoid DoS attacks through +recursively expanding entities when loading untrusted content. The +limit can be changed through the QXmlStreamReader::setEntityExpansionLimit() +method. + +Fixes: QTBUG-47417 +Change-Id: I94387815d74fcf34783e136387ee57fac5ded0c9 +Reviewed-by: Oswald Buddenhagen +Reviewed-by: Volker Hilsheimer +--- + src/corelib/xml/qxmlstream.cpp | 36 ++++++++++++++++++ + src/corelib/xml/qxmlstream.g | 14 ++++++- + src/corelib/xml/qxmlstream.h | 2 + + src/corelib/xml/qxmlstream_p.h | 14 ++++++- + 5 files changed, 106 insertions(+), 4 deletions(-) + +diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp +index 7ff87885a5..d7fb0d0d41 100644 +--- a/src/corelib/xml/qxmlstream.cpp ++++ b/src/corelib/xml/qxmlstream.cpp +@@ -2041,6 +2041,42 @@ QStringRef QXmlStreamReader::dtdSystemId() const + return QStringRef(); + } + ++/*! ++ \since 5.15 ++ ++ Returns the maximum amount of characters a single entity is ++ allowed to expand into. If a single entity expands past the ++ given limit, the document is not considered well formed. ++ ++ \sa setEntityExpansionLimit ++*/ ++int QXmlStreamReader::entityExpansionLimit() const ++{ ++ Q_D(const QXmlStreamReader); ++ return d->entityExpansionLimit; ++} ++ ++/*! ++ \since 5.15 ++ ++ Sets the maximum amount of characters a single entity is ++ allowed to expand into to \a limit. If a single entity expands ++ past the given limit, the document is not considered well formed. ++ ++ The limit is there to prevent DoS attacks when loading unknown ++ XML documents where recursive entity expansion could otherwise ++ exhaust all available memory. ++ ++ The default value for this property is 4096 characters. ++ ++ \sa entityExpansionLimit ++*/ ++void QXmlStreamReader::setEntityExpansionLimit(int limit) ++{ ++ Q_D(QXmlStreamReader); ++ d->entityExpansionLimit = limit; ++} ++ + /*! If the state() is \l StartElement, this function returns the + element's namespace declarations. Otherwise an empty vector is + returned. +diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g +index 12ecc9bdb2..b623de9505 100644 +--- a/src/corelib/xml/qxmlstream.g ++++ b/src/corelib/xml/qxmlstream.g +@@ -285,9 +285,19 @@ public: + QHash entityHash; + QHash parameterEntityHash; + QXmlStreamSimpleStackentityReferenceStack; ++ int entityExpansionLimit = 4096; ++ int entityLength = 0; + inline bool referenceEntity(Entity &entity) { + if (entity.isCurrentlyReferenced) { +- raiseWellFormedError(QXmlStream::tr("Recursive entity detected.")); ++ raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected.")); ++ return false; ++ } ++ // entityLength represents the amount of additional characters the ++ // entity expands into (can be negative for e.g. &). It's used to ++ // avoid DoS attacks through recursive entity expansions ++ entityLength += entity.value.size() - entity.name.size() - 2; ++ if (entityLength > entityExpansionLimit) { ++ raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit.")); + return false; + } + entity.isCurrentlyReferenced = true; +@@ -838,6 +848,8 @@ entity_done ::= ENTITY_DONE; + /. + case $rule_number: + entityReferenceStack.pop()->isCurrentlyReferenced = false; ++ if (entityReferenceStack.isEmpty()) ++ entityLength = 0; + clearSym(); + break; + ./ +diff --git a/src/corelib/serialization/qxmlstream.h b/src/corelib/serialization/qxmlstream.h +index 7d0aa64570..c8647e0465 100644 +--- a/src/corelib/xml/qxmlstream.h ++++ b/src/corelib/xml/qxmlstream.h +@@ -426,6 +426,8 @@ public: + QStringRef dtdPublicId() const; + QStringRef dtdSystemId() const; + ++ int entityExpansionLimit() const; ++ void setEntityExpansionLimit(int limit); + + enum Error { + NoError, +diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h +index 9c94e6d434..103b123b10 100644 +--- a/src/corelib/xml/qxmlstream_p.h ++++ b/src/corelib/xml/qxmlstream_p.h +@@ -774,9 +774,19 @@ public: + QHash entityHash; + QHash parameterEntityHash; + QXmlStreamSimpleStackentityReferenceStack; ++ int entityExpansionLimit = 4096; ++ int entityLength = 0; + inline bool referenceEntity(Entity &entity) { + if (entity.isCurrentlyReferenced) { +- raiseWellFormedError(QXmlStream::tr("Recursive entity detected.")); ++ raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected.")); ++ return false; ++ } ++ // entityLength represents the amount of additional characters the ++ // entity expands into (can be negative for e.g. &). It's used to ++ // avoid DoS attacks through recursive entity expansions ++ entityLength += entity.value.size() - entity.name.size() - 2; ++ if (entityLength > entityExpansionLimit) { ++ raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit.")); + return false; + } + entity.isCurrentlyReferenced = true; +@@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse() + + case 10: + entityReferenceStack.pop()->isCurrentlyReferenced = false; ++ if (entityReferenceStack.isEmpty()) ++ entityLength = 0; + clearSym(); + break; + diff --git a/qt5-qtbase.spec b/qt5-qtbase.spec index ba5fad3e36819ee37c30850ecdd03dc6da9a7fd4..0ba145cf9c38b2e3a1fa16d261ced9e24c051765 100644 --- a/qt5-qtbase.spec +++ b/qt5-qtbase.spec @@ -13,7 +13,7 @@ Name: qt5-qtbase Summary: Core component of Qt toolkit Version: 5.11.1 -Release: 10 +Release: 11 License: LGPLv2 with exceptions or GPLv3 with exceptions Url: http://qt-project.org/ Source0: https://download.qt.io/official_releases/qt/5.11/%{version}/submodules/qtbase-everywhere-src-%{version}.tar.xz @@ -35,7 +35,8 @@ Patch0009: qt5-qtbase-5.9.1-firebird.patch Patch0010: qtbase-everywhere-src-5.11.1-python3.patch Patch0011: qt5-qtbase-glibc.patch -Patch6000: CVE-2018-15518.patch +Patch6000: CVE-2018-15518.patch +Patch6001: CVE-2015-9541.patch BuildRequires: pkgconfig(libsystemd) cups-devel desktop-file-utils findutils BuildRequires: libjpeg-devel libmng-devel libtiff-devel pkgconfig(alsa) @@ -402,6 +403,9 @@ fi %changelog +* Mon Sep 21 2020 wutao - 5.11.1-11 +- Fix CVE-2015-9541 + * Mon May 25 2020 lizhenhua - 5.11.1-10 - Fix compile issue with gcc 9