From f081ea9da2647a1788021bd4de812a371ac0334a Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Aug 07 2013 22:47:09 +0000 Subject: LDAP: Fix crash when processing nested groups https://fedorahosted.org/sssd/ticket/1932 There is a rather strange workaround in the nested groups processing code that calls tevent_req_post outside _send(). However, it broke in certain situations where the tevent_req_call resulted in req being freed, which freed state by extension and then the subsequent _post call was a use-after-free. This patch saves the two variables used outside state so that it's safe to use them even after the callback. --- diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index f52bbb6..1e9fb6d 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -3224,14 +3224,20 @@ static errno_t sdap_nested_group_lookup_user(struct tevent_req *req, return ret; } else if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, ("All done.\n")); + + /* Calling tevent req done might invoke callback which would + * zero out state */ + bool is_finished = state->send_finished; + struct tevent_context *ev = state->ev; + tevent_req_done(req); /** * FIXME: Rewrite nested group processing so we call * tevent_req_post() only in _send(). */ - if (state->send_finished == false) { - tevent_req_post(req, state->ev); + if (is_finished == false) { + tevent_req_post(req, ev); } } return EOK; @@ -3288,14 +3294,20 @@ static errno_t sdap_nested_group_lookup_group(struct tevent_req *req) return ret; } else if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, ("All done.\n")); + + /* Calling tevent req done might invoke callback which would + * zero out state */ + bool is_finished = state->send_finished; + struct tevent_context *ev = state->ev; + tevent_req_done(req); /** * FIXME: Rewrite nested group processing so we call * tevent_req_post() only in _send(). */ - if (state->send_finished == false) { - tevent_req_post(req, state->ev); + if (is_finished == false) { + tevent_req_post(req, ev); } } return EOK;