]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: peers: Fix memory leak in cfg_parse_peers
authorTim Duesterhus <tim@bastelstu.be>
Sun, 12 May 2019 20:54:50 +0000 (22:54 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 13 May 2019 08:10:01 +0000 (10:10 +0200)
cfg_parse_peers previously leaked the contents of the `kws` string,
as it was unconditionally filled using bind_dump_kws, but only used
(and freed) within the error case.

Move the dumping into the error case to:
1. Ensure that the registered keywords are actually printed as least once.
2. The contents of kws are not leaked.

This move allows to narrow the scope of `kws`, so this is done as well.

This bug was found using valgrind:

    ==28217== 590 bytes in 1 blocks are definitely lost in loss record 51 of 71
    ==28217==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==28217==    by 0x4AD4C7: indent_msg (standard.c:3676)
    ==28217==    by 0x47E962: cfg_parse_peers (cfgparse.c:700)
    ==28217==    by 0x480273: readcfgfile (cfgparse.c:2147)
    ==28217==    by 0x479D51: init (haproxy.c:1585)
    ==28217==    by 0x404A02: main (haproxy.c:2585)

with this super simple configuration:

    peers peers
     bind :8081
     server A

This bug exists since the introduction of cfg_parse_peers in commit
355b2033ec0c89660db179b23d6f77b678d8c26d (which was introduced for HAProxy
2.0, but marked as backportable). It should be backported to all branches
containing that commit.

src/cfgparse.c

index 3188d50e840fae1ac625202387b8100549e7894c..ab5a2eb75c1f3f16edf1280e43245ef7517e0a68 100644 (file)
@@ -616,7 +616,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                static int kws_dumped;
                struct bind_conf *bind_conf;
                struct bind_kw *kw;
-               char *kws;
 
                cur_arg = 1;
 
@@ -693,13 +692,14 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
                        }
                        cur_arg += 1 + kw->skip;
                }
-               kws = NULL;
-               if (!kws_dumped) {
-                       kws_dumped = 1;
-                       bind_dump_kws(&kws);
-                       indent_msg(&kws, 4);
-               }
                if (*args[cur_arg] != 0) {
+                       char *kws = NULL;
+
+                       if (!kws_dumped) {
+                               kws_dumped = 1;
+                               bind_dump_kws(&kws);
+                               indent_msg(&kws, 4);
+                       }
                        ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.%s%s\n",
                                 file, linenum, args[cur_arg], cursection,
                                 kws ? " Registered keywords :" : "", kws ? kws: "");