summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2013-08-06 21:15:42 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-08-09 16:00:46 +0200
commit49bc313040d96acab37f67c57d22bffac8fbe9c4 (patch)
tree6d15c1504a8c1b830e3bff2a03d52336c4ac7ca8
parent049bf68953209ab200150b330f97eed3b9da9e67 (diff)
downloadsssd-1.9.2-116.el6.tar.gz
sssd-1.9.2-116.el6.tar.xz
sssd-1.9.2-116.el6.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.
-rw-r--r--src/providers/ldap/sdap_async_groups.c20
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;