From 054443dfb908521e30aa57335dbcb5f9cd6f7218 Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Thu, 6 Mar 2025 09:29:05 +0100 Subject: [PATCH] BUG/MINOR: cfgparse/peers: properly handle ignored local peer case In 8ba10fea6 ("BUG/MINOR: peers: Incomplete peers sections should be validated."), some checks were relaxed in parse_server(), and extra logic was added in the peers section parser in an attempt to properly ignore incomplete "server" or "peer" statement under peers section. This was done in response to GH #565, the main intent was that haproxy should already complain about incomplete peers section (ie: missing localpeer). However, 8ba10fea69 explicitly skipped the peer cleanup upon missing srv association for local peers. This is wrong because later haproxy code always assumes that peer->srv is valid. Indeed, we got reports that the (invalid) config below would cause segmentation fault on all stable versions: global localpeer 01JM0TEPAREK01FQQ439DDZXD8 peers my-table peer 01JM0TEPAREK01FQQ439DDZXD8 listen dummy bind localhost:8080 To fix the issue, instead of by-passing some cleanup for the local peer, handle this case specifically by doing the regular peer cleanup and reset some fields set on the curpeers and curpeers proxy because of the invalid local peer (do as if the peer was not declared). It should still comply with requirements from #565. This patch should be backported to all stable versions. --- src/cfgparse.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/cfgparse.c b/src/cfgparse.c index bf8d7a6c0..ab49a73b3 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -893,13 +893,18 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) /* parse_server didn't add a server: * Remove the newly allocated peer. */ - if (newpeer != curpeers->local) { - struct peer *p; + struct peer *p; - p = curpeers->remote; - curpeers->remote = curpeers->remote->next; - free(p->id); - free(p); + p = curpeers->remote; + curpeers->remote = curpeers->remote->next; + free(p->id); + free(p); + if (newpeer == curpeers->local) { + /* reset curpeers and curpeers fields + * that are local peer related + */ + curpeers->local = NULL; + ha_free(&curpeers->peers_fe->id); } goto out; }