From f69ac60b0cb18cf2f1006174012d43a5f87b5c0e Mon Sep 17 00:00:00 2001 From: Allan Odgaard Date: Sun, 10 Mar 2013 16:04:47 +0100 Subject: [PATCH] Limit file descriptors passed to child process MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- Frameworks/OakSystem/src/process.cc | 17 ++++++++++++----- Frameworks/io/src/exec.cc | 5 ++++- Frameworks/network/src/tbz.cc | 8 +++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Frameworks/OakSystem/src/process.cc b/Frameworks/OakSystem/src/process.cc index c53bb576..0571d61b 100644 --- a/Frameworks/OakSystem/src/process.cc +++ b/Frameworks/OakSystem/src/process.cc @@ -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); diff --git a/Frameworks/io/src/exec.cc b/Frameworks/io/src/exec.cc index f94d2568..47f7848e 100644 --- a/Frameworks/io/src/exec.cc +++ b/Frameworks/io/src/exec.cc @@ -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::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 diff --git a/Frameworks/network/src/tbz.cc b/Frameworks/network/src/tbz.cc index caa949c3..ff3dc124 100644 --- a/Frameworks/network/src/tbz.cc +++ b/Frameworks/network/src/tbz.cc @@ -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;