|
|
dc8c34 |
From 3120dbe2653c143a445f35b46929d5f63c8aa5c6 Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
dc8c34 |
Date: Wed, 30 Sep 2015 13:32:05 -0700
|
|
|
dc8c34 |
Subject: [PATCH 343/344] Ticket #48299 - pagedresults - when timed out, search
|
|
|
dc8c34 |
results could have been already freed.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Description: When a search results object is freed, there is a window
|
|
|
dc8c34 |
until the information is set to the pagedresults handle. If the paged-
|
|
|
dc8c34 |
results handle is released due to a timeout in the window, double free
|
|
|
dc8c34 |
occurs.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
This patch sets NULL just before the search results object is freed
|
|
|
dc8c34 |
in the backend as well as in dse.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Plus, fixed a minor memory leak in pagedresults_parse_control_value.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/48299
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed and a bug found by tbordaz@redhat.com (Thank you, Thierry!!)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
(cherry picked from commit f90c3a6e1933b9cc19a51b17a038f26652c4b2bc)
|
|
|
dc8c34 |
(cherry picked from commit 56151ed75bbd63af80932fe73a512df835b17593)
|
|
|
dc8c34 |
(cherry picked from commit 10ed80cf265fbfbec0c8dda005dcb84b6f39762b)
|
|
|
dc8c34 |
(cherry picked from commit 54e574ad5334fc9c0e27be0a57551add38d84d1e)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/back-ldbm/ldbm_search.c | 1 +
|
|
|
dc8c34 |
ldap/servers/slapd/dse.c | 1 +
|
|
|
dc8c34 |
ldap/servers/slapd/pagedresults.c | 33 +++++++++++++++++++++++++++++-
|
|
|
dc8c34 |
ldap/servers/slapd/proto-slap.h | 1 +
|
|
|
dc8c34 |
4 files changed, 35 insertions(+), 1 deletion(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
|
dc8c34 |
index 92ae691..bbcbe0e 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
|
|
|
dc8c34 |
@@ -1890,6 +1890,7 @@ delete_search_result_set( Slapi_PBlock *pb, back_search_result_set **sr )
|
|
|
dc8c34 |
/* If the op is pagedresults, let the module clean up sr. */
|
|
|
dc8c34 |
return;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ pagedresults_set_search_result_pb(pb, NULL, 0);
|
|
|
dc8c34 |
slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
if ( NULL != (*sr)->sr_candidates )
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
|
|
|
dc8c34 |
index 22cbff1..8080ec9 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/dse.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/dse.c
|
|
|
dc8c34 |
@@ -2578,6 +2578,7 @@ dse_next_search_entry (Slapi_PBlock *pb)
|
|
|
dc8c34 |
/* we reached the end of the list */
|
|
|
dc8c34 |
if (e == NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
+ pagedresults_set_search_result_pb(pb, NULL, 0);
|
|
|
dc8c34 |
dse_search_set_delete (ss);
|
|
|
dc8c34 |
slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
index 010e5c1..9e183ec 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/pagedresults.c
|
|
|
dc8c34 |
@@ -185,7 +185,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
/* reset sizelimit */
|
|
|
dc8c34 |
op->o_pagedresults_sizelimit = -1;
|
|
|
dc8c34 |
- slapi_ch_free((void **)&cookie.bv_val);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen)) {
|
|
|
dc8c34 |
if (conn->c_pagedresults.prl_list[*index].pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED) {
|
|
|
dc8c34 |
@@ -202,6 +201,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
|
|
|
dc8c34 |
LDAPDebug1Arg(LDAP_DEBUG_ANY, "pagedresults_parse_control_value: invalid cookie: %d\n", *index);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
bail:
|
|
|
dc8c34 |
+ slapi_ch_free((void **)&cookie.bv_val);
|
|
|
dc8c34 |
/* cleaning up the rest of the timedout or abandoned if any */
|
|
|
dc8c34 |
prp = conn->c_pagedresults.prl_list;
|
|
|
dc8c34 |
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++, prp++) {
|
|
|
dc8c34 |
@@ -1023,3 +1023,34 @@ pagedresults_is_abandoned_or_notavailable( Connection *conn, int index )
|
|
|
dc8c34 |
PR_Unlock(conn->c_mutex);
|
|
|
dc8c34 |
return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+
|
|
|
dc8c34 |
+int
|
|
|
dc8c34 |
+pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked)
|
|
|
dc8c34 |
+{
|
|
|
dc8c34 |
+ int rc = -1;
|
|
|
dc8c34 |
+ Connection *conn = NULL;
|
|
|
dc8c34 |
+ Operation *op = NULL;
|
|
|
dc8c34 |
+ int index = -1;
|
|
|
dc8c34 |
+ if (!pb) {
|
|
|
dc8c34 |
+ return 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_OPERATION, &op);
|
|
|
dc8c34 |
+ if (!op_is_pagedresults(op)) {
|
|
|
dc8c34 |
+ return 0; /* noop */
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_CONNECTION, &conn;;
|
|
|
dc8c34 |
+ slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &index);
|
|
|
dc8c34 |
+ LDAPDebug2Args(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
+ "--> pagedresults_set_search_result_pb: idx=%d, sr=%p\n", index, sr);
|
|
|
dc8c34 |
+ if (conn && (index > -1)) {
|
|
|
dc8c34 |
+ if (!locked) PR_Lock(conn->c_mutex);
|
|
|
dc8c34 |
+ if (index < conn->c_pagedresults.prl_maxlen) {
|
|
|
dc8c34 |
+ conn->c_pagedresults.prl_list[index].pr_search_result_set = sr;
|
|
|
dc8c34 |
+ rc = 0;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (!locked) PR_Unlock(conn->c_mutex);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ LDAPDebug1Arg(LDAP_DEBUG_TRACE,
|
|
|
dc8c34 |
+ "<-- pagedresults_set_search_result_pb: %d\n", rc);
|
|
|
dc8c34 |
+ return rc;
|
|
|
dc8c34 |
+}
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
index 7a1ab46..8f86eb7 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/proto-slap.h
|
|
|
dc8c34 |
@@ -1481,6 +1481,7 @@ void op_set_pagedresults(Operation *op);
|
|
|
dc8c34 |
void pagedresults_lock(Connection *conn, int index);
|
|
|
dc8c34 |
void pagedresults_unlock(Connection *conn, int index);
|
|
|
dc8c34 |
int pagedresults_is_abandoned_or_notavailable(Connection *conn, int index);
|
|
|
dc8c34 |
+int pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/*
|
|
|
dc8c34 |
* sort.c
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.9.3
|
|
|
dc8c34 |
|