389-ds-base/SOURCES/Issue-5646-Various-memory-l...

112 lines
4.5 KiB
Diff

From 58d09ebe2498dfbbd7f20524a00f81b8cb6092f1 Mon Sep 17 00:00:00 2001
From: James Chapman <jachapma@redhat.com>
Date: Mon, 29 May 2023 09:38:21 +0000
Subject: [PATCH] Issue 5646 - Various memory leaks (#5725)
Bug description: A memory leak occurs when a sync repl search is run
in refreshPersist mode. The connection from sync repl consumer is
closed without freeing up the ldap req ctrls.
Fix description: When the connection to the client is closed or on
shutdown free the request control structure if it exists.
relates: https://github.com/389ds/389-ds-base/issues/5646
Reviewed by: @progier389, @droideck, @Firstyear, @tbordaz (Thank you)
---
dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py | 5 +----
ldap/servers/plugins/sync/sync_persist.c | 7 +++++++
ldap/servers/plugins/sync/sync_util.c | 4 ++++
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
index 375517693a..eb3770b783 100644
--- a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
+++ b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
@@ -231,7 +231,7 @@ def run(self):
print('syncrepl_poll: LDAP error (%s)', e)
self.result = ldap_connection.get_cookies()
log.info("ZZZ result = %s" % self.result)
- self.conn.unbind()
+ ldap_connection.unbind()
def test_sync_repl_mep(topology, request):
"""Test sync repl with MEP plugin that triggers several
@@ -406,12 +406,10 @@ def test_sync_repl_cookie_add_del(topology, init_sync_repl_plugins, request):
6.: succeeds
"""
inst = topology[0]
-
# create a sync repl client and wait 5 seconds to be sure it is running
sync_repl = Sync_persist(inst)
sync_repl.start()
time.sleep(5)
-
# create users, that automember/memberof will generate nested updates
users = UserAccounts(inst, DEFAULT_SUFFIX)
users_set = []
@@ -427,7 +425,6 @@ def test_sync_repl_cookie_add_del(topology, init_sync_repl_plugins, request):
# and wait a bit to let sync_repl thread time to set its result before fetching it.
inst.stop()
cookies = sync_repl.get_result()
-
# checking that the cookie are in increasing and in an acceptable range (0..1000)
assert len(cookies) > 0
prev = -1
diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c
index 12b23ebac3..d2210b64c9 100644
--- a/ldap/servers/plugins/sync/sync_persist.c
+++ b/ldap/servers/plugins/sync/sync_persist.c
@@ -903,6 +903,7 @@ sync_send_results(void *arg)
int conn_acq_flag = 0;
Slapi_Connection *conn = NULL;
Slapi_Operation *op = req->req_orig_op;
+ LDAPControl **ctrls = NULL;
int rc;
PRUint64 connid;
int opid;
@@ -1049,6 +1050,12 @@ sync_send_results(void *arg)
slapi_ch_free((void **)&strFilter);
slapi_pblock_set(req->req_pblock, SLAPI_SEARCH_STRFILTER, NULL);
+ slapi_pblock_get(req->req_pblock, SLAPI_REQCONTROLS, &ctrls);
+ if (ctrls) {
+ ldap_controls_free(ctrls);
+ slapi_pblock_set(req->req_pblock, SLAPI_REQCONTROLS, NULL);
+ }
+
slapi_pblock_destroy(req->req_pblock);
req->req_pblock = NULL;
diff --git a/ldap/servers/plugins/sync/sync_util.c b/ldap/servers/plugins/sync/sync_util.c
index 21e1606312..605ddf1f36 100644
--- a/ldap/servers/plugins/sync/sync_util.c
+++ b/ldap/servers/plugins/sync/sync_util.c
@@ -689,6 +689,7 @@ sync_pblock_copy(Slapi_PBlock *src)
Slapi_Operation *operation;
Slapi_Operation *operation_new;
Slapi_Connection *connection;
+ LDAPControl **ctrls = NULL;
int *scope;
int *deref;
int *filter_normalized;
@@ -715,8 +716,10 @@ sync_pblock_copy(Slapi_PBlock *src)
slapi_pblock_get(src, SLAPI_REQUESTOR_ISROOT, &isroot);
slapi_pblock_get(src, SLAPI_SEARCH_SIZELIMIT, &sizelimit);
slapi_pblock_get(src, SLAPI_SEARCH_TIMELIMIT, &timelimit);
+ slapi_pblock_get(src, SLAPI_REQCONTROLS, &ctrls);
slapi_pblock_get(src, SLAPI_PLUGIN, &pi);
+
Slapi_PBlock *dest = slapi_pblock_new();
operation_new = slapi_operation_new(0);
msgid = slapi_operation_get_msgid(operation);
@@ -737,6 +740,7 @@ sync_pblock_copy(Slapi_PBlock *src)
slapi_pblock_set(dest, SLAPI_REQUESTOR_ISROOT, &isroot);
slapi_pblock_set(dest, SLAPI_SEARCH_SIZELIMIT, &sizelimit);
slapi_pblock_set(dest, SLAPI_SEARCH_TIMELIMIT, &timelimit);
+ slapi_pblock_set(dest, SLAPI_REQCONTROLS, ctrls);
slapi_pblock_set(dest, SLAPI_PLUGIN, pi);
return dest;