From 50bf172a2c4d448145a2061dfbaa5ee2a413874e Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Thu, 23 Nov 2023 14:28:14 +0100
Subject: [PATCH] BUG/MINOR: server: do not leak default-server in defaults
 sections
 
When a default-server directive is used in a defaults section, it's never
freed and the "defaults" proxy gets reset without freeing the fields from
that default-server. Normally there are no allocation there, except for
the config file location stored in srv->conf.file form an strdup() since
commit 9394a9444 ("REORG: server: move alert traces in parse_server")
that appeared in 2.4. In addition, if a "default-server" directive
appears multiple times in a defaults section, one more entry will be
leaked per call.
 
This commit addresses this by checking that we don't overwrite the file
upon multiple calls, and by clearing it when resetting the default proxy.
This should be backported to 2.4.
 
(cherry picked from commit 53da8bfcb6d3f4918a45fe77347317ad885ba25e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 8bb771af10bf68ffb46edba4bb601bd2a79ff5bd)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 0810c8082b5db901f823b554602702ae52881fc1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
 
Conflict: NA
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=50bf172a2c4d448145a2061dfbaa5ee2a413874e
---
 src/proxy.c  | 1 +
 src/server.c | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)
 
diff --git a/src/proxy.c b/src/proxy.c
index dea6004ec..8bfe1175c 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1442,6 +1442,7 @@ void proxy_free_defaults(struct proxy *defproxy)
 
 	ha_free(&defproxy->id);
 	ha_free(&defproxy->conf.file);
+	ha_free((char **)&defproxy->defsrv.conf.file);
 	ha_free(&defproxy->check_command);
 	ha_free(&defproxy->check_path);
 	ha_free(&defproxy->cookie_name);
diff --git a/src/server.c b/src/server.c
index a927811a9..eb78cc02e 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2927,7 +2927,8 @@ int parse_server(const char *file, int linenum, char **args,
 	if (err_code & ERR_CODE)
 		goto out;
 
-	newsrv->conf.file = strdup(file);
+	if (!newsrv->conf.file) // note: do it only once for default-server
+		newsrv->conf.file = strdup(file);
 	newsrv->conf.line = linenum;
 
 	while (*args[cur_arg]) {
-- 
2.33.0