diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2013-08-06 21:15:42 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-08-09 16:00:46 +0200 |
commit | 49bc313040d96acab37f67c57d22bffac8fbe9c4 (patch) | |
tree | 6d15c1504a8c1b830e3bff2a03d52336c4ac7ca8 /src/providers/ldap/sdap_async_groups.c | |
parent | 049bf68953209ab200150b330f97eed3b9da9e67 (diff) | |
download | sssd-49bc313040d96acab37f67c57d22bffac8fbe9c4.tar.gz sssd-49bc313040d96acab37f67c57d22bffac8fbe9c4.tar.xz sssd-49bc313040d96acab37f67c57d22bffac8fbe9c4.zip |
LDAP: Fix crash when processing nested groupssssd-1.9.2-116.el6
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.
Diffstat (limited to 'src/providers/ldap/sdap_async_groups.c')
-rw-r--r-- | src/providers/ldap/sdap_async_groups.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index 55111783c..9a1d66daa 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -3220,14 +3220,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; @@ -3284,14 +3290,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; |