]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: init: Use a dynamic buffer to set HAPROXY_CFGFILES env variable
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 12 Jan 2021 17:57:38 +0000 (18:57 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 13 Jan 2021 16:45:25 +0000 (17:45 +0100)
The HAPROXY_CFGFILES env variable is built using a static trash chunk, via a
call to get_trash_chunk() function. This chunk is reserved during the whole
configuration parsing. It is far too large to guarantee it will not be
reused during the configuration parsing. And in fact, it happens in the lua
code since the commit f67442efd ("BUG/MINOR: lua: warn when registering
action, conv, sf, cli or applet multiple times"), when a lua script is
loaded.

To fix the bug, we now use a dynamic buffer instead. And we call memprintf()
function to handle both the allocation and the formatting. Allocation errors
at this stage are fatal.

This patch should fix the issue #1041. It must be backported as far as 2.0.

src/haproxy.c

index 7612e4c451ead3302fd6294788f212f8b7532149..e36e020c5ce771a6d891feb7e117ecb10f487385 100644 (file)
@@ -1826,7 +1826,8 @@ static void init(int argc, char **argv)
 
        /* in wait mode, we don't try to read the configuration files */
        if (!(global.mode & MODE_MWORKER_WAIT)) {
-               struct buffer *trash = get_trash_chunk();
+               char *env_cfgfiles = NULL;
+               int env_err = 0;
 
                /* handle cfgfiles that are actually directories */
                cfgfiles_expand_directories();
@@ -1838,22 +1839,27 @@ static void init(int argc, char **argv)
                list_for_each_entry(wl, &cfg_cfgfiles, list) {
                        int ret;
 
-                       if (trash->data)
-                               chunk_appendf(trash, ";");
-
-                       chunk_appendf(trash, "%s", wl->s);
+                       if (env_err == 0) {
+                               if (!memprintf(&env_cfgfiles, "%s%s%s",
+                                              (env_cfgfiles ? env_cfgfiles : ""),
+                                              (env_cfgfiles ? ";" : ""), wl->s))
+                                       env_err = 1;
+                       }
 
                        ret = readcfgfile(wl->s);
                        if (ret == -1) {
                                ha_alert("Could not open configuration file %s : %s\n",
                                         wl->s, strerror(errno));
+                               free(env_cfgfiles);
                                exit(1);
                        }
                        if (ret & (ERR_ABORT|ERR_FATAL))
                                ha_alert("Error(s) found in configuration file : %s\n", wl->s);
                        err_code |= ret;
-                       if (err_code & ERR_ABORT)
+                       if (err_code & ERR_ABORT) {
+                               free(env_cfgfiles);
                                exit(1);
+                       }
                }
 
                /* do not try to resolve arguments nor to spot inconsistencies when
@@ -1862,10 +1868,15 @@ static void init(int argc, char **argv)
                 */
                if (err_code & (ERR_ABORT|ERR_FATAL)) {
                        ha_alert("Fatal errors found in configuration.\n");
+                       free(env_cfgfiles);
+                       exit(1);
+               }
+               if (env_err) {
+                       ha_alert("Could not allocate memory for HAPROXY_CFGFILES env variable\n");
                        exit(1);
                }
-               if (trash->data)
-                       setenv("HAPROXY_CFGFILES", trash->area, 1);
+               setenv("HAPROXY_CFGFILES", env_cfgfiles, 1);
+               free(env_cfgfiles);
 
        }
        if (global.mode & MODE_MWORKER) {