00db14
From 19d0482859d9068b893104b9f8beeaba709aec2d Mon Sep 17 00:00:00 2001
00db14
From: Quentin Armitage <quentin@armitage.org.uk>
00db14
Date: Mon, 27 Mar 2017 11:28:02 +0100
00db14
Subject: [PATCH 2/3] Don't segfault if unable to load ip_vs module
00db14
00db14
In a docker container it isn't possible to load a kernel module. The
00db14
check code was detecting that it couldn't load the module, but the
00db14
checker process, when cleaning up prior to exiting, was assuming that
00db14
certain pointers had been initialised which hadn't been when an error
00db14
was detected so early in the initialisation.
00db14
00db14
This commit adds testing for uninitialised pointers during the exit
00db14
sequence.
00db14
00db14
Signed-off-by: Quentin Armitage <quentin@armitage.org.uk>
00db14
---
00db14
 keepalived/check/check_api.c         | 3 +++
00db14
 keepalived/check/check_daemon.c      | 8 +++++---
00db14
 keepalived/check/check_data.c        | 7 ++++++-
00db14
 keepalived/check/ipvswrapper.c       | 9 ++++++---
00db14
 keepalived/check/ipwrapper.c         | 6 ++++--
00db14
 keepalived/check/libipvs.c           | 5 ++++-
00db14
 keepalived/core/keepalived_netlink.c | 7 ++++---
00db14
 7 files changed, 32 insertions(+), 13 deletions(-)
00db14
00db14
diff --git a/keepalived/check/check_api.c b/keepalived/check/check_api.c
00db14
index 51d8cc71..b7081fd0 100644
00db14
--- a/keepalived/check/check_api.c
00db14
+++ b/keepalived/check/check_api.c
00db14
@@ -224,6 +224,9 @@ init_checkers_queue(void)
00db14
 void
00db14
 free_checkers_queue(void)
00db14
 {
00db14
+	if (!checkers_queue)
00db14
+		return;
00db14
+
00db14
 	free_list(&checkers_queue);
00db14
 	ncheckers = 0;
00db14
 }
00db14
diff --git a/keepalived/check/check_daemon.c b/keepalived/check/check_daemon.c
00db14
index a87fd4cd..a3ff8cab 100644
00db14
--- a/keepalived/check/check_daemon.c
00db14
+++ b/keepalived/check/check_daemon.c
00db14
@@ -74,7 +74,7 @@ stop_check(int status)
00db14
 		clear_services();
00db14
 	ipvs_stop();
00db14
 #ifdef _WITH_SNMP_CHECKER_
00db14
-	if (global_data->enable_snmp_checker)
00db14
+	if (global_data && global_data->enable_snmp_checker)
00db14
 		check_snmp_agent_close();
00db14
 #endif
00db14
 
00db14
@@ -82,8 +82,10 @@ stop_check(int status)
00db14
 	pidfile_rm(checkers_pidfile);
00db14
 
00db14
 	/* Clean data */
00db14
-	free_global_data(global_data);
00db14
-	free_check_data(check_data);
00db14
+	if (global_data)
00db14
+		free_global_data(global_data);
00db14
+	if (check_data)
00db14
+		free_check_data(check_data);
00db14
 	free_parent_mallocs_exit();
00db14
 
00db14
 	/*
00db14
diff --git a/keepalived/check/check_data.c b/keepalived/check/check_data.c
00db14
index 0c3f1940..6ce87229 100644
00db14
--- a/keepalived/check/check_data.c
00db14
+++ b/keepalived/check/check_data.c
00db14
@@ -51,7 +51,12 @@ alloc_ssl(void)
00db14
 void
00db14
 free_ssl(void)
00db14
 {
00db14
-	ssl_data_t *ssl = check_data->ssl;
00db14
+	ssl_data_t *ssl;
00db14
+       
00db14
+	if (!check_data)
00db14
+		return;
00db14
+
00db14
+	ssl = check_data->ssl;
00db14
 
00db14
 	if (!ssl)
00db14
 		return;
00db14
diff --git a/keepalived/check/ipvswrapper.c b/keepalived/check/ipvswrapper.c
00db14
index cd7f169e..20757c94 100644
00db14
--- a/keepalived/check/ipvswrapper.c
00db14
+++ b/keepalived/check/ipvswrapper.c
00db14
@@ -165,9 +165,12 @@ void
00db14
 ipvs_stop(void)
00db14
 {
00db14
 	/* Clean up the room */
00db14
-	FREE(srule);
00db14
-	FREE(drule);
00db14
-	FREE(daemonrule);
00db14
+	if (srule)
00db14
+		FREE(srule);
00db14
+	if (drule)
00db14
+		FREE(drule);
00db14
+	if (daemonrule)
00db14
+		FREE(daemonrule);
00db14
 	ipvs_close();
00db14
 }
00db14
 
00db14
diff --git a/keepalived/check/ipwrapper.c b/keepalived/check/ipwrapper.c
00db14
index 0c2fc46b..ecf12713 100644
00db14
--- a/keepalived/check/ipwrapper.c
00db14
+++ b/keepalived/check/ipwrapper.c
00db14
@@ -138,10 +138,12 @@ void
00db14
 clear_services(void)
00db14
 {
00db14
 	element e;
00db14
-	list l = check_data->vs;
00db14
 	virtual_server_t *vs;
00db14
 
00db14
-	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
00db14
+	if (!check_data || !check_data->vs)
00db14
+		return;
00db14
+
00db14
+	for (e = LIST_HEAD(check_data->vs); e; ELEMENT_NEXT(e)) {
00db14
 		vs = ELEMENT_DATA(e);
00db14
 		clear_service_vs(vs);
00db14
 	}
00db14
diff --git a/keepalived/check/libipvs.c b/keepalived/check/libipvs.c
00db14
index 2250e2b4..8722f7a6 100644
00db14
--- a/keepalived/check/libipvs.c
00db14
+++ b/keepalived/check/libipvs.c
00db14
@@ -1157,7 +1157,10 @@ void ipvs_close(void)
00db14
 	if (try_nl)
00db14
 		return;
00db14
 #endif
00db14
-	close(sockfd);
00db14
+	if (sockfd != -1) {
00db14
+		close(sockfd);
00db14
+		sockfd = -1;
00db14
+	}
00db14
 }
00db14
 
00db14
 const char *ipvs_strerror(int err)
00db14
diff --git a/keepalived/core/keepalived_netlink.c b/keepalived/core/keepalived_netlink.c
00db14
index 41e63b85..0f465cf5 100644
00db14
--- a/keepalived/core/keepalived_netlink.c
00db14
+++ b/keepalived/core/keepalived_netlink.c
00db14
@@ -251,9 +251,12 @@ netlink_socket(nl_handle_t *nl, int flags, int group, ...)
00db14
 }
00db14
 
00db14
 /* Close a netlink socket */
00db14
-static int
00db14
+static void
00db14
 netlink_close(nl_handle_t *nl)
00db14
 {
00db14
+	if (!nl)
00db14
+		return;
00db14
+
00db14
 	/* First of all release pending thread */
00db14
 	thread_cancel(nl->thread);
00db14
 
00db14
@@ -269,8 +272,6 @@ netlink_close(nl_handle_t *nl)
00db14
 #endif
00db14
 		close(nl->fd);
00db14
 #endif
00db14
-
00db14
-	return 0;
00db14
 }
00db14
 
00db14
 #ifdef _WITH_VRRP_
00db14
-- 
00db14
2.13.5
00db14