URL: https://github.com/SSSD/sssd/pull/821 Author: thalman Title: #821: SERVER: Receving SIGSEGV process on shutdown Action: synchronized
To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/821/head:pr821 git checkout pr821
From 34e89dbdd435e12b0f6f241a7052cf5b84e300b2 Mon Sep 17 00:00:00 2001 From: Tomas Halman <[email protected]> Date: Fri, 31 May 2019 10:31:29 +0200 Subject: [PATCH 1/3] SERVER: Receving SIGSEGV process on shutdown There is race condition when dynamic libraries are unloaded. Talloc library calls our destructors but they still need openssl calls which might be not available. Solution is to free explicitly memory context and trigger destructors before calling exit(). Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1672584 --- src/util/server.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/util/server.c b/src/util/server.c index 70f86e9bdc..dd97e07b80 100644 --- a/src/util/server.c +++ b/src/util/server.c @@ -234,7 +234,7 @@ int pidfile(const char *file) void orderly_shutdown(int status) { #if HAVE_GETPGRP - static int sent_sigterm; + static int sent_sigterm = 0; int debug; if (sent_sigterm == 0 && getpgrp() == getpid()) { @@ -256,6 +256,11 @@ static void default_quit(struct tevent_context *ev, void *siginfo, void *private_data) { + struct main_context *ctx = talloc_get_type(private_data, struct main_context); + if (ctx) { + talloc_free(ctx); + } + orderly_shutdown(0); } @@ -540,26 +545,26 @@ int server_setup(const char *name, int flags, return 1; } + ctx = talloc(event_ctx, struct main_context); + if (ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory, aborting!\n"); + return ENOMEM; + } + /* Set up an event handler for a SIGINT */ tes = tevent_add_signal(event_ctx, event_ctx, SIGINT, 0, - default_quit, NULL); + default_quit, ctx); if (tes == NULL) { return EIO; } /* Set up an event handler for a SIGTERM */ tes = tevent_add_signal(event_ctx, event_ctx, SIGTERM, 0, - default_quit, NULL); + default_quit, ctx); if (tes == NULL) { return EIO; } - ctx = talloc(event_ctx, struct main_context); - if (ctx == NULL) { - DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory, aborting!\n"); - return ENOMEM; - } - ctx->parent_pid = getppid(); ctx->event_ctx = event_ctx; From 7a08f8556ed6461950b47a91d6631e2d7efd9e8d Mon Sep 17 00:00:00 2001 From: Tomas Halman <[email protected]> Date: Fri, 31 May 2019 15:08:20 +0200 Subject: [PATCH 2/3] krb5: Free resources on exit We hit a race condition when unloading talloc and openssl libraries. Here we explicitly free krb5 backend before calling exit(). Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1672584 --- src/providers/krb5/krb5_common.c | 26 +++++++------------------- src/providers/krb5/krb5_common.h | 2 +- src/providers/krb5/krb5_init_shared.c | 2 +- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index f188dc8415..b4de7fecf3 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -1141,38 +1141,26 @@ void krb5_finalize(struct tevent_context *ev, void *siginfo, void *private_data) { + struct be_ctx *be_ctx; + + be_ctx = talloc_get_type(private_data, struct be_ctx); + talloc_free(be_ctx); orderly_shutdown(0); } -errno_t krb5_install_sigterm_handler(struct tevent_context *ev, +errno_t krb5_install_sigterm_handler(struct be_ctx *be_ctx, struct krb5_ctx *krb5_ctx) { - const char *krb5_realm; - char *sig_realm; struct tevent_signal *sige; BlockSignals(false, SIGTERM); - krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); - if (krb5_realm == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Missing krb5_realm option!\n"); - return EINVAL; - } - - sig_realm = talloc_strdup(krb5_ctx, krb5_realm); - if (sig_realm == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); - return ENOMEM; - } - - sige = tevent_add_signal(ev, krb5_ctx, SIGTERM, SA_SIGINFO, krb5_finalize, - sig_realm); + sige = tevent_add_signal(be_ctx->ev, krb5_ctx, SIGTERM, SA_SIGINFO, krb5_finalize, + be_ctx); if (sige == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n"); - talloc_free(sig_realm); return ENOMEM; } - talloc_steal(sige, sig_realm); return EOK; } diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h index 441c52b342..8c216eef84 100644 --- a/src/providers/krb5/krb5_common.h +++ b/src/providers/krb5/krb5_common.h @@ -203,7 +203,7 @@ void krb5_finalize(struct tevent_context *ev, void *siginfo, void *private_data); -errno_t krb5_install_sigterm_handler(struct tevent_context *ev, +errno_t krb5_install_sigterm_handler(struct be_ctx *be_ctx, struct krb5_ctx *krb5_ctx); errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm); diff --git a/src/providers/krb5/krb5_init_shared.c b/src/providers/krb5/krb5_init_shared.c index 368d6f7b0f..7198e5c837 100644 --- a/src/providers/krb5/krb5_init_shared.c +++ b/src/providers/krb5/krb5_init_shared.c @@ -71,7 +71,7 @@ errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx, goto done; } - ret = krb5_install_sigterm_handler(bectx->ev, krb5_auth_ctx); + ret = krb5_install_sigterm_handler(bectx, krb5_auth_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_sigterm_handler failed.\n"); goto done; From 3a35a0461d5c86476e33e6332010c858915ebd55 Mon Sep 17 00:00:00 2001 From: Tomas Halman <[email protected]> Date: Fri, 31 May 2019 15:31:02 +0200 Subject: [PATCH 3/3] ldap: Free resources on exit We hit a race condition when unloading talloc and openssl libraries. Here we explicitly free LDAP connection before calling exit(). Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1672584 --- src/providers/ldap/ldap_common.c | 28 +++++++++++++--------------- src/providers/ldap/ldap_common.h | 4 ++-- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index cd8d2a10c7..1952828a3c 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -158,32 +158,30 @@ static void sdap_finalize(struct tevent_context *ev, void *siginfo, void *private_data) { + struct sdap_id_ctx *sdap_id_ctx; + + sdap_id_ctx = talloc_get_type(private_data, struct sdap_id_ctx); + if (sdap_id_ctx != NULL) { + talloc_zfree(sdap_id_ctx->conn); + } + orderly_shutdown(0); } -errno_t sdap_install_sigterm_handler(TALLOC_CTX *mem_ctx, +errno_t sdap_install_sigterm_handler(struct sdap_id_ctx *sdap_id_ctx, struct tevent_context *ev, const char *realm) { - char *sig_realm; struct tevent_signal *sige; BlockSignals(false, SIGTERM); - sig_realm = talloc_strdup(mem_ctx, realm); - if (sig_realm == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); - return ENOMEM; - } - - sige = tevent_add_signal(ev, mem_ctx, SIGTERM, SA_SIGINFO, sdap_finalize, - sig_realm); + sige = tevent_add_signal(ev, sdap_id_ctx, SIGTERM, SA_SIGINFO, sdap_finalize, + sdap_id_ctx); if (sige == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n"); - talloc_free(sig_realm); return ENOMEM; } - talloc_steal(sige, sig_realm); return EOK; } @@ -322,7 +320,7 @@ const char *sdap_gssapi_realm(struct dp_option *opts) return realm; } -int sdap_gssapi_init(TALLOC_CTX *mem_ctx, +int sdap_gssapi_init(struct sdap_id_ctx *sdap_id_ctx, struct dp_option *opts, struct be_ctx *bectx, struct sdap_service *sdap_service, @@ -368,7 +366,7 @@ int sdap_gssapi_init(TALLOC_CTX *mem_ctx, &n_lookahead_primary, &n_lookahead_backup); - ret = krb5_service_init(mem_ctx, bectx, + ret = krb5_service_init(sdap_id_ctx, bectx, SSS_KRB5KDC_FO_SRV, krb5_servers, krb5_backup_servers, krb5_realm, dp_opt_get_bool(opts, @@ -381,7 +379,7 @@ int sdap_gssapi_init(TALLOC_CTX *mem_ctx, goto done; } - ret = sdap_install_sigterm_handler(mem_ctx, bectx->ev, krb5_realm); + ret = sdap_install_sigterm_handler(sdap_id_ctx, bectx->ev, krb5_realm); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to install sigterm handler\n"); goto done; diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index 5d6302dcd1..d7464f653e 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -176,7 +176,7 @@ void sdap_service_reset_fo(struct be_ctx *ctx, const char *sdap_gssapi_realm(struct dp_option *opts); -int sdap_gssapi_init(TALLOC_CTX *mem_ctx, +int sdap_gssapi_init(struct sdap_id_ctx *sdap_id_ctx, struct dp_option *opts, struct be_ctx *bectx, struct sdap_service *sdap_service, @@ -187,7 +187,7 @@ errno_t sdap_install_offline_callback(TALLOC_CTX *mem_ctx, const char *realm, const char *service_name); -errno_t sdap_install_sigterm_handler(TALLOC_CTX *mem_ctx, +errno_t sdap_install_sigterm_handler(struct sdap_id_ctx *sdap_id_ctx, struct tevent_context *ev, const char *realm);
_______________________________________________ sssd-devel mailing list -- [email protected] To unsubscribe send an email to [email protected] Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/[email protected]
