173 lines
6.4 KiB
Diff
173 lines
6.4 KiB
Diff
From 8a8869994745429b3f5535a5d0b91f1d0b2fa723 Mon Sep 17 00:00:00 2001
|
|
From: Sumit Bose <sbose@redhat.com>
|
|
Date: Wed, 29 Mar 2023 12:58:37 +0200
|
|
Subject: [PATCH] fail_over: protect against a segmentation fault
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
A missing server name in struct fo_server will cause a segmentation
|
|
fault. Currently it is unclear why the server name is missing at this
|
|
point. To avoid the segmentation fault it is checked before if the
|
|
server name is missing. Additionally the state of some internal
|
|
structures is added to the debug logs to help debugging why the server
|
|
name is missing.
|
|
|
|
Resolves: https://github.com/SSSD/sssd/issues/6659
|
|
|
|
Reviewed-by: Alejandro López <allopez@redhat.com>
|
|
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
|
|
|
|
Reference: https://github.com/SSSD/sssd/commit/8a8869994745429b3f5535a5d0b91f1d0b2fa723
|
|
Conflict: data_provider_fo.c
|
|
---
|
|
src/providers/data_provider_fo.c | 14 +++++++++
|
|
src/providers/fail_over.c | 53 ++++++++++++++++++++++++++++++++
|
|
src/providers/fail_over.h | 3 ++
|
|
3 files changed, 70 insertions(+)
|
|
|
|
diff --git a/src/external/sizes.m4 b/src/external/sizes.m4
|
|
index c4f00d66ff..0b6b630026 100644
|
|
--- a/src/external/sizes.m4
|
|
+++ b/src/external/sizes.m4
|
|
@@ -9,6 +9,7 @@ AC_CHECK_SIZEOF(long long)
|
|
AC_CHECK_SIZEOF(uid_t)
|
|
AC_CHECK_SIZEOF(gid_t)
|
|
AC_CHECK_SIZEOF(id_t)
|
|
+AC_CHECK_SIZEOF(time_t)
|
|
|
|
if test $ac_cv_sizeof_long_long -lt 8 ; then
|
|
AC_MSG_ERROR([SSSD requires long long of 64-bits])
|
|
|
|
diff --git a/src/util/sss_format.h b/src/util/sss_format.h
|
|
index 9a30417..a9f3770 100644
|
|
--- a/src/util/sss_format.h
|
|
+++ b/src/util/sss_format.h
|
|
@@ -64,5 +64,12 @@
|
|
# error Unexpected sizeof gid_t
|
|
#endif /* SIZEOF_GID_T */
|
|
|
|
+#if SIZEOF_TIME_T == 8
|
|
+# define SPRItime PRId64
|
|
+#elif SIZEOF_TIME_T == 4
|
|
+# define SPRItime PRId32
|
|
+#else
|
|
+# error Unexpected sizeof time_t
|
|
+#endif /*SIZEOF_TIME_T*/
|
|
|
|
#endif /* __SSS_FORMAT_H__ */
|
|
|
|
diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c
|
|
index eca5f2f8e..b0aed54e9 100644
|
|
--- a/src/providers/data_provider_fo.c
|
|
+++ b/src/providers/data_provider_fo.c
|
|
@@ -594,6 +594,14 @@ fail:
|
|
tevent_req_error(req, ret);
|
|
}
|
|
|
|
+static void dump_be_svc_data(const struct be_svc_data *svc)
|
|
+{
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "be_svc_data: name=[%s] last_good_srv=[%s] "
|
|
+ "last_good_port=[%d] last_status_change=[%"SPRItime"]\n",
|
|
+ svc->name, svc->last_good_srv, svc->last_good_port,
|
|
+ svc->last_status_change);
|
|
+}
|
|
+
|
|
errno_t be_resolve_server_process(struct tevent_req *subreq,
|
|
struct be_resolve_server_state *state,
|
|
struct tevent_req **new_subreq)
|
|
@@ -681,6 +689,12 @@ errno_t be_resolve_server_process(struct tevent_req *subreq,
|
|
DEBUG(SSSDBG_FUNC_DATA, "Found address for server %s: [%s] TTL %d\n",
|
|
fo_get_server_str_name(state->srv), ipaddr,
|
|
srvaddr->addr_list[0]->ttl);
|
|
+ } else {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing server name.\n");
|
|
+ dump_be_svc_data(state->svc);
|
|
+ dump_fo_server(state->srv);
|
|
+ dump_fo_server_list(state->srv);
|
|
+ return ENOENT;
|
|
}
|
|
|
|
srv_status_change = fo_get_server_hostname_last_change(state->srv);
|
|
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
|
|
index 9cb26838c..7cb642448 100644
|
|
--- a/src/providers/fail_over.c
|
|
+++ b/src/providers/fail_over.c
|
|
@@ -200,6 +200,59 @@ str_srv_data_status(enum srv_lookup_status status)
|
|
return "unknown SRV lookup status";
|
|
}
|
|
|
|
+static void dump_srv_data(const struct srv_data *srv_data)
|
|
+{
|
|
+ if (srv_data == NULL) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "srv_data is NULL\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "srv_data: dns_domain [%s] discovery_domain [%s] "
|
|
+ "sssd_domain [%s] proto [%s] srv [%s] "
|
|
+ "srv_lookup_status [%s] ttl [%d] "
|
|
+ "last_status_change [%"SPRItime"]\n",
|
|
+ srv_data->dns_domain == NULL ? "dns_domain is NULL"
|
|
+ : srv_data->dns_domain,
|
|
+ srv_data->discovery_domain == NULL ? "discovery_domain is NULL"
|
|
+ : srv_data->discovery_domain,
|
|
+ srv_data->sssd_domain == NULL ? "sssd_domain is NULL"
|
|
+ : srv_data->sssd_domain,
|
|
+ srv_data->proto == NULL ? "proto is NULL"
|
|
+ : srv_data->proto,
|
|
+ srv_data->srv == NULL ? "srv is NULL"
|
|
+ : srv_data->srv,
|
|
+ str_srv_data_status(srv_data->srv_lookup_status),
|
|
+ srv_data->ttl, srv_data->last_status_change.tv_sec);
|
|
+}
|
|
+
|
|
+void dump_fo_server(const struct fo_server *srv)
|
|
+{
|
|
+ DEBUG(SSSDBG_OP_FAILURE, "fo_server: primary [%s] port [%d] "
|
|
+ "port_status [%s] common->name [%s].\n",
|
|
+ srv->primary ? "true" : "false", srv->port,
|
|
+ str_port_status(srv->port_status),
|
|
+ srv->common == NULL ? "common is NULL"
|
|
+ : (srv->common->name == NULL
|
|
+ ? "common->name is NULL"
|
|
+ : srv->common->name));
|
|
+ dump_srv_data(srv->srv_data);
|
|
+}
|
|
+
|
|
+void dump_fo_server_list(const struct fo_server *srv)
|
|
+{
|
|
+ const struct fo_server *s;
|
|
+
|
|
+ s = srv;
|
|
+ while (s->prev != NULL) {
|
|
+ s = s->prev;
|
|
+ }
|
|
+
|
|
+ while (s != NULL) {
|
|
+ dump_fo_server(s);
|
|
+ s = s->next;
|
|
+ }
|
|
+}
|
|
+
|
|
static const char *
|
|
str_server_status(enum server_status status)
|
|
{
|
|
diff --git a/src/providers/fail_over.h b/src/providers/fail_over.h
|
|
index 92a0456b5..36021ad6f 100644
|
|
--- a/src/providers/fail_over.h
|
|
+++ b/src/providers/fail_over.h
|
|
@@ -88,6 +88,9 @@ struct fo_options {
|
|
enum restrict_family family_order;
|
|
};
|
|
|
|
+void dump_fo_server(const struct fo_server *srv);
|
|
+void dump_fo_server_list(const struct fo_server *srv);
|
|
+
|
|
/*
|
|
* Create a new fail over context based on options passed in the
|
|
* opts parameter
|
|
--
|
|
2.27.0
|
|
|