From d21653e8cf13d37bac5066aaf830d958b2c340c9 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sun, 23 Mar 2025 14:48:21 +0800 Subject: [PATCH] Don't leak parent file descriptors to child processes It is unexpected for the child process to inherit parent file descriptors. Requires Qt >= 6.6 and only affects Linux. Closes #10312. PR #22457. --- src/app/application.cpp | 3 +++ src/base/search/searchdownloadhandler.cpp | 3 +++ src/base/search/searchhandler.cpp | 8 +++++--- src/base/search/searchpluginmanager.cpp | 3 +++ src/base/utils/foreignapps.cpp | 3 +++ src/gui/utils.cpp | 3 +++ 6 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/app/application.cpp b/src/app/application.cpp index 82bcead85..69d8af646 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -674,6 +674,9 @@ void Application::runExternalProgram(const QString &programTemplate, const BitTo QProcess proc; proc.setProgram(command); proc.setArguments(args); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + proc.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); +#endif if (proc.startDetached()) { diff --git a/src/base/search/searchdownloadhandler.cpp b/src/base/search/searchdownloadhandler.cpp index 436637183..4614c7f34 100644 --- a/src/base/search/searchdownloadhandler.cpp +++ b/src/base/search/searchdownloadhandler.cpp @@ -42,6 +42,9 @@ SearchDownloadHandler::SearchDownloadHandler(const QString &pluginName, const QS , m_downloadProcess {new QProcess(this)} { m_downloadProcess->setEnvironment(QProcess::systemEnvironment()); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + m_downloadProcess->setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); +#endif connect(m_downloadProcess, qOverload(&QProcess::finished) , this, &SearchDownloadHandler::downloadProcessFinished); const QStringList params diff --git a/src/base/search/searchhandler.cpp b/src/base/search/searchhandler.cpp index fa43ef880..e5e792bd7 100644 --- a/src/base/search/searchhandler.cpp +++ b/src/base/search/searchhandler.cpp @@ -71,6 +71,10 @@ SearchHandler::SearchHandler(const QString &pattern, const QString &category, co { // Load environment variables (proxy) m_searchProcess->setEnvironment(QProcess::systemEnvironment()); + m_searchProcess->setProgram(Utils::ForeignApps::pythonInfo().executableName); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + m_searchProcess->setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); +#endif const QStringList params { @@ -79,9 +83,6 @@ SearchHandler::SearchHandler(const QString &pattern, const QString &category, co m_usedPlugins.join(u','), m_category }; - - // Launch search - m_searchProcess->setProgram(Utils::ForeignApps::pythonInfo().executableName); m_searchProcess->setArguments(params + m_pattern.split(u' ')); connect(m_searchProcess, &QProcess::errorOccurred, this, &SearchHandler::processFailed); @@ -93,6 +94,7 @@ SearchHandler::SearchHandler(const QString &pattern, const QString &category, co connect(m_searchTimeout, &QTimer::timeout, this, &SearchHandler::cancelSearch); m_searchTimeout->start(3min); + // Launch search // deferred start allows clients to handle starting-related signals QMetaObject::invokeMethod(this, [this]() { m_searchProcess->start(QIODevice::ReadOnly); } , Qt::QueuedConnection); diff --git a/src/base/search/searchpluginmanager.cpp b/src/base/search/searchpluginmanager.cpp index 477a0cec2..ec1f1375b 100644 --- a/src/base/search/searchpluginmanager.cpp +++ b/src/base/search/searchpluginmanager.cpp @@ -520,6 +520,9 @@ void SearchPluginManager::update() { QProcess nova; nova.setProcessEnvironment(QProcessEnvironment::systemEnvironment()); +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + nova.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); +#endif const QStringList params { diff --git a/src/base/utils/foreignapps.cpp b/src/base/utils/foreignapps.cpp index f255a5607..038d5128f 100644 --- a/src/base/utils/foreignapps.cpp +++ b/src/base/utils/foreignapps.cpp @@ -57,6 +57,9 @@ namespace info = {}; QProcess proc; +#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + proc.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); +#endif proc.start(exeName, {u"--version"_s}, QIODevice::ReadOnly); if (proc.waitForFinished() && (proc.exitCode() == QProcess::NormalExit)) { diff --git a/src/gui/utils.cpp b/src/gui/utils.cpp index c14bb4ed1..ac5d922dc 100644 --- a/src/gui/utils.cpp +++ b/src/gui/utils.cpp @@ -176,6 +176,9 @@ void Utils::Gui::openFolderSelect(const Path &path) const int lineMaxLength = 64; QProcess proc; +#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) + proc.setUnixProcessParameters(QProcess::UnixProcessFlag::CloseFileDescriptors); +#endif proc.start(u"xdg-mime"_s, {u"query"_s, u"default"_s, u"inode/directory"_s}); proc.waitForFinished(); const auto output = QString::fromLocal8Bit(proc.readLine(lineMaxLength).simplified());