]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: cfgparse/peers: properly handle ignored local peer case
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 6 Mar 2025 08:29:05 +0000 (09:29 +0100)
committerAurelien DARRAGON <adarragon@haproxy.com>
Thu, 6 Mar 2025 21:05:29 +0000 (22:05 +0100)
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

index bf8d7a6c027ae953db1c008ab6115789b4413ca0..ab49a73b3c86aa193006046a5dd74b4cd1333e0c 100644 (file)
@@ -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;
                }