1
0
Fork 0
mirror of https://gitlab.alpinelinux.org/alpine/aports.git synced 2025-07-22 02:35:23 +03:00
aports/community/openjdk8/icedtea-jdk-close-fds.patch
Natanael Copa f10a27abc4 community/openjdk8: fix deadlock
avoid malloc after fork
fixes #11861
2020-08-18 07:19:22 +00:00

115 lines
3.2 KiB
Diff

Avoid use opendir after fork as its not async safe and may lead to deadlock
https://gitlab.alpinelinux.org/alpine/aports/-/issues/11861
diff --git a/openjdk/jdk/src/solaris/native/java/lang/childproc.c b/openjdk/jdk/src/solaris/native/java/lang/childproc.c
index 1d183cf..05aa6cb 100644
--- openjdk/jdk/src/solaris/native/java/lang/childproc.c
+++ openjdk/jdk/src/solaris/native/java/lang/childproc.c
@@ -23,13 +23,13 @@
* questions.
*/
-#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
+#include <poll.h>
#include "childproc.h"
@@ -56,61 +56,47 @@ closeSafely(int fd)
return (fd == -1) ? 0 : close(fd);
}
-int
-isAsciiDigit(char c)
-{
- return c >= '0' && c <= '9';
-}
-
-#ifdef _ALLBSD_SOURCE
-#define FD_DIR "/dev/fd"
-#define dirent64 dirent
-#define readdir64 readdir
-#elif defined(_AIX)
-/* AIX does not understand '/proc/self' - it requires the real process ID */
-#define FD_DIR aix_fd_dir
-#else
-#define FD_DIR "/proc/self/fd"
-#endif
-
int
closeDescriptors(void)
{
- DIR *dp;
- struct dirent64 *dirp;
int from_fd = FAIL_FILENO + 1;
+ struct pollfd pfds[1024];
+ int i, total, nclosed = 0;
+ int max_fd = sysconf(_SC_OPEN_MAX);
- /* We're trying to close all file descriptors, but opendir() might
- * itself be implemented using a file descriptor, and we certainly
- * don't want to close that while it's in use. We assume that if
- * opendir() is implemented using a file descriptor, then it uses
- * the lowest numbered file descriptor, just like open(). So we
- * close a couple explicitly. */
+ if (max_fd < 0)
+ return 0;
- close(from_fd); /* for possible use by opendir() */
- close(from_fd + 1); /* another one for good luck */
+ /* init events */
+ total = max_fd - from_fd;
+ for (i = 0; i < (total < 1024 ? total : 1024); i++) {
+ pfds[i].events = 0;
+ }
-#if defined(_AIX)
- /* AIX does not understand '/proc/self' - it requires the real process ID */
- char aix_fd_dir[32]; /* the pid has at most 19 digits */
- snprintf(aix_fd_dir, 32, "/proc/%d/fd", getpid());
-#endif
+ while (from_fd < max_fd) {
+ int nfds, r = 0;
- if ((dp = opendir(FD_DIR)) == NULL)
- return 0;
+ total = max_fd - from_fd;
+ nfds = total < 1024 ? total : 1024;
- /* We use readdir64 instead of readdir to work around Solaris bug
- * 6395699: /proc/self/fd fails to report file descriptors >= 1024 on Solaris 9
- */
- while ((dirp = readdir64(dp)) != NULL) {
- int fd;
- if (isAsciiDigit(dirp->d_name[0]) &&
- (fd = strtol(dirp->d_name, NULL, 10)) >= from_fd + 2)
- close(fd);
- }
+ for (i = 0; i < nfds; i++)
+ pfds[i].fd = from_fd + i;
- closedir(dp);
+ do {
+ r = poll(pfds, nfds, 0);
+ } while (r == -1 && errno == EINTR);
+ if (r < 0)
+ return 0;
+
+
+ for (i = 0; i < nfds; i++)
+ if (pfds[i].revents != POLLNVAL) {
+ nclosed++;
+ close(pfds[i].fd);
+ }
+ from_fd += nfds;
+ }
return 1;
}