From d9765a4cc05464d4082dac79585dccf4b11aa7ea Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Fri, 14 Dec 2018 21:34:44 -0800 Subject: [PATCH] fd_utils: carry over O_CLOEXEC on duplicated FDs Due to b/30963384, every time zygote creates a new child, zygote reopens all existing file descriptors, taking careful measures to preserve the file status flags, file descriptor flags, and seek offset. However, dup2 resets the sole file descriptor flag (FD_CLOEXEC) on duplication, defeating the hard work done to preserve the flag. From "man dup" NAME dup, dup2, dup3 - duplicate a file descriptor DESCRIPTION The dup() system call creates a copy ... ... The two file descriptors do not share file descriptor flags (the close-on-exec flag). The close-on-exec flag (FD_CLOEXEC; see fcntl(2)) for the duplicate descriptor is off. ... The dup2() system call performs the same task as dup() ... Use dup3 instead to allow us to preserve the FD_CLOEXEC status. Bug: 120983106 Test: Android compiles and boots Change-Id: Idbb27c83092f30d8394c254cfbdf33406f74eb94 --- core/jni/fd_utils.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp index d457a1b48e381..a03e929fa60be 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -327,11 +327,13 @@ bool FileDescriptorInfo::ReopenOrDetach(std::string* error_msg) const { return false; } - if (TEMP_FAILURE_RETRY(dup2(new_fd, fd)) == -1) { + int dupFlags = (fd_flags & FD_CLOEXEC) ? O_CLOEXEC : 0; + if (TEMP_FAILURE_RETRY(dup3(new_fd, fd, dupFlags)) == -1) { close(new_fd); - *error_msg = android::base::StringPrintf("Failed dup2(%d, %d) (%s): %s", + *error_msg = android::base::StringPrintf("Failed dup3(%d, %d, %d) (%s): %s", fd, new_fd, + dupFlags, file_path.c_str(), strerror(errno)); return false;