From d6e581de4be1d3564d771056303242c9ae930c40 Mon Sep 17 00:00:00 2001 From: Emeric Brun Date: Tue, 13 Sep 2022 16:16:30 +0200 Subject: [PATCH] BUG/MEDIUM: sink: bad init sequence on tcp sink from a ring. The init of tcp sink, particularly for SSL, was done too early in the code, during parsing, and this can cause a crash specially if nbthread was not configured. This was detected by William using ASAN on a new regtest on log forward. This patch adds the 'struct proxy' created for a sink to a list and this list is now submitted to the same init code than the main proxies list or the log_forward's proxies list. Doing this, we are assured to use the right init sequence. It also removes the ini code for ssl from post section parsing. This patch should be backported as far as v2.2 Note: this fix uses 'goto' labels created by commit 'BUG/MAJOR: log-forward: Fix log-forward proxies not fully initialized' but this code didn't exist before v2.3 so this patch needs to be adapted for v2.2. --- include/haproxy/sink.h | 2 ++ src/cfgparse.c | 8 ++++++++ src/sink.c | 14 ++++++-------- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/haproxy/sink.h b/include/haproxy/sink.h index 51d507ce7..a9f809930 100644 --- a/include/haproxy/sink.h +++ b/include/haproxy/sink.h @@ -28,6 +28,8 @@ extern struct list sink_list; +extern struct proxy *sink_proxies_list; + struct sink *sink_find(const char *name); struct sink *sink_new_fd(const char *name, const char *desc, enum log_fmt, int fd); ssize_t __sink_write(struct sink *sink, const struct ist msg[], size_t nmsg, diff --git a/src/cfgparse.c b/src/cfgparse.c index 4201c1354..171982c0b 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -3911,6 +3912,13 @@ out_uri_auth_compat: goto init_proxies_list_stage1; } + if (init_proxies_list == cfg_log_forward) { + init_proxies_list = sink_proxies_list; + /* check if list is not null to avoid infinite loop */ + if (init_proxies_list) + goto init_proxies_list_stage1; + } + /***********************************************************/ /* At this point, target names have already been resolved. */ /***********************************************************/ diff --git a/src/sink.c b/src/sink.c index 2eb050a16..29c38764d 100644 --- a/src/sink.c +++ b/src/sink.c @@ -41,6 +41,9 @@ struct list sink_list = LIST_HEAD_INIT(sink_list); +/* sink proxies list */ +struct proxy *sink_proxies_list; + struct sink *cfg_sink; struct sink *sink_find(const char *name) @@ -287,7 +290,7 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc void sink_setup_proxy(struct proxy *px) { px->last_change = now.tv_sec; - px->cap = PR_CAP_FE | PR_CAP_BE; + px->cap = PR_CAP_FE | PR_CAP_BE | PR_CAP_INT; px->maxconn = 0; px->conn_retries = 1; px->timeout.server = TICK_ETERNITY; @@ -295,6 +298,8 @@ void sink_setup_proxy(struct proxy *px) px->timeout.connect = TICK_ETERNITY; px->accept = NULL; px->options2 |= PR_O2_INDEPSTR | PR_O2_SMARTCON | PR_O2_SMARTACC; + px->next = sink_proxies_list; + sink_proxies_list = px; } /* @@ -1223,13 +1228,6 @@ int cfg_post_parse_ring() srv = cfg_sink->forward_px->srv; while (srv) { struct sink_forward_target *sft; - /* init ssl if needed */ - if (srv->use_ssl == 1 && xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv) { - if (xprt_get(XPRT_SSL)->prepare_srv(srv)) { - ha_alert("unable to prepare SSL for server '%s' in ring '%s'.\n", srv->id, cfg_sink->name); - err_code |= ERR_ALERT | ERR_FATAL; - } - } /* allocate sink_forward_target descriptor */ sft = calloc(1, sizeof(*sft));