]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: server: fix a leak when completing a named default-server
authorAlexandre Laroche <larochealexandre@hotmail.com>
Fri, 6 Nov 2026 08:42:19 +0000 (03:42 -0500)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 6 Nov 2026 15:35:24 +0000 (16:35 +0100)
A named default-server may be defined over several lines, each line
completing the previous one, as documented and as exercised by
reg-tests/server/from_keyword.vtc. In _srv_parse_init(), the name is
duplicated with strdup() before being looked up in defsrv_by_name.
When the lookup finds the existing default-server, the copy is neither
stored nor freed, so every line after the first one leaks it.

The leak only happens at configuration load and is limited to the name
length plus one byte per line, so the impact is minimal, but it is
reported by LeakSanitizer, e.g. "haproxy -c" built with
-fsanitize=address on a configuration defining the same
"default-server name other ..." on several lines.

Fix it by freeing the copy when an existing default-server is found,
since that one already owns its name. The code path is already covered
by reg-tests/server/from_keyword.vtc, so no new regression test is
added.

This was introduced with named default-servers by commit 507f790af
("MEDIUM: proxy: implement named default-server") in 3.5-dev4, so no
backport is needed.

This fixes GitHub issue #3562.

src/server.c

index 10659b8ad10219688ea9eeb636eba2dd5d3b6d20..afbe589e04efb440d32867ca280d3b27810aec77 100644 (file)
@@ -3962,6 +3962,9 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
                        newsrv = cebuis_item_lookup(&curproxy->defsrv_by_name,
                                                    conf.name_node, id, name,
                                                    struct server);
+                       /* an existing default-server already owns its name */
+                       if (newsrv)
+                               ha_free(&name);
                }
                else {
                        /* unnamed default-server instance */