Open MessagePumpLibevent's pipe with O_CLOEXEC
This prevents the pipe's fds from being leaked into child processes.
This is a cherry-pick of https://crrev.com/80c77bfd86 .
TEST=git cl try
BUG=chromium:653930
Change-Id: I1d9ea26e41a23dc7ca5cd6d4b2133a2e69b1259c
Reviewed-on: https://chromium-review.googlesource.com/395446
Commit-Ready: Luis Hector Chavez <lhchavez@google.com>
Tested-by: Luis Hector Chavez <lhchavez@google.com>
Reviewed-by: Luis Hector Chavez <lhchavez@google.com>
diff --git a/base/files/file_util.h b/base/files/file_util.h
index 8fd9fff..dbad7e5 100644
--- a/base/files/file_util.h
+++ b/base/files/file_util.h
@@ -359,6 +359,17 @@
BASE_EXPORT bool SetNonBlocking(int fd);
#if defined(OS_POSIX)
+// Creates a non-blocking, close-on-exec pipe.
+// This creates a non-blocking pipe that is not intended to be shared with any
+// child process. This will be done atomically if the operating system supports
+// it. Returns true if it was able to create the pipe, otherwise false.
+BASE_EXPORT bool CreateLocalNonBlockingPipe(int fds[2]);
+
+// Sets the given |fd| to close-on-exec mode.
+// Returns true if it was able to set it in the close-on-exec mode, otherwise
+// false.
+BASE_EXPORT bool SetCloseOnExec(int fd);
+
// Test that |path| can only be changed by a given user and members of
// a given set of groups.
// Specifically, test that all parts of |path| under (and including) |base|:
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc
index 599759a..8462495 100644
--- a/base/files/file_util_posix.cc
+++ b/base/files/file_util_posix.cc
@@ -349,6 +349,29 @@
}
#endif // !defined(OS_NACL_NONSFI)
+bool CreateLocalNonBlockingPipe(int fds[2]) {
+#if defined(OS_LINUX)
+ return pipe2(fds, O_CLOEXEC | O_NONBLOCK) == 0;
+#else
+ int raw_fds[2];
+ if (pipe(raw_fds) != 0)
+ return false;
+ ScopedFD fd_out(raw_fds[0]);
+ ScopedFD fd_in(raw_fds[1]);
+ if (!SetCloseOnExec(fd_out.get()))
+ return false;
+ if (!SetCloseOnExec(fd_in.get()))
+ return false;
+ if (!SetNonBlocking(fd_out.get()))
+ return false;
+ if (!SetNonBlocking(fd_in.get()))
+ return false;
+ fds[0] = fd_out.release();
+ fds[1] = fd_in.release();
+ return true;
+#endif
+}
+
bool SetNonBlocking(int fd) {
const int flags = fcntl(fd, F_GETFL);
if (flags == -1)
@@ -360,6 +383,21 @@
return true;
}
+bool SetCloseOnExec(int fd) {
+#if defined(OS_NACL_NONSFI)
+ const int flags = 0;
+#else
+ const int flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ return false;
+ if (flags & FD_CLOEXEC)
+ return true;
+#endif // defined(OS_NACL_NONSFI)
+ if (HANDLE_EINTR(fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) == -1)
+ return false;
+ return true;
+}
+
bool PathExists(const FilePath& path) {
ThreadRestrictions::AssertIOAllowed();
#if defined(OS_ANDROID)
diff --git a/base/message_loop/message_pump_libevent.cc b/base/message_loop/message_pump_libevent.cc
index 5aa5567..5f20447 100644
--- a/base/message_loop/message_pump_libevent.cc
+++ b/base/message_loop/message_pump_libevent.cc
@@ -292,16 +292,8 @@
bool MessagePumpLibevent::Init() {
int fds[2];
- if (pipe(fds)) {
- DLOG(ERROR) << "pipe() failed, errno: " << errno;
- return false;
- }
- if (!SetNonBlocking(fds[0])) {
- DLOG(ERROR) << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
- return false;
- }
- if (!SetNonBlocking(fds[1])) {
- DLOG(ERROR) << "SetNonBlocking for pipe fd[1] failed, errno: " << errno;
+ if (!CreateLocalNonBlockingPipe(fds)) {
+ DPLOG(ERROR) << "pipe creation failed";
return false;
}
wakeup_pipe_out_ = fds[0];