libstore: fix linux sandbox parent death signal handling
setting the signal is not enough, we must also check that the process we expect to be parent to actually *is* our parent, not another process (eg init if the daemon exited). we also have to set the death signal *after* all set[ug]id calls, otherwise it will be cleared again by such changes. Change-Id: I4e8c9102ea407576ed85b3203c8bb9bfb56762de
This commit is contained in:
@@ -1518,6 +1518,16 @@ bool LinuxLocalDerivationGoal::prepareChildSetup()
|
||||
return false;
|
||||
}
|
||||
|
||||
void LinuxLocalDerivationGoal::finishChildSetup()
|
||||
{
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) {
|
||||
throw SysError("setting death signal");
|
||||
}
|
||||
if (getppid() != parentPid) {
|
||||
raise(SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
Pid LinuxLocalDerivationGoal::startChild(
|
||||
const Path & builder, const Strings & envStrs, const Strings & args, AutoCloseFD logPTY
|
||||
)
|
||||
@@ -1660,10 +1670,6 @@ Pid LinuxLocalDerivationGoal::startChild(
|
||||
}
|
||||
|
||||
return inVFork(/* flags*/ 0, [&]() {
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) {
|
||||
throw SysError("setting death signal");
|
||||
}
|
||||
|
||||
if (dup2(logPTY.get(), STDERR_FILENO) == -1) {
|
||||
throw SysError("failed to redirect build output to log file");
|
||||
}
|
||||
@@ -1698,15 +1704,7 @@ Pid LinuxLocalDerivationGoal::startChild(
|
||||
options.cloneFlags =
|
||||
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD;
|
||||
|
||||
return startProcess(
|
||||
[&]() {
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) {
|
||||
throw SysError("setting death signal");
|
||||
}
|
||||
runChild(builder, envStrs, args);
|
||||
},
|
||||
options
|
||||
);
|
||||
return startProcess([&]() { runChild(builder, envStrs, args); }, options);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "lix/libstore/gc-store.hh"
|
||||
#include "lix/libstore/local-store.hh"
|
||||
#include "lix/libutil/processes.hh"
|
||||
#include <unistd.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
@@ -58,6 +59,12 @@ private:
|
||||
|
||||
Pid pastaPid;
|
||||
|
||||
/**
|
||||
* used to initialize the parent death signal of children without racing
|
||||
* with the parent dying before we got around to setting a death signal.
|
||||
*/
|
||||
pid_t parentPid = getpid();
|
||||
|
||||
/**
|
||||
* Create a special accessor that can access paths that were built within the sandbox's
|
||||
* chroot.
|
||||
@@ -89,6 +96,8 @@ private:
|
||||
|
||||
bool prepareChildSetup() override;
|
||||
|
||||
void finishChildSetup() override;
|
||||
|
||||
std::string rewriteResolvConf(std::string fromHost);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user