[SCM] qtbase packaging branch, master, updated. debian/5.1.1+dfsg-5-2-gdb0eb79
Lisandro Damián Nicanor Pérez
lisandro at moszumanska.debian.org
Thu Dec 5 15:03:53 UTC 2013
Gitweb-URL: http://git.debian.org/?p=pkg-kde/qt/qtbase.git;a=commitdiff;h=db0eb79
The following commit has been merged in the master branch:
commit db0eb79841147a5838385b232029991841809d17
Author: Lisandro Damián Nicanor Pérez Meyer <perezmeyer at gmail.com>
Date: Thu Dec 5 12:03:24 2013 -0300
Backport Disallow_deep_or_widely_nested_entity_references.patch
Fix CVE-2013-4549: XML Entity Expansion Denial of Service.
---
debian/changelog | 4 +
...w_deep_or_widely_nested_entity_references.patch | 261 +++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 266 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index ecc8f57..51411ac 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,9 @@
qtbase-opensource-src (5.1.1+dfsg-6) UNRELEASED; urgency=low
+ [ Lisandro Damián Nicanor Pérez Meyer ]
+ * Backport Disallow_deep_or_widely_nested_entity_references.patch to fix
+ CVE-2013-4549: XML Entity Expansion Denial of Service.
+
-- Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org> Thu, 05 Dec 2013 11:59:03 -0300
qtbase-opensource-src (5.1.1+dfsg-5) unstable; urgency=low
diff --git a/debian/patches/Disallow_deep_or_widely_nested_entity_references.patch b/debian/patches/Disallow_deep_or_widely_nested_entity_references.patch
new file mode 100644
index 0000000..c74e477
--- /dev/null
+++ b/debian/patches/Disallow_deep_or_widely_nested_entity_references.patch
@@ -0,0 +1,261 @@
+From b57ddb1aff55a20a07b27135c6eab268764527fd Mon Sep 17 00:00:00 2001
+From: Mitch Curtis <mitch.curtis at digia.com>
+Date: Fri, 27 Sep 2013 12:32:28 +0200
+Subject: [PATCH] Disallow deep or widely nested entity references.
+
+Nested entities with a depth of 2 or more will fail. Entities
+that fully expand to more than 1024 characters will also fail.
+
+Change-Id: I75525bc1edfa796c4db30a5109fe21011ad43a2d
+Reviewed-by: Richard J. Moore <rich at kde.org>
+Reviewed-by: Lars Knoll <lars.knoll at digia.com>
+(cherries picked from commits 46a8885ae486e238a39efa5119c2714f328b08e4
+and f1053d94f59f053ce4acad9320df14f1fbe4faac)
+---
+ src/xml/sax/qxml.cpp | 63 ++++++++++++++++++++++
+ .../sax/qxmlsimplereader/tst_qxmlsimplereader.cpp | 58 ++++++++++++++++++++
+ .../xmldocs/1-levels-nested-dtd.xml | 12 +++++
+ .../xmldocs/2-levels-nested-dtd.xml | 13 +++++
+ .../internal-entity-polynomial-attribute.xml | 13 +++++
+ 5 files changed, 159 insertions(+)
+ create mode 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/1-levels-nested-dtd.xml
+ create mode 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/2-levels-nested-dtd.xml
+ create mode 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/internal-entity-polynomial-attribute.xml
+
+diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
+index 0e20041..5ddcf27 100644
+--- a/src/xml/sax/qxml.cpp
++++ b/src/xml/sax/qxml.cpp
+@@ -424,6 +424,12 @@ private:
+ int stringValueLen;
+ QString emptyStr;
+
++ // The limit to the amount of times the DTD parsing functions can be called
++ // for the DTD currently being parsed.
++ static const int dtdRecursionLimit = 2;
++ // The maximum amount of characters an entity value may contain, after expansion.
++ static const int entityCharacterLimit = 1024;
++
+ const QString &string();
+ void stringClear();
+ void stringAddC(QChar);
+@@ -493,6 +499,8 @@ private:
+ void parseFailed(ParseFunction where, int state);
+ void pushParseState(ParseFunction function, int state);
+
++ bool isExpandedEntityValueTooLarge(QString *errorMessage);
++
+ Q_DECLARE_PUBLIC(QXmlSimpleReader)
+ QXmlSimpleReader *q_ptr;
+
+@@ -5035,6 +5043,11 @@ bool QXmlSimpleReaderPrivate::parseDoctype()
+ }
+ break;
+ case Mup:
++ if (dtdRecursionLimit > 0 && parameterEntities.size() > dtdRecursionLimit) {
++ reportParseError(QString::fromLatin1(
++ "DTD parsing exceeded recursion limit of %1.").arg(dtdRecursionLimit));
++ return false;
++ }
+ if (!parseMarkupdecl()) {
+ parseFailed(&QXmlSimpleReaderPrivate::parseDoctype, state);
+ return false;
+@@ -6644,6 +6657,50 @@ bool QXmlSimpleReaderPrivate::parseChoiceSeq()
+ return false;
+ }
+
++bool QXmlSimpleReaderPrivate::isExpandedEntityValueTooLarge(QString *errorMessage)
++{
++ QMap<QString, int> literalEntitySizes;
++ // The entity at (QMap<QString,) referenced the entities at (QMap<QString,) (int>) times.
++ QMap<QString, QMap<QString, int> > referencesToOtherEntities;
++ QMap<QString, int> expandedSizes;
++
++ // For every entity, check how many times all entity names were referenced in its value.
++ foreach (QString toSearch, entities.keys()) {
++ // The amount of characters that weren't entity names, but literals, like 'X'.
++ QString leftOvers = entities.value(toSearch);
++ // How many times was entityName referenced by toSearch?
++ foreach (QString entityName, entities.keys()) {
++ for (int i = 0; i < leftOvers.size() && i != -1; ) {
++ i = leftOvers.indexOf(QString::fromLatin1("&%1;").arg(entityName), i);
++ if (i != -1) {
++ leftOvers.remove(i, entityName.size() + 2);
++ // The entityName we're currently trying to find was matched in this string; increase our count.
++ ++referencesToOtherEntities[toSearch][entityName];
++ }
++ }
++ }
++ literalEntitySizes[toSearch] = leftOvers.size();
++ }
++
++ foreach (QString entity, referencesToOtherEntities.keys()) {
++ expandedSizes[entity] = literalEntitySizes[entity];
++ foreach (QString referenceTo, referencesToOtherEntities.value(entity).keys()) {
++ const int references = referencesToOtherEntities.value(entity).value(referenceTo);
++ // The total size of an entity's value is the expanded size of all of its referenced entities, plus its literal size.
++ expandedSizes[entity] += expandedSizes[referenceTo] * references + literalEntitySizes[referenceTo] * references;
++ }
++
++ if (expandedSizes[entity] > entityCharacterLimit) {
++ if (errorMessage) {
++ *errorMessage = QString::fromLatin1("The XML entity \"%1\" expands too a string that is too large to process (%2 characters > %3).");
++ *errorMessage = (*errorMessage).arg(entity).arg(expandedSizes[entity]).arg(entityCharacterLimit);
++ }
++ return true;
++ }
++ }
++ return false;
++}
++
+ /*
+ Parse a EntityDecl [70].
+
+@@ -6738,6 +6795,12 @@ bool QXmlSimpleReaderPrivate::parseEntityDecl()
+ switch (state) {
+ case EValue:
+ if ( !entityExist(name())) {
++ QString errorMessage;
++ if (isExpandedEntityValueTooLarge(&errorMessage)) {
++ reportParseError(errorMessage);
++ return false;
++ }
++
+ entities.insert(name(), string());
+ if (declHnd) {
+ if (!declHnd->internalEntityDecl(name(), string())) {
+diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
+index d4c0ff4..d6ad867 100644
+--- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
++++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
+@@ -160,6 +160,7 @@ class tst_QXmlSimpleReader : public QObject
+ void reportNamespace() const;
+ void reportNamespace_data() const;
+ void roundtripWithNamespaces() const;
++ void dtdRecursionLimit();
+
+ private:
+ static QDomDocument fromByteArray(const QString &title, const QByteArray &ba, bool *ok);
+@@ -770,5 +771,62 @@ void tst_QXmlSimpleReader::roundtripWithNamespaces() const
+ }
+ }
+
++class TestHandler : public QXmlDefaultHandler
++{
++public:
++ TestHandler() :
++ recursionCount(0)
++ {
++ }
++
++ bool internalEntityDecl(const QString &name, const QString &value)
++ {
++ ++recursionCount;
++ return QXmlDefaultHandler::internalEntityDecl(name, value);
++ }
++
++ int recursionCount;
++};
++
++void tst_QXmlSimpleReader::dtdRecursionLimit()
++{
++ QFile file("xmldocs/2-levels-nested-dtd.xml");
++ QVERIFY(file.open(QIODevice::ReadOnly));
++ QXmlSimpleReader xmlReader;
++ {
++ QXmlInputSource *source = new QXmlInputSource(&file);
++ TestHandler handler;
++ xmlReader.setDeclHandler(&handler);
++ xmlReader.setErrorHandler(&handler);
++ QVERIFY(!xmlReader.parse(source));
++ }
++
++ file.close();
++ file.setFileName("xmldocs/1-levels-nested-dtd.xml");
++ QVERIFY(file.open(QIODevice::ReadOnly));
++ {
++ QXmlInputSource *source = new QXmlInputSource(&file);
++ TestHandler handler;
++ xmlReader.setDeclHandler(&handler);
++ xmlReader.setErrorHandler(&handler);
++ QVERIFY(!xmlReader.parse(source));
++ // The error wasn't because of the recursion limit being reached,
++ // it was because the document is not valid.
++ QVERIFY(handler.recursionCount < 2);
++ }
++
++ file.close();
++ file.setFileName("xmldocs/internal-entity-polynomial-attribute.xml");
++ QVERIFY(file.open(QIODevice::ReadOnly));
++ {
++ QXmlInputSource *source = new QXmlInputSource(&file);
++ TestHandler handler;
++ xmlReader.setDeclHandler(&handler);
++ xmlReader.setErrorHandler(&handler);
++ QVERIFY(!xmlReader.parse(source));
++ QCOMPARE(handler.recursionCount, 2);
++ }
++}
++
+ QTEST_MAIN(tst_QXmlSimpleReader)
+ #include "tst_qxmlsimplereader.moc"
+diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/1-levels-nested-dtd.xml b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/1-levels-nested-dtd.xml
+new file mode 100644
+index 0000000..0dfc15b
+--- /dev/null
++++ b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/1-levels-nested-dtd.xml
+@@ -0,0 +1,12 @@
++<?xml version="1.0"?>
++<!-- Test non-deterministic content model matching.
++
++Entity references are not part of the internal DTD subset (for good reason).
++
++-->
++<!DOCTYPE root [
++<!ELEMENT e0 EMPTY>
++<!ENTITY % e1 "(e0,e0)">
++<!ELEMENT root (%e1;)?>
++]>
++<root/>
+\ No newline at end of file
+diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/2-levels-nested-dtd.xml b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/2-levels-nested-dtd.xml
+new file mode 100644
+index 0000000..7ec06db
+--- /dev/null
++++ b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/2-levels-nested-dtd.xml
+@@ -0,0 +1,13 @@
++<?xml version="1.0"?>
++<!-- Test non-deterministic content model matching.
++
++Entity references are not part of the internal DTD subset (for good reason).
++
++-->
++<!DOCTYPE root [
++<!ELEMENT e0 EMPTY>
++<!ENTITY % e1 "(e0,e0)">
++<!ENTITY % e2 "(%e1;,%e1;,%e1;,%e1;,%e1;,%e1;,%e1;,%e1;,%e1;,%e1;,%e1;,%e1;,%e1;)">
++<!ELEMENT root (%e2;)?>
++]>
++<root/>
+diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/internal-entity-polynomial-attribute.xml b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/internal-entity-polynomial-attribute.xml
+new file mode 100644
+index 0000000..bbb88f3
+--- /dev/null
++++ b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/internal-entity-polynomial-attribute.xml
+@@ -0,0 +1,13 @@
++<?xml version="1.0"?>
++<!-- Test polynomial growth of expanded XML.
++ Expansion happens in an attribute. -->
++<!DOCTYPE root [
++<!ELEMENT root EMPTY>
++<!ATTLIST root id CDATA #IMPLIED>
++<!ENTITY e1 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX">
++<!ENTITY e2 "&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;&e1;">
++<!ENTITY e3 "&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;&e2;">
++<!ENTITY e4 "&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;&e3;">
++]>
++<root id="&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;&e4;"/>
++
+--
+1.8.4.2
+
diff --git a/debian/patches/series b/debian/patches/series
index 348d46c..22e9ee9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,5 +2,6 @@ sha3_64bit_BE.diff
linux_no_perf.diff
fix_usr-move_workaround_in_the_presence_of_multi-arch.patch
hurd_opengl_incldir.diff
+Disallow_deep_or_widely_nested_entity_references.patch
# Debian specific.
--
qtbase packaging
More information about the pkg-kde-commits
mailing list