From 2efc64944726cec78d87210cd5fba67b24d686b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20L=C3=A9caille?= Date: Tue, 14 Mar 2017 14:32:17 +0100 Subject: [PATCH] BUG/MINOR: cfgparse: loop in tracked servers lists not detected by check_config_validity(). There is a silly case where a loop is not detected in tracked servers lists: when a server tracks itself. Ex: server srv1 127.0.0.1:8000 track srv1 Well, this never happens and this does not prevent haproxy from working. But with this next following configuration: server srv1 127.0.0.1:8000 track srv2 server srv2 127.0.0.1:8000 track srv2 server srv3 127.0.0.1:8000 track srv2 the code in charge of detecting such loops never returns (without any error message). haproxy becomes stuck in an infinite loop because of this statement found in check_config_validity(): for (loop = srv->track; loop && loop != newsrv; loop = loop->track); Again, such a configuration is never accidentally used I guess. This latter example seems silly, but as several 'default-server' directives may be used in the same proxy section, and as 'default-server' settings are not resetted each a new 'default-server' line is created, it will match the following configuration, in the future, when 'track' setting will be supported by 'default-server': default-server track srv3 server srv1 127.0.0.1:8000 server srv2 127.0.0.1:8000 . . . default-server check server srv3 127.0.0.1:8000 (cherry picked from commit 6528fc93d3c065fdac841f24e55cfe9674a67414) --- src/cfgparse.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cfgparse.c b/src/cfgparse.c index 2eb25edb5..b03a8214d 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -8396,11 +8396,12 @@ out_uri_auth_compat: for (loop = srv->track; loop && loop != newsrv; loop = loop->track); - if (loop) { + if (newsrv == srv || loop) { Alert("config : %s '%s', server '%s': unable to track %s/%s as it " "belongs to a tracking chain looping back to %s/%s.\n", proxy_type_str(curproxy), curproxy->id, - newsrv->id, px->id, srv->id, px->id, loop->id); + newsrv->id, px->id, srv->id, px->id, + newsrv == srv ? srv->id : loop->id); cfgerr++; goto next_srv; }