Blame SOURCES/0025-Issue-50984-Memory-leaks-in-disk-monitoring.patch

d69b2b
From 68ca1de0f39c11056a57b03a544520bd6708d855 Mon Sep 17 00:00:00 2001
d69b2b
From: Simon Pichugin <simon.pichugin@gmail.com>
d69b2b
Date: Thu, 11 Jun 2020 15:39:59 +0200
d69b2b
Subject: [PATCH] Issue 50984 - Memory leaks in disk monitoring
d69b2b
d69b2b
Description: Fix the rest of the leaks in disk monitoring
d69b2b
which are present when we shutdown while being below half
d69b2b
of the threshold (at the start-up in main.c).
d69b2b
d69b2b
Free directories, sockets and ports before going to cleanup.
d69b2b
d69b2b
https://pagure.io/389-ds-base/issue/50984
d69b2b
d69b2b
Reviewed by: mhonek, tbordaz (Thanks!)
d69b2b
---
d69b2b
 ldap/servers/slapd/daemon.c | 75 ++++++++++++++++++++-----------------
d69b2b
 ldap/servers/slapd/fe.h     |  1 +
d69b2b
 ldap/servers/slapd/main.c   | 49 +++++++++++++-----------
d69b2b
 3 files changed, 70 insertions(+), 55 deletions(-)
d69b2b
d69b2b
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
d69b2b
index a70f40316..7091b570d 100644
d69b2b
--- a/ldap/servers/slapd/daemon.c
d69b2b
+++ b/ldap/servers/slapd/daemon.c
d69b2b
@@ -884,6 +884,46 @@ convert_pbe_des_to_aes(void)
d69b2b
     charray_free(attrs);
d69b2b
 }
d69b2b
 
d69b2b
+void
d69b2b
+slapd_sockets_ports_free(daemon_ports_t *ports_info)
d69b2b
+{
d69b2b
+    /* freeing PRFileDescs */
d69b2b
+    PRFileDesc **fdesp = NULL;
d69b2b
+    for (fdesp = ports_info->n_socket; fdesp && *fdesp; fdesp++) {
d69b2b
+        PR_Close(*fdesp);
d69b2b
+    }
d69b2b
+    slapi_ch_free((void **)&ports_info->n_socket);
d69b2b
+
d69b2b
+    for (fdesp = ports_info->s_socket; fdesp && *fdesp; fdesp++) {
d69b2b
+        PR_Close(*fdesp);
d69b2b
+    }
d69b2b
+    slapi_ch_free((void **)&ports_info->s_socket);
d69b2b
+#if defined(ENABLE_LDAPI)
d69b2b
+    for (fdesp = ports_info->i_socket; fdesp && *fdesp; fdesp++) {
d69b2b
+        PR_Close(*fdesp);
d69b2b
+    }
d69b2b
+    slapi_ch_free((void **)&ports_info->i_socket);
d69b2b
+#endif /* ENABLE_LDAPI */
d69b2b
+
d69b2b
+    /* freeing NetAddrs */
d69b2b
+    PRNetAddr **nap;
d69b2b
+    for (nap = ports_info->n_listenaddr; nap && *nap; nap++) {
d69b2b
+        slapi_ch_free((void **)nap);
d69b2b
+    }
d69b2b
+    slapi_ch_free((void **)&ports_info->n_listenaddr);
d69b2b
+
d69b2b
+    for (nap = ports_info->s_listenaddr; nap && *nap; nap++) {
d69b2b
+        slapi_ch_free((void **)nap);
d69b2b
+    }
d69b2b
+    slapi_ch_free((void **)&ports_info->s_listenaddr);
d69b2b
+#if defined(ENABLE_LDAPI)
d69b2b
+    for (nap = ports_info->i_listenaddr; nap && *nap; nap++) {
d69b2b
+        slapi_ch_free((void **)nap);
d69b2b
+    }
d69b2b
+    slapi_ch_free((void **)&ports_info->i_listenaddr);
d69b2b
+#endif
d69b2b
+}
d69b2b
+
d69b2b
 void
d69b2b
 slapd_daemon(daemon_ports_t *ports)
d69b2b
 {
d69b2b
@@ -1099,40 +1139,7 @@ slapd_daemon(daemon_ports_t *ports)
d69b2b
     /* free the listener indexes */
d69b2b
     slapi_ch_free((void **)&listener_idxs);
d69b2b
 
d69b2b
-    for (fdesp = n_tcps; fdesp && *fdesp; fdesp++) {
d69b2b
-        PR_Close(*fdesp);
d69b2b
-    }
d69b2b
-    slapi_ch_free((void **)&n_tcps);
d69b2b
-
d69b2b
-    for (fdesp = i_unix; fdesp && *fdesp; fdesp++) {
d69b2b
-        PR_Close(*fdesp);
d69b2b
-    }
d69b2b
-    slapi_ch_free((void **)&i_unix);
d69b2b
-
d69b2b
-    for (fdesp = s_tcps; fdesp && *fdesp; fdesp++) {
d69b2b
-        PR_Close(*fdesp);
d69b2b
-    }
d69b2b
-    slapi_ch_free((void **)&s_tcps);
d69b2b
-
d69b2b
-    /* freeing NetAddrs */
d69b2b
-    {
d69b2b
-        PRNetAddr **nap;
d69b2b
-        for (nap = ports->n_listenaddr; nap && *nap; nap++) {
d69b2b
-            slapi_ch_free((void **)nap);
d69b2b
-        }
d69b2b
-        slapi_ch_free((void **)&ports->n_listenaddr);
d69b2b
-
d69b2b
-        for (nap = ports->s_listenaddr; nap && *nap; nap++) {
d69b2b
-            slapi_ch_free((void **)nap);
d69b2b
-        }
d69b2b
-        slapi_ch_free((void **)&ports->s_listenaddr);
d69b2b
-#if defined(ENABLE_LDAPI)
d69b2b
-        for (nap = ports->i_listenaddr; nap && *nap; nap++) {
d69b2b
-            slapi_ch_free((void **)nap);
d69b2b
-        }
d69b2b
-        slapi_ch_free((void **)&ports->i_listenaddr);
d69b2b
-#endif
d69b2b
-    }
d69b2b
+    slapd_sockets_ports_free(ports);
d69b2b
 
d69b2b
     op_thread_cleanup();
d69b2b
     housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */
d69b2b
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
d69b2b
index 2d9a0931b..9cd122881 100644
d69b2b
--- a/ldap/servers/slapd/fe.h
d69b2b
+++ b/ldap/servers/slapd/fe.h
d69b2b
@@ -120,6 +120,7 @@ int connection_table_iterate_active_connections(Connection_Table *ct, void *arg,
d69b2b
  */
d69b2b
 int signal_listner(void);
d69b2b
 int daemon_pre_setuid_init(daemon_ports_t *ports);
d69b2b
+void slapd_sockets_ports_free(daemon_ports_t *ports_info);
d69b2b
 void slapd_daemon(daemon_ports_t *ports);
d69b2b
 void daemon_register_connection(void);
d69b2b
 int slapd_listenhost2addr(const char *listenhost, PRNetAddr ***addr);
d69b2b
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
d69b2b
index e54b8e1c5..9e5219c4a 100644
d69b2b
--- a/ldap/servers/slapd/main.c
d69b2b
+++ b/ldap/servers/slapd/main.c
d69b2b
@@ -734,7 +734,6 @@ main(int argc, char **argv)
d69b2b
      * etc the backends need to start
d69b2b
      */
d69b2b
 
d69b2b
-
d69b2b
     /* Important: up 'till here we could be running as root (on unix).
d69b2b
      * we believe that we've not created any files before here, otherwise
d69b2b
      * they'd be owned by root, which is bad. We're about to change identity
d69b2b
@@ -891,6 +890,34 @@ main(int argc, char **argv)
d69b2b
     }
d69b2b
     }
d69b2b
 
d69b2b
+    if (config_get_disk_monitoring()) {
d69b2b
+        char **dirs = NULL;
d69b2b
+        char *dirstr = NULL;
d69b2b
+        uint64_t disk_space = 0;
d69b2b
+        int64_t threshold = 0;
d69b2b
+        uint64_t halfway = 0;
d69b2b
+        threshold = config_get_disk_threshold();
d69b2b
+        halfway = threshold / 2;
d69b2b
+        disk_mon_get_dirs(&dirs);
d69b2b
+        dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space);
d69b2b
+        if (dirstr != NULL && disk_space < halfway) {
d69b2b
+            slapi_log_err(SLAPI_LOG_EMERG, "main",
d69b2b
+                          "Disk Monitoring is enabled and disk space on (%s) is too far below the threshold(%" PRIu64 " bytes). Exiting now.\n",
d69b2b
+                          dirstr, threshold);
d69b2b
+            slapi_ch_array_free(dirs);
d69b2b
+            /*
d69b2b
+             * We should free the structs we allocated for sockets and addresses
d69b2b
+             * as they would be freed at the slapd_daemon but it was not initiated
d69b2b
+             * at that point of start-up.
d69b2b
+             */
d69b2b
+            slapd_sockets_ports_free(&ports_info);
d69b2b
+            return_value = 1;
d69b2b
+            goto cleanup;
d69b2b
+        }
d69b2b
+        slapi_ch_array_free(dirs);
d69b2b
+        dirs = NULL;
d69b2b
+    }
d69b2b
+
d69b2b
     /* initialize the normalized DN cache */
d69b2b
     if (ndn_cache_init() != 0) {
d69b2b
         slapi_log_err(SLAPI_LOG_EMERG, "main", "Unable to create ndn cache\n");
d69b2b
@@ -940,26 +967,6 @@ main(int argc, char **argv)
d69b2b
         slapi_ch_free((void **)&versionstring);
d69b2b
     }
d69b2b
 
d69b2b
-    if (config_get_disk_monitoring()) {
d69b2b
-        char **dirs = NULL;
d69b2b
-        char *dirstr = NULL;
d69b2b
-        uint64_t disk_space = 0;
d69b2b
-        int64_t threshold = 0;
d69b2b
-        uint64_t halfway = 0;
d69b2b
-        threshold = config_get_disk_threshold();
d69b2b
-        halfway = threshold / 2;
d69b2b
-        disk_mon_get_dirs(&dirs);
d69b2b
-        dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space);
d69b2b
-        if (dirstr != NULL && disk_space < halfway) {
d69b2b
-            slapi_log_err(SLAPI_LOG_EMERG, "main",
d69b2b
-                          "Disk Monitoring is enabled and disk space on (%s) is too far below the threshold(%" PRIu64 " bytes). Exiting now.\n",
d69b2b
-                          dirstr, threshold);
d69b2b
-            return_value = 1;
d69b2b
-            goto cleanup;
d69b2b
-        }
d69b2b
-        slapi_ch_array_free(dirs);
d69b2b
-        dirs = NULL;
d69b2b
-    }
d69b2b
     /* log the max fd limit as it is typically set in env/systemd */
d69b2b
     slapi_log_err(SLAPI_LOG_INFO, "main",
d69b2b
             "Setting the maximum file descriptor limit to: %ld\n",
d69b2b
-- 
d69b2b
2.26.2
d69b2b