[SSSD] [PATCH] Keep deref controls until the whole request is finished

Jakub Hrozek jhrozek at redhat.com
Tue Sep 6 10:43:55 UTC 2011


http://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.

John confirmed off-list that this patch fixed his issue.

I was also considering copying the controls into the search request, but
it seemed like a pointless allocation.
-------------- next part --------------
>From f0f064137f22a04fec386242c249ef3c4b0a81c4 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
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



More information about the sssd-devel mailing list