URL: https://github.com/SSSD/sssd/pull/784
Author: pbrezina
 Title: #784: be: remember last good server's name instead of fo_server 
structure
Action: opened

PR body:
"""
This fo_server may be freed when collapsing servers from SRV lookup
in `collapse_srv_lookup`. This would cause crash when we try to
dereference the pointer.

Resolves:
https://pagure.io/SSSD/sssd/issue/XXXX
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/784/head:pr784
git checkout pr784
From a6a4b83389868f04ac29bd6f5481946b52609d6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Fri, 1 Mar 2019 11:07:16 +0100
Subject: [PATCH] be: remember last good server's name instead of fo_server
 structure

This fo_server may be freed when collapsing servers from SRV lookup
in `collapse_srv_lookup`. This would cause crash when we try to
dereference the pointer.

Resolves:
https://pagure.io/SSSD/sssd/issue/XXXX
---
 src/providers/backend.h                         |  2 +-
 src/providers/data_provider/dp_iface_failover.c | 13 +------------
 src/providers/data_provider_fo.c                | 14 ++++++++++++--
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/src/providers/backend.h b/src/providers/backend.h
index 6a34b91a91..1fe1c23136 100644
--- a/src/providers/backend.h
+++ b/src/providers/backend.h
@@ -58,7 +58,7 @@ struct be_svc_data {
     const char *name;
     struct fo_service *fo_service;
 
-    struct fo_server *last_good_srv;
+    char *last_good_srv;
     time_t last_status_change;
     bool run_callbacks;
 
diff --git a/src/providers/data_provider/dp_iface_failover.c b/src/providers/data_provider/dp_iface_failover.c
index 7d95ffdd62..5fe6f35383 100644
--- a/src/providers/data_provider/dp_iface_failover.c
+++ b/src/providers/data_provider/dp_iface_failover.c
@@ -293,18 +293,7 @@ errno_t dp_failover_active_server(struct sbus_request *sbus_req,
         return EOK;
     }
 
-    if (svc->last_good_srv == NULL) {
-        server = "";
-    } else {
-        server = fo_get_server_name(svc->last_good_srv);
-        if (server == NULL) {
-            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get server name\n");
-            sbus_request_reply_error(sbus_req, SBUS_ERROR_INTERNAL,
-                                     "Unable to get server name");
-            return EOK;
-        }
-    }
-
+    server = svc->last_good_srv == NULL ? "" : svc->last_good_srv;
     iface_dp_failover_ActiveServer_finish(sbus_req, server);
     return EOK;
 }
diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c
index 332174e34c..82c587f862 100644
--- a/src/providers/data_provider_fo.c
+++ b/src/providers/data_provider_fo.c
@@ -588,6 +588,7 @@ errno_t be_resolve_server_process(struct tevent_req *subreq,
     errno_t ret;
     time_t srv_status_change;
     struct be_svc_callback *callback;
+    char *srvname;
 
     ret = fo_resolve_service_recv(subreq, state, &state->srv);
     switch (ret) {
@@ -667,13 +668,22 @@ errno_t be_resolve_server_process(struct tevent_req *subreq,
 
     /* now call all svc callbacks if server changed or if it is explicitly
      * requested or if the server is the same but changed status since last time*/
-    if (state->srv != state->svc->last_good_srv ||
+    if (state->svc->last_good_srv == NULL ||
+        strcmp(fo_get_server_name(state->srv), state->svc->last_good_srv) != 0 ||
         state->svc->run_callbacks ||
         srv_status_change > state->svc->last_status_change) {
-        state->svc->last_good_srv = state->srv;
         state->svc->last_status_change = srv_status_change;
         state->svc->run_callbacks = false;
 
+        srvname = talloc_strdup(state->svc, fo_get_server_name(state->srv));
+        if (srvname == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to copy server name\n");
+            return ENOMEM;
+        }
+
+        talloc_free(state->svc->last_good_srv);
+        state->svc->last_good_srv = srvname;
+
         DLIST_FOR_EACH(callback, state->svc->callbacks) {
             callback->fn(callback->private_data, state->srv);
         }
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
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/sssd-devel@lists.fedorahosted.org

Reply via email to