93 lines
4.3 KiB
Diff
93 lines
4.3 KiB
Diff
Description: QProcess: ensure we don't accidentally execute something from CWD
|
|
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
|
|
Origin: upstream, https://download.qt.io/official_releases/qt/5.15/CVE-2022-25255-qprocess5-15.diff
|
|
Last-Update: 2022-02-21
|
|
|
|
--- 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)
|
|
@@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint
|
|
envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
|
|
}
|
|
|
|
- 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);
|
|
+ const QByteArray &tmp = QFile::encodeName(exeFilePath);
|
|
+ argv[0] = ::strdup(tmp.constData());
|
|
+ } else {
|
|
+ argv[0] = ::strdup(QFile::encodeName(program));
|
|
}
|
|
- if (tmp.isEmpty())
|
|
- tmp = QFile::encodeName(program);
|
|
- argv[0] = tmp.data();
|
|
|
|
if (envp)
|
|
qt_safe_execve(argv[0], argv, envp);
|
|
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
|
|
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
|
|
@@ -1449,7 +1449,7 @@ void tst_QApplication::desktopSettingsAw
|
|
{
|
|
#if QT_CONFIG(process)
|
|
QProcess testProcess;
|
|
- testProcess.start("desktopsettingsaware_helper");
|
|
+ testProcess.start("./desktopsettingsaware_helper");
|
|
QVERIFY2(testProcess.waitForStarted(),
|
|
qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
|
|
QVERIFY(testProcess.waitForFinished(10000));
|
|
@@ -2365,7 +2365,7 @@ void tst_QApplication::qtbug_12673()
|
|
#if QT_CONFIG(process)
|
|
QProcess testProcess;
|
|
QStringList arguments;
|
|
- testProcess.start("modal_helper", arguments);
|
|
+ testProcess.start("./modal_helper", arguments);
|
|
QVERIFY2(testProcess.waitForStarted(),
|
|
qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
|
|
QVERIFY(testProcess.waitForFinished(20000));
|