Limit file descriptors passed to child process

Instead of passing the file descriptor to the child, and have the child close it, we set FD_CLOEXEC on the file descriptor in the parent process.

While it limits the window in which another thread can fork() and cause the file descriptor to be “leaked”, it doesn’t eliminate the problem.
This commit is contained in:
Allan Odgaard
2013-03-10 16:04:47 +01:00
parent 13edc6d131
commit f69ac60b0c
3 changed files with 21 additions and 9 deletions

View File

@@ -154,10 +154,19 @@ namespace oak
int inputPipe[2], outputPipe[2], errorPipe[2];
if(input_fd == -1)
pipe(inputPipe);
else inputPipe[0] = input_fd;
{
pipe(inputPipe);
fcntl(inputPipe[1], F_SETFD, FD_CLOEXEC);
}
else
{
inputPipe[0] = input_fd;
}
pipe(outputPipe);
pipe(errorPipe);
fcntl(outputPipe[0], F_SETFD, FD_CLOEXEC);
fcntl(errorPipe[0], F_SETFD, FD_CLOEXEC);
output_fd = outputPipe[0];
error_fd = errorPipe[0];
@@ -171,11 +180,9 @@ namespace oak
signal(SIGPIPE, SIG_DFL);
setpgid(0, getpid());
int const oldOutErr[] = { 0, 1, 2, outputPipe[0], errorPipe[0] };
int const oldOutErr[] = { 0, 1, 2 };
int const newOutErr[] = { inputPipe[0], outputPipe[1], errorPipe[1] };
for(int fd : oldOutErr) close(fd);
if(input_fd == -1)
close(inputPipe[1]);
for(int fd : newOutErr) dup(fd);
for(int fd : newOutErr) close(fd);

View File

@@ -27,6 +27,9 @@ namespace io
int outputPipe[2], errorPipe[2];
pipe(outputPipe);
pipe(errorPipe);
fcntl(outputPipe[0], F_SETFD, FD_CLOEXEC);
fcntl(errorPipe[0], F_SETFD, FD_CLOEXEC);
int output_fd = outputPipe[0], error_fd = errorPipe[0];
std::map<std::string, std::string>::const_iterator it = environment.find("PWD");
@@ -38,7 +41,7 @@ namespace io
{
setpgid(0, getpid());
int const oldOutErr[] = { 0, 1, 2, output_fd };
int const oldOutErr[] = { 0, 1, 2 };
for(int fd : oldOutErr) close(fd);
open("/dev/null", O_RDONLY); // stdin

View File

@@ -13,6 +13,8 @@ namespace network
int in[2], out[2];
pipe(&in[0]);
pipe(&out[0]);
fcntl(in[1], F_SETFD, FD_CLOEXEC);
fcntl(out[0], F_SETFD, FD_CLOEXEC);
char const* argv[] = { "/usr/bin/tar", "-jxmkC", dest.c_str(), "--strip-components", "1", NULL };
oak::c_array env(oak::basic_environment());
@@ -21,7 +23,7 @@ namespace network
{
close(0); close(1); close(2);
dup(in[0]); dup(out[1]); dup(out[1]);
close(in[0]); close(in[1]); close(out[0]); close(out[1]);
close(in[0]); close(out[1]);
signal(SIGPIPE, SIG_DFL);
@@ -42,8 +44,8 @@ namespace network
}
else
{
fcntl(input = in[1], F_SETFD, FD_CLOEXEC);
fcntl(output = out[0], F_SETFD, FD_CLOEXEC);
input = in[1];
output = out[0];
}
}
return pid;