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
This commit is contained in:
Nick Kralevich
2018-12-14 21:34:44 -08:00
parent 1d709c965b
commit d9765a4cc0

View File

@@ -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;