From 30d38e7f6b118a4f0f401fd868cd7a293770847e Mon Sep 17 00:00:00 2001
From: MIZUTA Takeshi <mizuta.takeshi@fujitsu.com>
Date: Thu, 10 Dec 2020 14:11:57 +0900
Subject: [PATCH] BUG/MINOR: haproxy: Add a check whether the given pid is
 "haproxy"

The -sf/-st option unconditionally sends the signals to the PID specified in
pidlist. If the pidlist contains a non-haproxy process, it sends the signals
to the non-haproxy process. Add a determination of whether the specified
pidlist is a haproxy so that no signal is sent to another process.
---
 src/haproxy.c | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/haproxy.c b/src/haproxy.c
index f6236fb92..45fbfb172 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -676,6 +676,41 @@ static void usage(char *name)
 /*   more specific functions   ***************************************/
 /*********************************************************************/
 
+/* Checks whether the given pid is "haproxy",
+ * based on the process name from /proc/pid/exe.
+ */
+static int is_haproxy_alive(pid_t pid)
+{
+	char proc_path[32]; /* /proc/pid/exe */
+	char fullpath[PATH_MAX];
+	char *procname;
+	ssize_t rsize;
+
+	if (kill(pid, 0) != 0)
+		return 0;
+
+#ifdef __linux__
+	sprintf(proc_path, "/proc/%d/exe", pid);
+
+	memset(fullpath, 0, sizeof(fullpath));
+	rsize = readlink(proc_path, fullpath, sizeof(fullpath));
+	if (rsize < 0) {
+		if (errno != ENOENT) {
+			ha_alert("Cannot read procfile. %s (%s)\n", proc_path, strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+		return 0;
+	}
+
+	procname = basename(fullpath);
+	if (strcmp(procname, "haproxy")) {
+	        /* pid is not haproxy */
+	        return 0;
+	}
+#endif
+	return 1;
+}
+
 /* sends the signal <sig> to all pids found in <oldpids>. Returns the number of
  * pids the signal was correctly delivered to.
  */
@@ -684,8 +719,9 @@ int tell_old_pids(int sig)
 	int p;
 	int ret = 0;
 	for (p = 0; p < nb_oldpids; p++)
-		if (kill(oldpids[p], sig) == 0)
-			ret++;
+		if (is_haproxy_alive(oldpids[p]))
+			if (kill(oldpids[p], sig) == 0)
+				ret++;
 	return ret;
 }
 
-- 
2.26.2

