diff options
author | Pavel Březina <pbrezina@redhat.com> | 2012-10-02 15:22:32 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2012-10-11 12:24:54 +0200 |
commit | 20ae5925d2963937dfc6a66017c05bb018cedd3f (patch) | |
tree | 4bf2d70afa531e0484efd1c476020c0a299e9c2f /src/responder | |
parent | 6b45f632759293fc9f2a28317fae2e224ac53020 (diff) | |
download | sssd-20ae5925d2963937dfc6a66017c05bb018cedd3f.tar.gz sssd-20ae5925d2963937dfc6a66017c05bb018cedd3f.tar.xz sssd-20ae5925d2963937dfc6a66017c05bb018cedd3f.zip |
do not call dp callbacks when responder is shutting down
https://fedorahosted.org/sssd/ticket/1514
We were experiencing crash duting responder shut down. This happened
when there were some unresolved dp request during the shut down.
The memory hierarchy is main_ctx->specific_ctx->rctx, where
specific_ctx may be one of the pam, nss, sudo, etc. contexts.
If we try to call dp request callback as a result of responder
termination, the specific context is already semi freed, which may
cause crash.
Diffstat (limited to 'src/responder')
-rw-r--r-- | src/responder/common/responder.h | 2 | ||||
-rw-r--r-- | src/responder/common/responder_common.c | 15 | ||||
-rw-r--r-- | src/responder/common/responder_dp.c | 8 |
3 files changed, 25 insertions, 0 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 5bab0d3c3..2903aac00 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -104,6 +104,8 @@ struct resp_ctx { char *default_domain; void *pvt_ctx; + + bool shutting_down; }; struct cli_ctx { diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index 4fa819097..d9f73fe26 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -716,6 +716,18 @@ failed: return EIO; } +static int sss_responder_ctx_destructor(void *ptr) +{ + struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx); + + /* mark that we are shutting down the responder, so it is propagated + * into underlying contexts that are freed right before rctx */ + DEBUG(SSSDBG_TRACE_FUNC, ("Responder is being shut down\n")); + rctx->shutting_down = true; + + return 0; +} + int sss_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb, @@ -745,6 +757,9 @@ int sss_process_init(TALLOC_CTX *mem_ctx, rctx->sock_name = sss_pipe_name; rctx->priv_sock_name = sss_priv_pipe_name; rctx->confdb_service_path = confdb_service_path; + rctx->shutting_down = false; + + talloc_set_destructor((TALLOC_CTX*)rctx, sss_responder_ctx_destructor); ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path, CONFDB_RESPONDER_CLI_IDLE_TIMEOUT, diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c index ca9cb834d..34fc9f349 100644 --- a/src/responder/common/responder_dp.c +++ b/src/responder/common/responder_dp.c @@ -76,6 +76,14 @@ static int sss_dp_req_destructor(void *ptr) sdp_req->pending_reply = NULL; } + /* Do not call callbacks if the responder is shutting down, because + * the top level responder context (pam_ctx, sudo_ctx, ...) may be + * already semi-freed and we may end up accessing freed memory. + */ + if (sdp_req->rctx->shutting_down) { + return 0; + } + /* If there are callbacks that haven't been invoked, return * an error now. */ |