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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -188,11 +188,6 @@ void TerminalRunner::interruptProcess()
m_stubProc->interruptProcess();
}
void TerminalRunner::setRunAsRoot(bool on)
{
m_runAsRoot = on;
}
void TerminalRunner::start()
{
QTC_ASSERT(m_stubRunnable, reportFailure({}); return);
@@ -209,20 +204,11 @@ void TerminalRunner::start()
connect(m_stubProc, &QtcProcess::finished,
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->setWorkingDirectory(stub.workingDirectory);
// Error message for user is delivered via a signal.
m_stubProc->setCommand(commandLine);
m_stubProc->setCommand(stub.command);
m_stubProc->start();
}

View File

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

View File

@@ -381,13 +381,7 @@ void ApplicationLauncherPrivate::start(const Runnable &runnable, const IDevice::
cmdLine = disclaim;
}
if (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->setRunAsRoot(m_runAsRoot);
m_localProcess->setCommand(cmdLine);
m_localProcess->start();
} else {