From c539632ec1422c528776fe8e3f1e480d5726a416 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 12 Jan 2021 18:57:38 +0100 Subject: [PATCH] BUG/MINOR: init: Use a dynamic buffer to set HAPROXY_CFGFILES env variable 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. (cherry picked from commit 4e36682d51f4e206c63d792a8cde3e669fb8a0d4) Signed-off-by: Christopher Faulet (cherry picked from commit 33edd5101136f9e0a7fecb07e1fb7a32d5c1e9e8) Signed-off-by: Christopher Faulet (cherry picked from commit 9f8149ff4ad693d6a4db2f1dbd9704e1ac1a97ba) Signed-off-by: Christopher Faulet --- src/haproxy.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/haproxy.c b/src/haproxy.c index 7ce80a1..dd8854b 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1966,7 +1966,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(); @@ -1978,22 +1979,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 @@ -2002,10 +2008,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) { -- 1.7.10.4