libutil: rename and optimize closeMostFDs
this is only used to close non-stdio files in derivation sandboxes. we
may as well encode that in its name, drop the unnecessary integer set,
and use close_range to deal with the actual closing of files. not only
is this clearer, it also makes sandbox setup on linux fast by 1ms each
Change-Id: Id90e259a49c7bc896189e76bfbbf6ef2c0bcd3b2
This commit is contained in:
parent
35a2f28a46
commit
c7d97802e4
|
@ -1618,7 +1618,7 @@ void LocalDerivationGoal::runChild()
|
||||||
throw SysError("changing into '%1%'", tmpDir);
|
throw SysError("changing into '%1%'", tmpDir);
|
||||||
|
|
||||||
/* Close all other file descriptors. */
|
/* Close all other file descriptors. */
|
||||||
closeMostFDs({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO});
|
closeExtraFDs();
|
||||||
|
|
||||||
setPersonality(drv->platform);
|
setPersonality(drv->platform);
|
||||||
|
|
||||||
|
|
|
@ -218,13 +218,24 @@ void Pipe::close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void closeMostFDs(const std::set<int> & exceptions)
|
void closeExtraFDs()
|
||||||
{
|
{
|
||||||
|
constexpr int MAX_KEPT_FD = 2;
|
||||||
|
static_assert(std::max({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}) == MAX_KEPT_FD);
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
|
// first try to close_range everything we don't care about. if this
|
||||||
|
// returns an error with these parameters we're running on a kernel
|
||||||
|
// that does not implement close_range (i.e. pre 5.9) and fall back
|
||||||
|
// to the old method. we should remove that though, in some future.
|
||||||
|
if (close_range(3, ~0U, 0) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (auto & s : readDirectory("/proc/self/fd")) {
|
for (auto & s : readDirectory("/proc/self/fd")) {
|
||||||
auto fd = std::stoi(s.name);
|
auto fd = std::stoi(s.name);
|
||||||
if (!exceptions.count(fd)) {
|
if (fd > MAX_KEPT_FD) {
|
||||||
debug("closing leaked FD %d", fd);
|
debug("closing leaked FD %d", fd);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
@ -236,8 +247,7 @@ void closeMostFDs(const std::set<int> & exceptions)
|
||||||
|
|
||||||
int maxFD = 0;
|
int maxFD = 0;
|
||||||
maxFD = sysconf(_SC_OPEN_MAX);
|
maxFD = sysconf(_SC_OPEN_MAX);
|
||||||
for (int fd = 0; fd < maxFD; ++fd)
|
for (int fd = MAX_KEPT_FD + 1; fd < maxFD; ++fd)
|
||||||
if (!exceptions.count(fd))
|
|
||||||
close(fd); /* ignore result */
|
close(fd); /* ignore result */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close all file descriptors except those listed in the given set.
|
* Close all file descriptors except stdio fds (ie 0, 1, 2).
|
||||||
* Good practice in child processes.
|
* Good practice in child processes.
|
||||||
*/
|
*/
|
||||||
void closeMostFDs(const std::set<int> & exceptions);
|
void closeExtraFDs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the close-on-exec flag for the given file descriptor.
|
* Set the close-on-exec flag for the given file descriptor.
|
||||||
|
|
Loading…
Reference in a new issue