runProgram: support gid, uid, chdir
This commit is contained in:
parent
dde8eeb39a
commit
b4a05edbfe
|
@ -465,26 +465,22 @@ void handleDiffHook(bool allowVfork, uid_t uid, uid_t gid, Path tryA, Path tryB,
|
||||||
{
|
{
|
||||||
auto diffHook = settings.diffHook;
|
auto diffHook = settings.diffHook;
|
||||||
if (diffHook != "" && settings.runDiffHook) {
|
if (diffHook != "" && settings.runDiffHook) {
|
||||||
auto wrapper = [&]() {
|
try {
|
||||||
if (chdir("/") == -1)
|
RunOptions diffHookOptions(diffHook,{tryA, tryB, drvPath, tmpDir});
|
||||||
throw SysError("chdir / failed");
|
diffHookOptions.searchPath = true;
|
||||||
if (setgid(gid) == -1)
|
diffHookOptions.uid = uid;
|
||||||
throw SysError("setgid failed");
|
diffHookOptions.gid = gid;
|
||||||
if (setgroups(0, 0) == -1)
|
diffHookOptions.chdir = "/";
|
||||||
throw SysError("setgroups failed");
|
|
||||||
if (setuid(uid) == -1)
|
|
||||||
throw SysError("setuid failed");
|
|
||||||
|
|
||||||
try {
|
auto diffRes = runProgram(diffHookOptions);
|
||||||
auto diff = runProgram(diffHook, true, {tryA, tryB, drvPath, tmpDir});
|
if (!statusOk(diffRes.first))
|
||||||
if (diff != "")
|
throw ExecError(diffRes.first, fmt("diff-hook program '%1%' %2%", diffHook, statusToString(diffRes.first)));
|
||||||
printError(chomp(diff));
|
|
||||||
} catch (Error & error) {
|
|
||||||
printError("diff hook execution failed: %s", error.what());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
doFork(allowVfork, wrapper);
|
if (diffRes.second != "")
|
||||||
|
printError(chomp(diffRes.second));
|
||||||
|
} catch (Error & error) {
|
||||||
|
printError("diff hook execution failed: %s", error.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <grp.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
@ -914,8 +915,8 @@ void killUser(uid_t uid)
|
||||||
|
|
||||||
/* Wrapper around vfork to prevent the child process from clobbering
|
/* Wrapper around vfork to prevent the child process from clobbering
|
||||||
the caller's stack frame in the parent. */
|
the caller's stack frame in the parent. */
|
||||||
pid_t doFork(bool allowVfork, std::function<void()> fun) __attribute__((noinline));
|
static pid_t doFork(bool allowVfork, std::function<void()> fun) __attribute__((noinline));
|
||||||
pid_t doFork(bool allowVfork, std::function<void()> fun)
|
static pid_t doFork(bool allowVfork, std::function<void()> fun)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
pid_t pid = allowVfork ? vfork() : fork();
|
pid_t pid = allowVfork ? vfork() : fork();
|
||||||
|
@ -1025,6 +1026,16 @@ void runProgram2(const RunOptions & options)
|
||||||
if (source && dup2(in.readSide.get(), STDIN_FILENO) == -1)
|
if (source && dup2(in.readSide.get(), STDIN_FILENO) == -1)
|
||||||
throw SysError("dupping stdin");
|
throw SysError("dupping stdin");
|
||||||
|
|
||||||
|
//if (options.chdir && chdir((*options.chdir).c_str()) == -1)
|
||||||
|
// throw SysError("chdir failed");
|
||||||
|
if (options.gid && setgid(*options.gid) == -1)
|
||||||
|
throw SysError("setgid failed");
|
||||||
|
/* Drop all other groups if we're setgid. */
|
||||||
|
if (options.gid && setgroups(0, 0) == -1)
|
||||||
|
throw SysError("setgroups failed");
|
||||||
|
if (options.uid && setuid(*options.uid) == -1)
|
||||||
|
throw SysError("setuid failed");
|
||||||
|
|
||||||
Strings args_(options.args);
|
Strings args_(options.args);
|
||||||
args_.push_front(options.program);
|
args_.push_front(options.program);
|
||||||
|
|
||||||
|
|
|
@ -265,10 +265,11 @@ string runProgram(Path program, bool searchPath = false,
|
||||||
const Strings & args = Strings(),
|
const Strings & args = Strings(),
|
||||||
const std::optional<std::string> & input = {});
|
const std::optional<std::string> & input = {});
|
||||||
|
|
||||||
pid_t doFork(bool allowVfork, std::function<void()> fun);
|
|
||||||
|
|
||||||
struct RunOptions
|
struct RunOptions
|
||||||
{
|
{
|
||||||
|
std::optional<uid_t> uid;
|
||||||
|
std::optional<uid_t> gid;
|
||||||
|
std::optional<Path> chdir;
|
||||||
Path program;
|
Path program;
|
||||||
bool searchPath = true;
|
bool searchPath = true;
|
||||||
Strings args;
|
Strings args;
|
||||||
|
|
Loading…
Reference in a new issue