>From f0f064137f22a04fec386242c249ef3c4b0a81c4 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 6 Sep 2011 00:07:15 +0200 Subject: [PATCH] Keep deref controls until the whole request is finished https://fedorahosted.org/sssd/ticket/989 John Hodrien found out that when paging is used while dereferencing an entry, sssd_be may segfault on the second page. This was because paging returned the control to sdap_generic_search multiple times but sssd was freeing dereference control after the first search invocation. The subsequend sdap searched accessed memory that was already freed. --- src/providers/ldap/sdap_async.c | 23 +++++++++++++++-------- 1 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index 5594dd5..556745c 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -1300,6 +1300,7 @@ struct sdap_x_deref_search_state { struct sdap_handle *sh; struct sdap_op *op; struct sdap_attr_map_info *maps; + LDAPControl *ctrls[2]; struct sdap_deref_reply dreply; int num_maps; @@ -1315,7 +1316,6 @@ sdap_x_deref_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_x_deref_search_state *state; - LDAPControl *ctrls[2] = { NULL, NULL }; int ret; req = tevent_req_create(memctx, &state, struct sdap_x_deref_search_state); @@ -1326,20 +1326,21 @@ sdap_x_deref_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, state->op = NULL; state->num_maps = num_maps; - ret = sdap_x_deref_create_control(sh, deref_attr, attrs, &ctrls[0]); + ret = sdap_x_deref_create_control(sh, deref_attr, + attrs, &state->ctrls[0]); if (ret != EOK) { DEBUG(1, ("Could not create OpenLDAP deref control\n")); talloc_zfree(req); return NULL; } + state->ctrls[1] = NULL; DEBUG(6, ("Dereferencing entry [%s] using OpenLDAP deref\n", base_dn)); subreq = sdap_get_generic_ext_send(state, ev, opts, sh, base_dn, LDAP_SCOPE_BASE, NULL, attrs, - false, ctrls, NULL, 0, timeout, + false, state->ctrls, NULL, 0, timeout, sdap_x_deref_parse_entry, state); - ldap_control_free(ctrls[0]); if (!subreq) { talloc_zfree(req); return NULL; @@ -1464,9 +1465,12 @@ static void sdap_x_deref_search_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); + struct sdap_x_deref_search_state *state = tevent_req_data(req, + struct sdap_x_deref_search_state); int ret; ret = sdap_get_generic_ext_recv(subreq); + ldap_control_free(state->ctrls[0]); talloc_zfree(subreq); if (ret) { DEBUG(4, ("sdap_get_generic_ext_recv failed [%d]: %s\n", @@ -1499,6 +1503,7 @@ sdap_x_deref_search_recv(struct tevent_req *req, struct sdap_asq_search_state { struct sdap_attr_map_info *maps; int num_maps; + LDAPControl *ctrls[2]; struct sdap_deref_reply dreply; }; @@ -1522,7 +1527,6 @@ sdap_asq_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct tevent_req *subreq = NULL; struct sdap_asq_search_state *state; int ret; - LDAPControl *ctrls[2] = { NULL, NULL }; req = tevent_req_create(memctx, &state, struct sdap_asq_search_state); if (!req) return NULL; @@ -1530,20 +1534,20 @@ sdap_asq_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, state->maps = maps; state->num_maps = num_maps; - ret = sdap_asq_search_create_control(sh, deref_attr, &ctrls[0]); + ret = sdap_asq_search_create_control(sh, deref_attr, &state->ctrls[0]); if (ret != EOK) { talloc_zfree(req); DEBUG(1, ("Could not create ASQ control\n")); return NULL; } + state->ctrls[1] = NULL; DEBUG(6, ("Dereferencing entry [%s] using ASQ\n", base_dn)); subreq = sdap_get_generic_ext_send(state, ev, opts, sh, base_dn, LDAP_SCOPE_BASE, NULL, attrs, - false, ctrls, NULL, 0, timeout, + false, state->ctrls, NULL, 0, timeout, sdap_asq_search_parse_entry, state); - ldap_control_free(ctrls[0]); if (!subreq) { talloc_zfree(req); return NULL; @@ -1670,9 +1674,12 @@ static void sdap_asq_search_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); + struct sdap_asq_search_state *state = tevent_req_data(req, + struct sdap_asq_search_state); int ret; ret = sdap_get_generic_ext_recv(subreq); + ldap_control_free(state->ctrls[0]); talloc_zfree(subreq); if (ret) { DEBUG(4, ("sdap_get_generic_ext_recv failed [%d]: %s\n", -- 1.7.6