Fix CVE-2021-38593 and CVE-2022-25255
(cherry picked from commit fb537edb24b6d18187c0d177fd0d6c22423a70b3)
This commit is contained in:
parent
394a64ea52
commit
cbc3e7276e
84
CVE-2021-38593.patch
Normal file
84
CVE-2021-38593.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
Description: 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 individually visible
|
||||||
|
anyway, just replace with a semi-transparent solid line for such
|
||||||
|
cases.
|
||||||
|
Origin: upstream, commits:
|
||||||
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=7f345f2a1c8d9f60
|
||||||
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=9378ba2ae857df7e
|
||||||
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=81998f50d039a631
|
||||||
|
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=cca8ed0547405b1c
|
||||||
|
Last-Update: 2021-12-12
|
||||||
|
|
||||||
|
--- a/src/gui/painting/qpaintengineex.cpp
|
||||||
|
+++ b/src/gui/painting/qpaintengineex.cpp
|
||||||
|
@@ -385,10 +385,10 @@ QPainterState *QPaintEngineEx::createSta
|
||||||
|
|
||||||
|
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;
|
||||||
|
+ qDebug() << "QPaintEngineEx::stroke()" << inPen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Q_D(QPaintEngineEx);
|
||||||
|
@@ -403,6 +403,38 @@ void QPaintEngineEx::stroke(const QVecto
|
||||||
|
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
|
||||||
|
+ 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));
|
||||||
|
+ patternLength *= pw;
|
||||||
|
+ 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 QVecto
|
||||||
|
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();
|
||||||
219
CVE-2022-25255.patch
Normal file
219
CVE-2022-25255.patch
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
From ab3e0383b9de49c61bc49f5fbef80d1409fcafde Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thiago Macieira <thiago.macieira@intel.com>
|
||||||
|
Date: Mon, 31 Jan 2022 11:00:19 -0800
|
||||||
|
Subject: [PATCH] QProcess/Unix: ensure we don't accidentally execute something
|
||||||
|
from CWD
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Unless "." (or the empty string) is in $PATH, we're not supposed to find
|
||||||
|
executables in the current directory. This is how the Unix shells behave
|
||||||
|
and we match their behavior. It's also the behavior Qt had prior to 5.9
|
||||||
|
(commit 28666d167aa8e602c0bea25ebc4d51b55005db13). On Windows, searching
|
||||||
|
the current directory is the norm, so we keep that behavior.
|
||||||
|
|
||||||
|
This commit does not add an explicit check for an empty return from
|
||||||
|
QStandardPaths::findExecutable(). Instead, we allow that empty string to
|
||||||
|
go all the way to execve(2), which will fail with ENOENT. We could catch
|
||||||
|
it early, before fork(2), but why add code for the error case?
|
||||||
|
|
||||||
|
See https://kde.org/info/security/advisory-20220131-1.txt
|
||||||
|
|
||||||
|
[ChangeLog][Important Behavior Changes] When passed a simple program
|
||||||
|
name with no slashes, QProcess on Unix systems will now only search the
|
||||||
|
current directory if "." is one of the entries in the PATH environment
|
||||||
|
variable. This bug fix restores the behavior QProcess had before Qt 5.9.
|
||||||
|
If launching an executable in the directory set by setWorkingDirectory()
|
||||||
|
or inherited from the parent is intended, pass a program name starting
|
||||||
|
with "./". For more information and best practices about finding an
|
||||||
|
executable, see QProcess' documentation.
|
||||||
|
|
||||||
|
Pick-to: 5.15 6.2 6.3
|
||||||
|
Change-Id: I54f205f6b7314351b078fffd16cf7013c97ee9fb
|
||||||
|
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
|
||||||
|
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
|
||||||
|
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
|
||||||
|
(cherry picked from commit 29fceed2ffb41954a63001414bd042611f2d4980)
|
||||||
|
|
||||||
|
Note: This currently breaks various autotests, as they rely on the test
|
||||||
|
helpers (same directory as the test) to be in $PATH. In Qt 6, the CMake
|
||||||
|
test code sets this explicitly, which is not the case in Qt 5 (yet).
|
||||||
|
---
|
||||||
|
src/corelib/io/qprocess_unix.cpp | 24 ++---
|
||||||
|
.../auto/corelib/io/qprocess/tst_qprocess.cpp | 93 ++++++++++++++++++-
|
||||||
|
.../kernel/qapplication/tst_qapplication.cpp | 4 +-
|
||||||
|
3 files changed, 107 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
|
||||||
|
index 50390e57f5..5bd3b7f297 100644
|
||||||
|
--- a/src/corelib/io/qprocess_unix.cpp
|
||||||
|
+++ b/src/corelib/io/qprocess_unix.cpp
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
-** Copyright (C) 2016 Intel Corporation.
|
||||||
|
+** Copyright (C) 2022 Intel Corporation.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
|
@@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
|
||||||
|
// Add the program name to the argument list.
|
||||||
|
argv[0] = nullptr;
|
||||||
|
if (!program.contains(QLatin1Char('/'))) {
|
||||||
|
+ // findExecutable() returns its argument if it's an absolute path,
|
||||||
|
+ // otherwise it searches $PATH; returns empty if not found (we handle
|
||||||
|
+ // that case much later)
|
||||||
|
const QString &exeFilePath = QStandardPaths::findExecutable(program);
|
||||||
|
- if (!exeFilePath.isEmpty()) {
|
||||||
|
- const QByteArray &tmp = QFile::encodeName(exeFilePath);
|
||||||
|
- argv[0] = ::strdup(tmp.constData());
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- if (!argv[0])
|
||||||
|
+ const QByteArray &tmp = QFile::encodeName(exeFilePath);
|
||||||
|
+ argv[0] = ::strdup(tmp.constData());
|
||||||
|
+ } else {
|
||||||
|
argv[0] = ::strdup(encodedProgramName.constData());
|
||||||
|
+ }
|
||||||
|
|
||||||
|
// Add every argument to the list
|
||||||
|
for (int i = 0; i < arguments.count(); ++i)
|
||||||
|
@@ -985,11 +986,12 @@ bool QProcessPrivate::startDetached(qint64 *pid)
|
||||||
|
|
||||||
|
QByteArray tmp;
|
||||||
|
if (!program.contains(QLatin1Char('/'))) {
|
||||||
|
+ // findExecutable() returns its argument if it's an absolute path,
|
||||||
|
+ // otherwise it searches $PATH; returns empty if not found (we handle
|
||||||
|
+ // that case much later)
|
||||||
|
const QString &exeFilePath = QStandardPaths::findExecutable(program);
|
||||||
|
- if (!exeFilePath.isEmpty())
|
||||||
|
- tmp = QFile::encodeName(exeFilePath);
|
||||||
|
- }
|
||||||
|
- if (tmp.isEmpty())
|
||||||
|
+ tmp = QFile::encodeName(exeFilePath);
|
||||||
|
+ } else
|
||||||
|
tmp = QFile::encodeName(program);
|
||||||
|
argv[0] = tmp.data();
|
||||||
|
|
||||||
|
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
|
||||||
|
index bc9df3f1f3..33051d3803 100644
|
||||||
|
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
|
||||||
|
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
-** Copyright (C) 2016 Intel Corporation.
|
||||||
|
+** Copyright (C) 2022 Intel Corporation.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
|
@@ -149,6 +149,8 @@ private slots:
|
||||||
|
void startStopStartStopBuffers();
|
||||||
|
void processEventsInAReadyReadSlot_data();
|
||||||
|
void processEventsInAReadyReadSlot();
|
||||||
|
+ void startFromCurrentWorkingDir_data();
|
||||||
|
+ void startFromCurrentWorkingDir();
|
||||||
|
|
||||||
|
// keep these at the end, since they use lots of processes and sometimes
|
||||||
|
// caused obscure failures to occur in tests that followed them (esp. on the Mac)
|
||||||
|
@@ -2732,5 +2734,94 @@ void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
|
||||||
|
QVERIFY(process.waitForFinished());
|
||||||
|
}
|
||||||
|
|
||||||
|
+enum class ChdirMode {
|
||||||
|
+ None = 0,
|
||||||
|
+ InParent,
|
||||||
|
+ InChild
|
||||||
|
+};
|
||||||
|
+Q_DECLARE_METATYPE(ChdirMode)
|
||||||
|
+
|
||||||
|
+void tst_QProcess::startFromCurrentWorkingDir_data()
|
||||||
|
+{
|
||||||
|
+ qRegisterMetaType<ChdirMode>();
|
||||||
|
+ QTest::addColumn<QString>("programPrefix");
|
||||||
|
+ QTest::addColumn<ChdirMode>("chdirMode");
|
||||||
|
+ QTest::addColumn<bool>("success");
|
||||||
|
+
|
||||||
|
+ constexpr bool IsWindows = true
|
||||||
|
+#ifdef Q_OS_UNIX
|
||||||
|
+ && false
|
||||||
|
+#endif
|
||||||
|
+ ;
|
||||||
|
+
|
||||||
|
+ // baseline: trying to execute the directory, this can't possibly succeed!
|
||||||
|
+ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
|
||||||
|
+
|
||||||
|
+ // cross-platform behavior: neither OS searches the setWorkingDirectory()
|
||||||
|
+ // dir without "./"
|
||||||
|
+ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
|
||||||
|
+
|
||||||
|
+ // cross-platform behavior: both OSes search the parent's CWD with "./"
|
||||||
|
+ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
|
||||||
|
+
|
||||||
|
+ // opposite behaviors: Windows searches the parent's CWD and Unix searches
|
||||||
|
+ // the child's with "./"
|
||||||
|
+ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
|
||||||
|
+
|
||||||
|
+ // Windows searches the parent's CWD without "./"
|
||||||
|
+ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void tst_QProcess::startFromCurrentWorkingDir()
|
||||||
|
+{
|
||||||
|
+ QFETCH(QString, programPrefix);
|
||||||
|
+ QFETCH(ChdirMode, chdirMode);
|
||||||
|
+ QFETCH(bool, success);
|
||||||
|
+
|
||||||
|
+ QProcess process;
|
||||||
|
+ qRegisterMetaType<QProcess::ProcessError>();
|
||||||
|
+ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
|
||||||
|
+ QVERIFY(errorSpy.isValid());
|
||||||
|
+
|
||||||
|
+ // both the dir name and the executable name
|
||||||
|
+ const QString target = QStringLiteral("testProcessNormal");
|
||||||
|
+ process.setProgram(programPrefix + target);
|
||||||
|
+
|
||||||
|
+#ifdef Q_OS_UNIX
|
||||||
|
+ // Reset PATH, to be sure it doesn't contain . or the empty path.
|
||||||
|
+ // We can't do this on Windows because DLLs are searched in PATH
|
||||||
|
+ // and Windows always searches "." anyway.
|
||||||
|
+ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
|
||||||
|
+ qputenv("PATH", old);
|
||||||
|
+ });
|
||||||
|
+ qputenv("PATH", "/");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ switch (chdirMode) {
|
||||||
|
+ case ChdirMode::InParent: {
|
||||||
|
+ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
|
||||||
|
+ QDir::setCurrent(old);
|
||||||
|
+ });
|
||||||
|
+ QVERIFY(QDir::setCurrent(target));
|
||||||
|
+ process.start();
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ case ChdirMode::InChild:
|
||||||
|
+ process.setWorkingDirectory(target);
|
||||||
|
+ Q_FALLTHROUGH();
|
||||||
|
+ case ChdirMode::None:
|
||||||
|
+ process.start();
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ QCOMPARE(process.waitForStarted(), success);
|
||||||
|
+ QCOMPARE(errorSpy.count(), int(!success));
|
||||||
|
+ if (success) {
|
||||||
|
+ QVERIFY(process.waitForFinished());
|
||||||
|
+ } else {
|
||||||
|
+ QCOMPARE(process.error(), QProcess::FailedToStart);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
QTEST_MAIN(tst_QProcess)
|
||||||
|
#include "tst_qprocess.moc"
|
||||||
|
--
|
||||||
|
2.34.0
|
||||||
|
|
||||||
@ -13,7 +13,7 @@
|
|||||||
Name: qt5-qtbase
|
Name: qt5-qtbase
|
||||||
Summary: Core component of Qt toolkit
|
Summary: Core component of Qt toolkit
|
||||||
Version: 5.11.1
|
Version: 5.11.1
|
||||||
Release: 12
|
Release: 13
|
||||||
License: LGPLv2 with exceptions or GPLv3 with exceptions
|
License: LGPLv2 with exceptions or GPLv3 with exceptions
|
||||||
Url: http://qt-project.org/
|
Url: http://qt-project.org/
|
||||||
Source0: https://download.qt.io/new_archive/qt/5.11/%{version}/submodules/qtbase-everywhere-src-%{version}.tar.xz
|
Source0: https://download.qt.io/new_archive/qt/5.11/%{version}/submodules/qtbase-everywhere-src-%{version}.tar.xz
|
||||||
@ -37,6 +37,10 @@ Patch0011: qt5-qtbase-glibc.patch
|
|||||||
Patch6000: CVE-2018-15518.patch
|
Patch6000: CVE-2018-15518.patch
|
||||||
Patch6001: CVE-2015-9541.patch
|
Patch6001: CVE-2015-9541.patch
|
||||||
Patch6002: CVE-2019-18281.patch
|
Patch6002: CVE-2019-18281.patch
|
||||||
|
# https://launchpad.net/ubuntu/+source/qtbase-opensource-src/5.12.8+dfsg-0ubuntu2.1
|
||||||
|
Patch6003: CVE-2021-38593.patch
|
||||||
|
# https://build.opensuse.org/package/view_file/SUSE:SLE-15-SP3:Update/libqt5-qtbase/0001-QProcess-Unix-ensure-we-don-t-accidentally-execute-s.patch?expand=1
|
||||||
|
Patch6004: CVE-2022-25255.patch
|
||||||
|
|
||||||
BuildRequires: pkgconfig(libsystemd) cups-devel desktop-file-utils findutils
|
BuildRequires: pkgconfig(libsystemd) cups-devel desktop-file-utils findutils
|
||||||
BuildRequires: libjpeg-devel libmng-devel libtiff-devel pkgconfig(alsa)
|
BuildRequires: libjpeg-devel libmng-devel libtiff-devel pkgconfig(alsa)
|
||||||
@ -403,6 +407,9 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jul 26 2022 wangkai <wangkai385@h-partners.com> - 5.11.1-13
|
||||||
|
- Fix CVE-2021-38593 and CVE-2022-25255
|
||||||
|
|
||||||
* Thu Apr 22 2021 wangyue <wangyue92@huawei.com> - 5.11.1-12
|
* Thu Apr 22 2021 wangyue <wangyue92@huawei.com> - 5.11.1-12
|
||||||
- fix CVE-2019-18281
|
- fix CVE-2019-18281
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user