Fix running as root

There is no need for TerminalRunner::setRunAsRoot()
as debugger is already being run as root.
Implement runAsRoot for non-terminal QtcProcess, too.

Fixes: QTCREATORBUG-26964
Change-Id: Id5110db86b7b809a5608714464241cee73875f2b
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2022-02-01 14:51:23 +01:00
parent 2be0fc2537
commit 239688180d
9 changed files with 62 additions and 77 deletions

View File

@@ -263,9 +263,6 @@ public:
void setAbortOnMetaChars(bool abort) { m_abortOnMetaChars = abort; } void setAbortOnMetaChars(bool abort) { m_abortOnMetaChars = abort; }
bool isAbortOnMetaChars() const { return m_abortOnMetaChars; } bool isAbortOnMetaChars() const { return m_abortOnMetaChars; }
void setRunAsRoot(bool on) { m_runAsRoot = on; }
bool runAsRoot() const { return m_runAsRoot; }
void setBelowNormalPriority() { m_belowNormalPriority = true; } void setBelowNormalPriority() { m_belowNormalPriority = true; }
bool isBelowNormalPriority() const { return m_belowNormalPriority; } bool isBelowNormalPriority() const { return m_belowNormalPriority; }
void setNativeArguments(const QString &arguments) { m_nativeArguments = arguments; } void setNativeArguments(const QString &arguments) { m_nativeArguments = arguments; }
@@ -287,7 +284,6 @@ private:
bool m_lowPriority = false; bool m_lowPriority = false;
bool m_unixTerminalDisabled = false; bool m_unixTerminalDisabled = false;
bool m_abortOnMetaChars = true; bool m_abortOnMetaChars = true;
bool m_runAsRoot = false;
}; };
class TerminalImpl : public ProcessInterface class TerminalImpl : public ProcessInterface
@@ -319,7 +315,6 @@ public:
void customStart(const CommandLine &command, const FilePath &workingDirectory, void customStart(const CommandLine &command, const FilePath &workingDirectory,
const Environment &environment) override const Environment &environment) override
{ {
m_terminal.setRunAsRoot(runAsRoot());
m_terminal.setAbortOnMetaChars(isAbortOnMetaChars()); m_terminal.setAbortOnMetaChars(isAbortOnMetaChars());
m_terminal.setCommand(command); m_terminal.setCommand(command);
m_terminal.setWorkingDirectory(workingDirectory); m_terminal.setWorkingDirectory(workingDirectory);
@@ -606,11 +601,10 @@ public:
return filePath.searchInPath(); return filePath.searchInPath();
} }
void defaultStart() void defaultStart(const CommandLine &commandLine, const FilePath &workingDirectory,
const Environment &environment)
{ {
clearForRun(); if (commandLine.executable().needsDevice()) {
if (m_commandLine.executable().needsDevice()) {
QTC_ASSERT(s_deviceHooks.startProcessHook, return); QTC_ASSERT(s_deviceHooks.startProcessHook, return);
s_deviceHooks.startProcessHook(*q); s_deviceHooks.startProcessHook(*q);
return; return;
@@ -618,33 +612,24 @@ public:
if (processLog().isDebugEnabled()) { if (processLog().isDebugEnabled()) {
static int n = 0; static int n = 0;
qCDebug(processLog) << "STARTING PROCESS: " << ++n << " " << m_commandLine.toUserOutput(); qCDebug(processLog) << "STARTING PROCESS: " << ++n << " " << commandLine.toUserOutput();
} }
Environment env; m_process->setProcessEnvironment(environment.toProcessEnvironment());
if (m_haveEnv) { m_process->setWorkingDirectory(workingDirectory.path());
if (m_environment.size() == 0)
qWarning("QtcProcess::start: Empty environment set when running '%s'.",
qPrintable(m_commandLine.executable().toString()));
env = m_environment;
} else {
env = Environment::systemEnvironment();
}
m_process->setProcessEnvironment(env.toProcessEnvironment());
m_process->setWorkingDirectory(m_workingDirectory.path());
QString command; QString commandString;
ProcessArgs arguments; ProcessArgs arguments;
const bool success = ProcessArgs::prepareCommand(m_commandLine, &command, &arguments, &env, const bool success = ProcessArgs::prepareCommand(commandLine, &commandString, &arguments,
&m_workingDirectory); &environment, &workingDirectory);
if (m_commandLine.executable().osType() == OsTypeWindows) { if (commandLine.executable().osType() == OsTypeWindows) {
QString args; QString args;
if (m_useCtrlCStub) { if (m_useCtrlCStub) {
if (m_process->isLowPriority()) if (m_process->isLowPriority())
ProcessArgs::addArg(&args, "-nice"); ProcessArgs::addArg(&args, "-nice");
ProcessArgs::addArg(&args, QDir::toNativeSeparators(command)); ProcessArgs::addArg(&args, QDir::toNativeSeparators(commandString));
command = QCoreApplication::applicationDirPath() commandString = QCoreApplication::applicationDirPath()
+ QLatin1String("/qtcreator_ctrlc_stub.exe"); + QLatin1String("/qtcreator_ctrlc_stub.exe");
} else if (m_process->isLowPriority()) { } else if (m_process->isLowPriority()) {
m_process->setBelowNormalPriority(); m_process->setBelowNormalPriority();
@@ -655,7 +640,7 @@ public:
#endif #endif
// Note: Arguments set with setNativeArgs will be appended to the ones // Note: Arguments set with setNativeArgs will be appended to the ones
// passed with start() below. // passed with start() below.
start(command, QStringList(), m_writeData); start(commandString, QStringList(), workingDirectory, m_writeData);
} else { } else {
if (!success) { if (!success) {
q->setErrorString(tr("Error in command line.")); q->setErrorString(tr("Error in command line."));
@@ -664,13 +649,14 @@ public:
emit q->errorOccurred(QProcess::UnknownError); emit q->errorOccurred(QProcess::UnknownError);
return; return;
} }
start(command, arguments.toUnixArgs(), m_writeData); start(commandString, arguments.toUnixArgs(), workingDirectory, m_writeData);
} }
} }
void start(const QString &program, const QStringList &arguments, const QByteArray &writeData) void start(const QString &program, const QStringList &arguments,
const FilePath &workingDirectory, const QByteArray &writeData)
{ {
const FilePath programFilePath = resolve(m_workingDirectory, FilePath::fromString(program)); const FilePath programFilePath = resolve(workingDirectory, FilePath::fromString(program));
if (programFilePath.exists() && programFilePath.isExecutableFile()) { if (programFilePath.exists() && programFilePath.isExecutableFile()) {
s_start.measureAndRun(&ProcessInterface::start, m_process, program, arguments, writeData); s_start.measureAndRun(&ProcessInterface::start, m_process, program, arguments, writeData);
} else { } else {
@@ -680,6 +666,33 @@ public:
} }
} }
CommandLine fullCommandLine() const
{
if (!m_runAsRoot || HostOsInfo::isWindowsHost())
return m_commandLine;
CommandLine rootCommand("sudo", {"-A"});
rootCommand.addCommandLineAsArgs(m_commandLine);
return rootCommand;
}
Environment fullEnvironment() const
{
Environment env;
if (m_haveEnv) {
if (m_environment.size() == 0)
qWarning("QtcProcess::start: Empty environment set when running '%s'.",
qPrintable(m_commandLine.executable().toString()));
env = m_environment;
} else {
env = Environment::systemEnvironment();
}
// TODO: needs SshSettings
// if (m_runAsRoot)
// RunControl::provideAskPassEntry(env);
return env;
}
QtcProcess *q; QtcProcess *q;
ProcessInterface *m_process; ProcessInterface *m_process;
const ProcessMode m_processMode; const ProcessMode m_processMode;
@@ -687,6 +700,7 @@ public:
FilePath m_workingDirectory; FilePath m_workingDirectory;
Environment m_environment; Environment m_environment;
QByteArray m_writeData; QByteArray m_writeData;
bool m_runAsRoot = false;
bool m_haveEnv = false; bool m_haveEnv = false;
bool m_useCtrlCStub = false; bool m_useCtrlCStub = false;
@@ -831,10 +845,13 @@ void QtcProcess::setUseCtrlCStub(bool enabled)
void QtcProcess::start() void QtcProcess::start()
{ {
d->clearForRun();
const CommandLine cmd = d->fullCommandLine();
const Environment env = d->fullEnvironment();
if (d->m_process->isCustomStart()) if (d->m_process->isCustomStart())
d->m_process->customStart(d->m_commandLine, d->m_workingDirectory, d->m_environment); d->m_process->customStart(cmd, d->m_workingDirectory, env);
else else
d->defaultStart(); d->defaultStart(cmd, d->m_workingDirectory, env);
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@@ -905,7 +922,12 @@ void QtcProcess::setAbortOnMetaChars(bool abort)
void QtcProcess::setRunAsRoot(bool on) void QtcProcess::setRunAsRoot(bool on)
{ {
d->m_process->setRunAsRoot(on); d->m_runAsRoot = on;
}
bool QtcProcess::isRunAsRoot() const
{
return d->m_runAsRoot;
} }
void QtcProcess::setStandardInputFile(const QString &inputFile) void QtcProcess::setStandardInputFile(const QString &inputFile)

View File

@@ -122,6 +122,7 @@ public:
void setLowPriority(); void setLowPriority();
void setDisableUnixTerminal(); void setDisableUnixTerminal();
void setRunAsRoot(bool on); void setRunAsRoot(bool on);
bool isRunAsRoot() const;
void setAbortOnMetaChars(bool abort); void setAbortOnMetaChars(bool abort);

View File

@@ -142,7 +142,6 @@ public:
QProcess::ProcessError m_error = QProcess::UnknownError; QProcess::ProcessError m_error = QProcess::UnknownError;
QString m_errorString; QString m_errorString;
bool m_abortOnMetaChars = true; bool m_abortOnMetaChars = true;
bool m_runAsRoot = false;
// Used on Unix only // Used on Unix only
QtcProcess m_process; QtcProcess m_process;
@@ -431,8 +430,6 @@ void TerminalProcess::start()
+ QLatin1String("/" RELATIVE_LIBEXEC_PATH "/qtcreator_process_stub"); + QLatin1String("/" RELATIVE_LIBEXEC_PATH "/qtcreator_process_stub");
QStringList allArgs = terminalArgs.toUnixArgs(); QStringList allArgs = terminalArgs.toUnixArgs();
if (d->m_runAsRoot)
allArgs << "sudo" << "-A";
allArgs << stubPath allArgs << stubPath
<< modeOption(d->m_terminalMode) << modeOption(d->m_terminalMode)
@@ -797,11 +794,6 @@ const Environment &TerminalProcess::environment() const
return d->m_environment; return d->m_environment;
} }
void TerminalProcess::setRunAsRoot(bool on)
{
d->m_runAsRoot = on;
}
QProcess::ProcessError TerminalProcess::error() const QProcess::ProcessError TerminalProcess::error() const
{ {
return d->m_error; return d->m_error;

View File

@@ -52,8 +52,6 @@ public:
void setEnvironment(const Environment &env); void setEnvironment(const Environment &env);
const Environment &environment() const; const Environment &environment() const;
void setRunAsRoot(bool on);
QProcess::ProcessError error() const; QProcess::ProcessError error() const;
QString errorString() const; QString errorString() const;

View File

@@ -316,7 +316,6 @@ void DebuggerRunTool::setUseTerminal(bool on)
if (on && !d->terminalRunner && !useCdbConsole) { if (on && !d->terminalRunner && !useCdbConsole) {
d->terminalRunner = d->terminalRunner =
new TerminalRunner(runControl(), [this] { return m_runParameters.inferior; }); new TerminalRunner(runControl(), [this] { return m_runParameters.inferior; });
d->terminalRunner->setRunAsRoot(m_runParameters.runAsRoot);
addStartDependency(d->terminalRunner); addStartDependency(d->terminalRunner);
} }
if (!on && d->terminalRunner) { if (!on && d->terminalRunner) {
@@ -327,8 +326,6 @@ void DebuggerRunTool::setUseTerminal(bool on)
void DebuggerRunTool::setRunAsRoot(bool on) void DebuggerRunTool::setRunAsRoot(bool on)
{ {
m_runParameters.runAsRoot = on; m_runParameters.runAsRoot = on;
if (d->terminalRunner)
d->terminalRunner->setRunAsRoot(on);
} }
void DebuggerRunTool::setCommandsAfterConnect(const QString &commands) void DebuggerRunTool::setCommandsAfterConnect(const QString &commands)

View File

@@ -3852,12 +3852,9 @@ void GdbEngine::setupEngine()
Environment gdbEnv = rp.debugger.environment; Environment gdbEnv = rp.debugger.environment;
gdbEnv.setupEnglishOutput(); gdbEnv.setupEnglishOutput();
if (rp.runAsRoot) { if (rp.runAsRoot)
CommandLine wrapped("sudo", {"-A"});
wrapped.addCommandLineAsArgs(gdbCommand);
gdbCommand = wrapped;
RunControl::provideAskPassEntry(gdbEnv); RunControl::provideAskPassEntry(gdbEnv);
} m_gdbProc.setRunAsRoot(rp.runAsRoot);
showMessage("STARTING " + gdbCommand.toUserOutput()); showMessage("STARTING " + gdbCommand.toUserOutput());

View File

@@ -188,11 +188,6 @@ void TerminalRunner::interruptProcess()
m_stubProc->interruptProcess(); m_stubProc->interruptProcess();
} }
void TerminalRunner::setRunAsRoot(bool on)
{
m_runAsRoot = on;
}
void TerminalRunner::start() void TerminalRunner::start()
{ {
QTC_ASSERT(m_stubRunnable, reportFailure({}); return); QTC_ASSERT(m_stubRunnable, reportFailure({}); return);
@@ -209,20 +204,11 @@ void TerminalRunner::start()
connect(m_stubProc, &QtcProcess::finished, connect(m_stubProc, &QtcProcess::finished,
this, &TerminalRunner::reportDone); this, &TerminalRunner::reportDone);
CommandLine commandLine = stub.command;
if (m_runAsRoot) { // TODO: fix me
m_stubProc->setRunAsRoot(true);
// CommandLine wrapped("sudo", {"-A"});
// wrapped.addCommandLineAsArgs(commandLine);
// commandLine = wrapped;
RunControl::provideAskPassEntry(stub.environment);
}
m_stubProc->setEnvironment(stub.environment); m_stubProc->setEnvironment(stub.environment);
m_stubProc->setWorkingDirectory(stub.workingDirectory); m_stubProc->setWorkingDirectory(stub.workingDirectory);
// Error message for user is delivered via a signal. // Error message for user is delivered via a signal.
m_stubProc->setCommand(commandLine); m_stubProc->setCommand(stub.command);
m_stubProc->start(); m_stubProc->start();
} }

View File

@@ -79,7 +79,6 @@ public:
void kickoffProcess(); void kickoffProcess();
void interruptProcess(); void interruptProcess();
void setRunAsRoot(bool on);
private: private:
void start() final; void start() final;
@@ -92,7 +91,6 @@ private:
std::function<ProjectExplorer::Runnable()> m_stubRunnable; std::function<ProjectExplorer::Runnable()> m_stubRunnable;
qint64 m_applicationPid = 0; qint64 m_applicationPid = 0;
qint64 m_applicationMainThreadId = 0; qint64 m_applicationMainThreadId = 0;
bool m_runAsRoot = false;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -381,13 +381,7 @@ void ApplicationLauncherPrivate::start(const Runnable &runnable, const IDevice::
cmdLine = disclaim; cmdLine = disclaim;
} }
if (m_runAsRoot) { m_localProcess->setRunAsRoot(m_runAsRoot);
CommandLine wrapped("sudo", {"-A"});
wrapped.addCommandLineAsArgs(cmdLine);
cmdLine = wrapped;
}
// TODO: QtcProcess::setRunAsRoot() doens't work as expected currently
// m_localProcess->setRunAsRoot(m_runAsRoot);
m_localProcess->setCommand(cmdLine); m_localProcess->setCommand(cmdLine);
m_localProcess->start(); m_localProcess->start();
} else { } else {