Fall back to FD_CLOEXEC when O_CLOEXEC is unavailable.

Older Linux systems don't have O_CLOEXEC.  If that's the case, we fcntl
immediately after open, to minimize the length of the racy period in
which an
operation in another thread can leak a file descriptor to a child.
This commit is contained in:
Y. T. Chung 2017-07-20 23:02:23 +08:00 committed by David Goldblatt
parent fb6787a78c
commit 0975b88dfd
2 changed files with 28 additions and 5 deletions

View File

@ -353,14 +353,31 @@ os_overcommits_proc(void) {
ssize_t nread; ssize_t nread;
#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_open) #if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_open)
#if defined(O_CLOEXEC)
fd = (int)syscall(SYS_open, "/proc/sys/vm/overcommit_memory", O_RDONLY | fd = (int)syscall(SYS_open, "/proc/sys/vm/overcommit_memory", O_RDONLY |
O_CLOEXEC); O_CLOEXEC);
#else
fd = (int)syscall(SYS_open, "/proc/sys/vm/overcommit_memory", O_RDONLY);
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
#endif
#elif defined(JEMALLOC_USE_SYSCALL) && defined(SYS_openat) #elif defined(JEMALLOC_USE_SYSCALL) && defined(SYS_openat)
#if defined(O_CLOEXEC)
fd = (int)syscall(SYS_openat, fd = (int)syscall(SYS_openat,
AT_FDCWD, "/proc/sys/vm/overcommit_memory", O_RDONLY | O_CLOEXEC); AT_FDCWD, "/proc/sys/vm/overcommit_memory", O_RDONLY | O_CLOEXEC);
#else #else
fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY | O_CLOEXEC); fd = (int)syscall(SYS_openat,
AT_FDCWD, "/proc/sys/vm/overcommit_memory", O_RDONLY);
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
#endif #endif
#else
#if defined(O_CLOEXEC)
fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY | O_CLOEXEC);
#else
fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY);
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
#endif
#endif
if (fd == -1) { if (fd == -1) {
return false; /* Error. */ return false; /* Error. */
} }

View File

@ -1409,7 +1409,13 @@ prof_open_maps(const char *format, ...) {
va_start(ap, format); va_start(ap, format);
malloc_vsnprintf(filename, sizeof(filename), format, ap); malloc_vsnprintf(filename, sizeof(filename), format, ap);
va_end(ap); va_end(ap);
#if defined(O_CLOEXEC)
mfd = open(filename, O_RDONLY | O_CLOEXEC); mfd = open(filename, O_RDONLY | O_CLOEXEC);
#else
mfd = open(filename, O_RDONLY);
fcntl(mfd, F_SETFD, fcntl(mfd, F_GETFD) | FD_CLOEXEC);
#endif
return mfd; return mfd;
} }