From: "Yann E. MORIN" <yann.morin.1998@free.fr>
To: Quentin Schulz <quentin.schulz@theobroma-systems.com>
Cc: Peter Seiderer <ps.report@gmx.net>,
Quentin Schulz <foss+buildroot@0leil.net>,
Julien Corjon <corjon.j@ecagroup.com>,
buildroot@buildroot.org
Subject: Re: [Buildroot] [PATCH v2] package/qt5/qt5base: fix CVE-2021-38593
Date: Fri, 21 Jan 2022 21:53:27 +0100 [thread overview]
Message-ID: <20220121205327.GK3252931@scaer> (raw)
In-Reply-To: <20220121165046.183224-1-quentin.schulz@theobroma-systems.com>
Quentin, All,
On 2022-01-21 17:50 +0100, Quentin Schulz spake thusly:
> 5.15.2 is the last public release of 5.15 and does not contain this CVE
> fix. However, >=6.1.2 and >5.12.12 all contain the necessary patches so
> let's port them to 5.15.2.
>
> Technically only the first two patches are required to patch the CVE.
> However, the second patch introduces a regression that is fixed in the third
> patch.
>
> The patches are taken from KDE kde/5.15 git branch.
>
> Cc: Quentin Schulz <foss+buildroot@0leil.net>
> Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
Applied to master, thanks.
Regards,
Yann E. MORIN.
> ---
>
> v2:
> - added third patch for fixing regression introduced by the second patch,
> - cherry-picked commits from kde git kde/5.15 branch instead of taking
> patches from 5.12.12 since they all applied nicely,
>
> ...-intensive-painting-of-high-number-o.patch | 163 ++++++++++++++++++
> ...-avoiding-huge-number-of-tiny-dashes.patch | 37 ++++
> ...-avoiding-huge-number-of-tiny-dashes.patch | 100 +++++++++++
> package/qt5/qt5base/qt5base.mk | 4 +
> 4 files changed, 304 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
> create mode 100644 package/qt5/qt5base/0012-Refix-for-avoiding-huge-number-of-tiny-dashes.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..03287d19ca
> --- /dev/null
> +++ b/package/qt5/qt5base/0010-Avoid-processing-intensive-painting-of-high-number-o.patch
> @@ -0,0 +1,163 @@
> +From 307bc02e379e63aa9b7a3d21bbcd9c84d34c600f 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.
> +
> +Pick-to: 6.1 6.0 5.15
> +Change-Id: I9e9f7861257ad5bce46a0cf113d1a9d7824911e6
> +Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
> +(cherry picked from commit f4d791b330d02777fcaf02938732892eb3167e9b)
> +
> +* asturmlechner 2021-08-21:
> +Conflict from preceding 94dd2ceb in dev branch:
> + src/gui/painting/qpaintengineex.cpp
> + Resolved via:
> +
> + if (pen.style() > Qt::SolidLine) {
> + QRectF cpRect = path.controlPointRect();
> + const QTransform &xf = state()->matrix;
> +- if (pen.isCosmetic()) {
> ++ if (qt_pen_is_cosmetic(pen, state()->renderHints)){
> + clipRect = d->exDeviceRect;
> + cpRect.translate(xf.dx(), xf.dy());
> + } else {
> +
> +FTBFS from preceding 471e4fcb in dev branch changing QVector to QList:
> + Resolved via:
> +
> + QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
> + qreal extent = qMax(extentRect.width(), extentRect.height());
> + qreal patternLength = 0;
> +- const QList<qreal> pattern = pen.dashPattern();
> ++ 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));
> +
> +[Retrieved from: https://invent.kde.org/qt/qt/qtbase/-/commit/081d835c040a90f8ee76807354355062ac521dfb]
> +Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
> +---
> + src/gui/painting/qpaintengineex.cpp | 44 +++++++++++++++----
> + .../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 5d8f89eadd..55fdb0c2a0 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);
> +
> + if (d->activeStroker == &d->stroker)
> + d->stroker.setForceOpen(path.hasExplicitOpen());
> +diff --git a/tests/auto/other/lancelot/scripts/tinydashes.qps b/tests/auto/other/lancelot/scripts/tinydashes.qps
> +new file mode 100644
> +index 0000000000..d41ced7f5f
> +--- /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.34.1
> +
> 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..16e0f20200
> --- /dev/null
> +++ b/package/qt5/qt5base/0011-Improve-fix-for-avoiding-huge-number-of-tiny-dashes.patch
> @@ -0,0 +1,37 @@
> +From 856d11f695fb6effe26a359f9ad0efdf24067085 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=UTF-8
> +Content-Transfer-Encoding: 8bit
> +
> +Some pathological cases were not caught by the previous fix.
> +
> +Fixes: QTBUG-95239
> +Pick-to: 6.2 6.1 5.15
> +Change-Id: I0337ee3923ff93ccb36c4d7b810a9c0667354cc5
> +Reviewed-by: Robert Löhning <robert.loehning@qt.io>
> +(cherry picked from commit 6b400e3147dcfd8cc3a393ace1bd118c93762e0c)
> +[Retrieved from: https://invent.kde.org/qt/qt/qtbase/-/commit/fed5713eeba5bf8e0ee413cb4e77109bfa7c2bce]
> +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 55fdb0c2a0..19e4b23423 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.34.1
> +
> diff --git a/package/qt5/qt5base/0012-Refix-for-avoiding-huge-number-of-tiny-dashes.patch b/package/qt5/qt5base/0012-Refix-for-avoiding-huge-number-of-tiny-dashes.patch
> new file mode 100644
> index 0000000000..ca3c2736ae
> --- /dev/null
> +++ b/package/qt5/qt5base/0012-Refix-for-avoiding-huge-number-of-tiny-dashes.patch
> @@ -0,0 +1,100 @@
> +From 3b1a60f651776a7b2d155803b07a52a9e27bdf78 Mon Sep 17 00:00:00 2001
> +From: Eirik Aavitsland <eirik.aavitsland@qt.io>
> +Date: Fri, 30 Jul 2021 13:03:49 +0200
> +Subject: [PATCH] Refix for avoiding huge number of tiny dashes
> +
> +Previous fix hit too widely so some valid horizontal and vertical
> +lines were affected; the root problem being that such lines have an
> +empty control point rect (width or height is 0). Fix by caculating in
> +the pen width.
> +
> +Pick-to: 6.2 6.1 5.15
> +Change-Id: I7a436e873f6d485028f6759d0e2c6456f07eebdc
> +Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
> +(cherry picked from commit 84aba80944a2e1c3058d7a1372e0e66676411884)
> +[Retrieved from: https://invent.kde.org/qt/qt/qtbase/-/commit/427df34efdcb56582a9ae9f7d2d1f39eeff70328]
> +Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
> +---
> + src/gui/painting/qpaintengineex.cpp | 8 ++---
> + .../gui/painting/qpainter/tst_qpainter.cpp | 31 +++++++++++++++++++
> + 2 files changed, 35 insertions(+), 4 deletions(-)
> +
> +diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
> +index 19e4b23423..9fe510827a 100644
> +--- a/src/gui/painting/qpaintengineex.cpp
> ++++ b/src/gui/painting/qpaintengineex.cpp
> +@@ -415,18 +415,18 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
> + 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 pw = pen.widthF() ? pen.widthF() : 1;
> ++ QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & 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();
> ++ patternLength *= pw;
> + if (qFuzzyIsNull(patternLength)) {
> + pen.setStyle(Qt::NoPen);
> +- } else if (qFuzzyIsNull(extent) || extent / patternLength > 10000) {
> ++ } else if (extent / patternLength > 10000) {
> + // approximate stream of tiny dashes with semi-transparent solid line
> + pen.setStyle(Qt::SolidLine);
> + QColor color(pen.color());
> +diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
> +index 42e98ce363..d7c3f95f1d 100644
> +--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
> ++++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
> +@@ -308,6 +308,7 @@ private slots:
> + void fillPolygon();
> +
> + void drawImageAtPointF();
> ++ void scaledDashes();
> +
> + private:
> + void fillData();
> +@@ -5468,6 +5469,36 @@ void tst_QPainter::drawImageAtPointF()
> + paint.end();
> + }
> +
> ++void tst_QPainter::scaledDashes()
> ++{
> ++ // Test that we do not hit the limit-huge-number-of-dashes path
> ++ QRgb fore = qRgb(0, 0, 0xff);
> ++ QRgb back = qRgb(0xff, 0xff, 0);
> ++ QImage image(5, 32, QImage::Format_RGB32);
> ++ image.fill(back);
> ++ QPainter p(&image);
> ++ QPen pen(QColor(fore), 3, Qt::DotLine);
> ++ p.setPen(pen);
> ++ p.scale(1, 2);
> ++ p.drawLine(2, 0, 2, 16);
> ++ p.end();
> ++
> ++ bool foreFound = false;
> ++ bool backFound = false;
> ++ int i = 0;
> ++ while (i < 32 && (!foreFound || !backFound)) {
> ++ QRgb pix = image.pixel(3, i);
> ++ if (pix == fore)
> ++ foreFound = true;
> ++ else if (pix == back)
> ++ backFound = true;
> ++ i++;
> ++ }
> ++
> ++ QVERIFY(foreFound);
> ++ QVERIFY(backFound);
> ++}
> ++
> + QTEST_MAIN(tst_QPainter)
> +
> + #include "tst_qpainter.moc"
> +--
> +2.34.1
> +
> 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.
> --
> 2.34.1
>
> _______________________________________________
> buildroot mailing list
> buildroot@buildroot.org
> https://lists.buildroot.org/mailman/listinfo/buildroot
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 561 099 427 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
next prev parent reply other threads:[~2022-01-21 20:53 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-21 16:50 [Buildroot] [PATCH v2] package/qt5/qt5base: fix CVE-2021-38593 Quentin Schulz
2022-01-21 20:53 ` Yann E. MORIN [this message]
2022-01-24 9:31 ` Quentin Schulz
2022-01-28 18:36 ` Peter Korsgaard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220121205327.GK3252931@scaer \
--to=yann.morin.1998@free.fr \
--cc=buildroot@buildroot.org \
--cc=corjon.j@ecagroup.com \
--cc=foss+buildroot@0leil.net \
--cc=ps.report@gmx.net \
--cc=quentin.schulz@theobroma-systems.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox