diff mbox series

package/qt5/qt5base: fix CVE-2021-38593

Message ID 20220121161458.220687-1-quentin.schulz@theobroma-systems.com
State Superseded
Headers show
Series package/qt5/qt5base: fix CVE-2021-38593 | expand

Commit Message

Quentin Schulz Jan. 21, 2022, 4:14 p.m. UTC
From: Quentin Schulz <quentin.schulz@theobroma-systems.com>

5.15.2 is the last public release of 5.15 and does not contain this CVE
fix. However, 6.1+ and 5.12.12 all contain the necessary patches so
let's port them to 5.15.2.

As a note, those are also available on kde "fork" in their kde/5.15
branch:
https://invent.kde.org/qt/qt/qtbase/-/commit/081d835c040a90f8ee76807354355062ac521dfb
https://invent.kde.org/qt/qt/qtbase/-/commit/fed5713eeba5bf8e0ee413cb4e77109bfa7c2bce

Cc: Quentin Schulz <foss+buildroot@0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
---
 ...-intensive-painting-of-high-number-o.patch | 136 ++++++++++++++++++
 ...-avoiding-huge-number-of-tiny-dashes.patch |  37 +++++
 package/qt5/qt5base/qt5base.mk                |   4 +
 3 files changed, 177 insertions(+)
 create mode 100644 package/qt5/qt5base/0010-Avoid-processing-intensive-painting-of-high-number-o.patch
 create mode 100644 package/qt5/qt5base/0011-Improve-fix-for-avoiding-huge-number-of-tiny-dashes.patch
diff mbox series

Patch

diff --git a/package/qt5/qt5base/0010-Avoid-processing-intensive-painting-of-high-number-o.patch b/package/qt5/qt5base/0010-Avoid-processing-intensive-painting-of-high-number-o.patch
new file mode 100644
index 0000000000..fe3a16fd19
--- /dev/null
+++ b/package/qt5/qt5base/0010-Avoid-processing-intensive-painting-of-high-number-o.patch
@@ -0,0 +1,136 @@ 
+From 7f345f2a1c8d9f60c60e8a9d8cc90729794bd2f1 Mon Sep 17 00:00:00 2001
+From: Eirik Aavitsland <eirik.aavitsland@qt.io>
+Date: Tue, 13 Apr 2021 14:23:45 +0200
+Subject: [PATCH] Avoid processing-intensive painting of high number of tiny
+ dashes
+
+When stroking a dashed path, an unnecessary amount of processing would
+be spent if there is a huge number of dashes visible, e.g. because of
+scaling. Since the dashes are too small to be indivdually visible
+anyway, just replace with a semi-transparent solid line for such
+cases.
+
+Change-Id: I9e9f7861257ad5bce46a0cf113d1a9d7824911e6
+Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
+(cherry picked from commit f4d791b330d02777fcaf02938732892eb3167e9b)
+Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
+[Upstream: https://code.qt.io/cgit/qt/qtbase.git/patch/?id=7f345f2a1c8d9f60c60e8a9d8cc90729794bd2f1]
+Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+---
+ src/gui/painting/qpaintengineex.cpp              | 44 +++++++++++++++++++-----
+ tests/auto/other/lancelot/scripts/tinydashes.qps | 34 ++++++++++++++++++
+ 2 files changed, 69 insertions(+), 9 deletions(-)
+ create mode 100644 tests/auto/other/lancelot/scripts/tinydashes.qps
+
+diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
+index f4cbf15fc70..f04e3a498d8 100644
+--- a/src/gui/painting/qpaintengineex.cpp
++++ b/src/gui/painting/qpaintengineex.cpp
+@@ -385,7 +385,7 @@ QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
+ 
+ Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+ 
+-void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
++void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
+ {
+ #ifdef QT_DEBUG_DRAW
+     qDebug() << "QPaintEngineEx::stroke()" << pen;
+@@ -403,6 +403,38 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
+         d->stroker.setCubicToHook(qpaintengineex_cubicTo);
+     }
+ 
++    QRectF clipRect;
++    QPen pen = inPen;
++    if (pen.style() > Qt::SolidLine) {
++        QRectF cpRect = path.controlPointRect();
++        const QTransform &xf = state()->matrix;
++        if (qt_pen_is_cosmetic(pen, state()->renderHints)) {
++            clipRect = d->exDeviceRect;
++            cpRect.translate(xf.dx(), xf.dy());
++        } else {
++            clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
++        }
++        // Check to avoid generating unwieldy amount of dashes that will not be visible anyway
++        QRectF extentRect = cpRect & clipRect;
++        qreal extent = qMax(extentRect.width(), extentRect.height());
++        qreal patternLength = 0;
++        const QVector<qreal> pattern = pen.dashPattern();
++        const int patternSize = qMin(pattern.size(), 32);
++        for (int i = 0; i < patternSize; i++)
++            patternLength += qMax(pattern.at(i), qreal(0));
++        if (pen.widthF())
++            patternLength *= pen.widthF();
++        if (qFuzzyIsNull(patternLength)) {
++            pen.setStyle(Qt::NoPen);
++        } else if (extent / patternLength > 10000) {
++            // approximate stream of tiny dashes with semi-transparent solid line
++            pen.setStyle(Qt::SolidLine);
++            QColor color(pen.color());
++            color.setAlpha(color.alpha() / 2);
++            pen.setColor(color);
++        }
++    }
++
+     if (!qpen_fast_equals(pen, d->strokerPen)) {
+         d->strokerPen = pen;
+         d->stroker.setJoinStyle(pen.joinStyle());
+@@ -430,14 +462,8 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
+         return;
+     }
+ 
+-    if (pen.style() > Qt::SolidLine) {
+-        if (qt_pen_is_cosmetic(pen, state()->renderHints)){
+-            d->activeStroker->setClipRect(d->exDeviceRect);
+-        } else {
+-            QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
+-            d->activeStroker->setClipRect(clipRect);
+-        }
+-    }
++    if (!clipRect.isNull())
++        d->activeStroker->setClipRect(clipRect);
+ 
+     const QPainterPath::ElementType *types = path.elements();
+     const qreal *points = path.points();
+diff --git a/tests/auto/other/lancelot/scripts/tinydashes.qps b/tests/auto/other/lancelot/scripts/tinydashes.qps
+new file mode 100644
+index 00000000000..d41ced7f5f9
+--- /dev/null
++++ b/tests/auto/other/lancelot/scripts/tinydashes.qps
+@@ -0,0 +1,34 @@
++# Version: 1
++# CheckVsReference: 5%
++
++path_addEllipse mypath 20.0 20.0 200.0 200.0
++
++save
++setPen blue 20 SolidLine FlatCap
++pen_setCosmetic true
++pen_setDashPattern [ 0.0004 0.0004 ]
++setBrush yellow
++
++drawPath mypath
++translate 300 0
++setRenderHint Antialiasing true
++drawPath mypath
++restore
++
++path_addEllipse bigpath 200000.0 200000.0 2000000.0 2000000.0
++
++setPen blue 20 DotLine FlatCap
++setBrush yellow
++
++save
++translate 0 300
++scale 0.0001 0.00011
++drawPath bigpath
++restore
++
++save
++translate 300 300
++setRenderHint Antialiasing true
++scale 0.0001 0.00011
++drawPath bigpath
++restore
+-- 
+2.16.3
+
diff --git a/package/qt5/qt5base/0011-Improve-fix-for-avoiding-huge-number-of-tiny-dashes.patch b/package/qt5/qt5base/0011-Improve-fix-for-avoiding-huge-number-of-tiny-dashes.patch
new file mode 100644
index 0000000000..f3c525e584
--- /dev/null
+++ b/package/qt5/qt5base/0011-Improve-fix-for-avoiding-huge-number-of-tiny-dashes.patch
@@ -0,0 +1,37 @@ 
+From 9378ba2ae857df7e21a384e514650823db2355c3 Mon Sep 17 00:00:00 2001
+From: Eirik Aavitsland <eirik.aavitsland@qt.io>
+Date: Fri, 23 Jul 2021 15:53:56 +0200
+Subject: [PATCH] Improve fix for avoiding huge number of tiny dashes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+Some pathological cases were not caught by the previous fix.
+
+Fixes: QTBUG-95239
+Change-Id: I0337ee3923ff93ccb36c4d7b810a9c0667354cc5
+Reviewed-by: Robert Löhning <robert.loehning@qt.io>
+(cherry picked from commit 6b400e3147dcfd8cc3a393ace1bd118c93762e0c)
+Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
+[Upstream: https://code.qt.io/cgit/qt/qtbase.git/patch/?id=9378ba2ae857df7e21a384e514650823db2355c3 ]
+Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+---
+ src/gui/painting/qpaintengineex.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
+index f04e3a498d8..bd6bdf7be12 100644
+--- a/src/gui/painting/qpaintengineex.cpp
++++ b/src/gui/painting/qpaintengineex.cpp
+@@ -426,7 +426,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
+             patternLength *= pen.widthF();
+         if (qFuzzyIsNull(patternLength)) {
+             pen.setStyle(Qt::NoPen);
+-        } else if (extent / patternLength > 10000) {
++        } else if (qFuzzyIsNull(extent) || extent / patternLength > 10000) {
+             // approximate stream of tiny dashes with semi-transparent solid line
+             pen.setStyle(Qt::SolidLine);
+             QColor color(pen.color());
+-- 
+2.16.3
+
diff --git a/package/qt5/qt5base/qt5base.mk b/package/qt5/qt5base/qt5base.mk
index bcdf036f00..4ef3759566 100644
--- a/package/qt5/qt5base/qt5base.mk
+++ b/package/qt5/qt5base/qt5base.mk
@@ -11,6 +11,10 @@  QT5BASE_SOURCE = qtbase-$(QT5_SOURCE_TARBALL_PREFIX)-$(QT5BASE_VERSION).tar.xz
 QT5BASE_DEPENDENCIES = host-pkgconf pcre2 zlib
 QT5BASE_INSTALL_STAGING = YES
 
+# 0010-Avoid-processing-intensive-painting-of-high-number-o.patch
+# 0011-Improve-fix-for-avoiding-huge-number-of-tiny-dashes.patch
+QT5BASE_IGNORE_CVES += CVE-2021-38593
+
 # A few comments:
 #  * -no-pch to workaround the issue described at
 #     http://comments.gmane.org/gmane.comp.lib.qt.devel/5933.