diff --git a/docs/manual/gammaray-advanced-usage.qdoc b/docs/manual/gammaray-advanced-usage.qdoc index b19c04018b..ad618e6641 100644 --- a/docs/manual/gammaray-advanced-usage.qdoc +++ b/docs/manual/gammaray-advanced-usage.qdoc @@ -66,4 +66,15 @@ For more details on how to integrate the GammaRay client with and IDE, please see the \l{https://docs.kdab.com/gammaray/latest/}{API documentation}. + + \section1 Working around \c{ld.so} secure-execution mode (Linux only) + + If your environment triggers the dynamic linker's secure-execution + mode, then the default \c{preload} injector will fail. In that + case, you can copy or link \c{gammaray_probe.so} into a standard + search directory (eg. \c{/usr/lib}), enable the set-user-ID mode + bit (eg. \c{chmod u+s /usr/lib/gammaray_probe.so}), and finally + use the \c{--injector-override gammaray_probe.so} + + For more information about \c{ld.so}'s secure mode, see the \l{http://man7.org/linux/man-pages/man8/ld.so.8.html#ENVIRONMENT}{man page} */ diff --git a/docs/manual/gammaray-command-line.qdoc b/docs/manual/gammaray-command-line.qdoc index 2cb304dc8f..d167675928 100644 --- a/docs/manual/gammaray-command-line.qdoc +++ b/docs/manual/gammaray-command-line.qdoc @@ -56,6 +56,9 @@ \row \li \c -i, \c --injector \c \li Specify injector type to use (see below). + \row + \li \c -o, \c --injector-override \c + \li Override the injector executable if handled (requires \c{-i/--injector}) \row \li \c --inprocess \li Use the Gammaray 1.x in-process UI. This is not necessary in most cases, diff --git a/launcher/core/injector/injectorfactory.cpp b/launcher/core/injector/injectorfactory.cpp index 26bf4b875a..264b4b7980 100644 --- a/launcher/core/injector/injectorfactory.cpp +++ b/launcher/core/injector/injectorfactory.cpp @@ -62,7 +62,7 @@ AbstractInjector::Ptr createInjector(const QString &name, const QString &executa #ifndef Q_OS_WIN if (name == QLatin1String("preload")) { - return AbstractInjector::Ptr(new PreloadInjector); + return AbstractInjector::Ptr(new PreloadInjector(executableOverride)); } #else if (name == QLatin1String("windll")) { diff --git a/launcher/core/injector/preloadinjector.cpp b/launcher/core/injector/preloadinjector.cpp index ec2b1bc1ad..26630a35cd 100644 --- a/launcher/core/injector/preloadinjector.cpp +++ b/launcher/core/injector/preloadinjector.cpp @@ -39,7 +39,11 @@ using namespace GammaRay; -PreloadInjector::PreloadInjector() = default; +PreloadInjector::PreloadInjector(const QString &probeDllOverride) + : ProcessInjector() + , m_probeDllOverride(probeDllOverride) +{ +} QString PreloadInjector::name() const { @@ -51,13 +55,15 @@ bool PreloadInjector::launch(const QStringList &programAndArgs, const QString &p { Q_UNUSED(probeFunc); + const QString actualProbeDll = m_probeDllOverride.isEmpty() ? probeDll : m_probeDllOverride; + QProcessEnvironment env(_env); #ifdef Q_OS_MAC - env.insert(QStringLiteral("DYLD_INSERT_LIBRARIES"), probeDll); + env.insert(QStringLiteral("DYLD_INSERT_LIBRARIES"), actualProbeDll); env.insert(QStringLiteral("GAMMARAY_UNSET_DYLD"), QStringLiteral("1")); // Make sure Qt do load it's correct libs/plugins. - if (probeDll.contains(QStringLiteral("_debug"), Qt::CaseInsensitive)) + if (actualProbeDll.contains(QStringLiteral("_debug"), Qt::CaseInsensitive)) env.insert(QStringLiteral("DYLD_IMAGE_SUFFIX"), QStringLiteral("_debug")); #else @@ -68,13 +74,13 @@ bool PreloadInjector::launch(const QStringList &programAndArgs, const QString &p // ASAN requires to be loaded first, so check if the target uses that // and if so inject it before GammaRay QStringList ldPreload; - foreach (const auto &lib, LibraryUtil::dependencies(exePath)) { + for (const auto &lib: LibraryUtil::dependencies(exePath)) { if (lib.contains("libasan.so") || lib.contains("libclang_rt.asan")) { ldPreload.push_back(QString::fromLocal8Bit(lib)); break; } } - ldPreload.push_back(probeDll); + ldPreload.push_back(actualProbeDll); env.insert(QStringLiteral("LD_PRELOAD"), ldPreload.join(QLatin1String(":"))); env.insert(QStringLiteral("GAMMARAY_UNSET_PRELOAD"), QStringLiteral("1")); diff --git a/launcher/core/injector/preloadinjector.h b/launcher/core/injector/preloadinjector.h index 34daf5d78b..6f366bfe12 100644 --- a/launcher/core/injector/preloadinjector.h +++ b/launcher/core/injector/preloadinjector.h @@ -37,10 +37,13 @@ class PreloadInjector : public ProcessInjector { Q_OBJECT public: - PreloadInjector(); + PreloadInjector(const QString &probeDllOverride = QString()); QString name() const override; bool launch(const QStringList &programAndArgs, const QString &probeDll, const QString &probeFunc, const QProcessEnvironment &_env) override; + +private: + const QString m_probeDllOverride; }; }