|
|
0d8777 |
From 5a73027642b826793658774df8a0536975120b19 Mon Sep 17 00:00:00 2001
|
|
|
0d8777 |
From: John Eckersberg <jeckersb@redhat.com>
|
|
|
0d8777 |
Date: Fri, 11 Oct 2019 08:59:41 -0400
|
|
|
0d8777 |
Subject: [PATCH] Fix: libcrmservice: try not to spam close() file descriptors
|
|
|
0d8777 |
|
|
|
0d8777 |
With large file descriptor limits, action_launch_child can close
|
|
|
0d8777 |
millions of non-existent file descriptors.
|
|
|
0d8777 |
|
|
|
0d8777 |
Instead, try to read open file descriptors from /proc or /dev/fd and
|
|
|
0d8777 |
close only those which are open.
|
|
|
0d8777 |
|
|
|
0d8777 |
See rhbz#1762025
|
|
|
0d8777 |
---
|
|
|
0d8777 |
lib/services/services_linux.c | 26 ++++++++++++++++++++++++--
|
|
|
0d8777 |
1 file changed, 24 insertions(+), 2 deletions(-)
|
|
|
0d8777 |
|
|
|
0d8777 |
diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c
|
|
|
0d8777 |
index 90c1f44..464fc5b 100644
|
|
|
0d8777 |
--- a/lib/services/services_linux.c
|
|
|
0d8777 |
+++ b/lib/services/services_linux.c
|
|
|
0d8777 |
@@ -445,6 +445,7 @@ static void
|
|
|
0d8777 |
action_launch_child(svc_action_t *op)
|
|
|
0d8777 |
{
|
|
|
0d8777 |
int lpc;
|
|
|
0d8777 |
+ DIR *dir;
|
|
|
0d8777 |
|
|
|
0d8777 |
/* SIGPIPE is ignored (which is different from signal blocking) by the gnutls library.
|
|
|
0d8777 |
* Depending on the libqb version in use, libqb may set SIGPIPE to be ignored as well.
|
|
|
0d8777 |
@@ -476,8 +477,29 @@ action_launch_child(svc_action_t *op)
|
|
|
0d8777 |
setpgid(0, 0);
|
|
|
0d8777 |
|
|
|
0d8777 |
// Close all file descriptors except stdin/stdout/stderr
|
|
|
0d8777 |
- for (lpc = getdtablesize() - 1; lpc > STDERR_FILENO; lpc--) {
|
|
|
0d8777 |
- close(lpc);
|
|
|
0d8777 |
+#if SUPPORT_PROCFS
|
|
|
0d8777 |
+ dir = opendir("/proc/self/fd");
|
|
|
0d8777 |
+#else
|
|
|
0d8777 |
+ dir = opendir("/dev/fd");
|
|
|
0d8777 |
+#endif
|
|
|
0d8777 |
+ if (dir == NULL) { /* /proc or /dev/fd not available */
|
|
|
0d8777 |
+ /* Iterate over all possible fds, might be slow */
|
|
|
0d8777 |
+ for (lpc = getdtablesize() - 1; lpc > STDERR_FILENO; lpc--) {
|
|
|
0d8777 |
+ close(lpc);
|
|
|
0d8777 |
+ }
|
|
|
0d8777 |
+ } else {
|
|
|
0d8777 |
+ /* Iterate over fds obtained from /proc or /dev/fd */
|
|
|
0d8777 |
+ struct dirent *entry;
|
|
|
0d8777 |
+ int dir_fd = dirfd(dir);
|
|
|
0d8777 |
+
|
|
|
0d8777 |
+ while ((entry = readdir(dir)) != NULL) {
|
|
|
0d8777 |
+ lpc = atoi(entry->d_name);
|
|
|
0d8777 |
+ if (lpc > STDERR_FILENO && lpc != dir_fd) {
|
|
|
0d8777 |
+ close(lpc);
|
|
|
0d8777 |
+ }
|
|
|
0d8777 |
+ }
|
|
|
0d8777 |
+
|
|
|
0d8777 |
+ closedir(dir);
|
|
|
0d8777 |
}
|
|
|
0d8777 |
|
|
|
0d8777 |
#if SUPPORT_CIBSECRETS
|
|
|
0d8777 |
--
|
|
|
0d8777 |
1.8.3.1
|
|
|
0d8777 |
|