]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: cfgparse: fix NULL ptr dereference in cfg_parse_peers
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Thu, 20 Feb 2025 14:00:38 +0000 (15:00 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 20 Feb 2025 16:10:26 +0000 (17:10 +0100)
When "peers" keyword is followed by more than one argument and it's the first
"peers" section in the config, cfg_parse_peers() detects it and exits with
"ERR_ALERT|ERR_FATAL" err_code.

So, upper layer parser, parse_cfg(), continues and parses the next keyword
"peer" and then he tries to check the global cfg_peers, which should contain
"my_cluster". The global cfg_peers is still NULL, because after alerting a user
in alertif_too_many_args, cfg_parse_peers() exited.

peers my_cluster __some_wrong_data__
peer haproxy1 1.1.1.1 1000

In order to fix this, let's add ERR_ABORT, if "peers" keyword is followed by
more than one argument. Like this parse_cfg() will stops immediately and
terminates haproxy with "too many args for peers my_cluster..." alert message.

It's more reliable, than add checks "if (cfg_peers !=NULL)" in "peer"
subparser, as we may have many "peers" sections.

peers my_another_cluster
peer haproxy1 1.1.1.2 1000

peers my_cluster  __some_wrong_data__
peer haproxy1 1.1.1.1 1000

In addition, for the example above, parse_cfg() will parse all configuration
until the end and only then terminates haproxy with the alert
"too many args...". Peer haproxy1 will be wrongly associated with
my_another_cluster.

This fixes the issue #2872.
This should be backported in all stable versions.

src/cfgparse.c

index 381759a2af47b302707483da860714562d059110..75d044fb8a39334cf1a927853fc137b533e81da0 100644 (file)
@@ -794,8 +794,10 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                        goto out;
                }
 
-               if (alertif_too_many_args(1, file, linenum, args, &err_code))
+               if (alertif_too_many_args(1, file, linenum, args, &err_code)) {
+                       err_code |= ERR_ABORT;
                        goto out;
+               }
 
                err = invalid_char(args[1]);
                if (err) {