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 ceb3163266f191679e9cf0af17be9b3e902566a8 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 | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/util/server.c b/src/util/server.c
index 70f86e9bdc..35cad82770 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,9 @@ 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);
+    talloc_free(ctx);
+
     orderly_shutdown(0);
 }
 
@@ -540,26 +543,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 b480be9705518323ea97d8199a9b9ce014ff7643 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 39b5afe895c98254870156d441b8e918da456ea4 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://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/[email protected]

Reply via email to