]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: sink: bad init sequence on tcp sink from a ring.
authorEmeric Brun <ebrun@haproxy.com>
Tue, 13 Sep 2022 14:16:30 +0000 (16:16 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Tue, 13 Sep 2022 15:03:30 +0000 (17:03 +0200)
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
src/cfgparse.c
src/sink.c

index 51d507ce739379e106d0d5ae444a075af4acffd2..a9f8099303bc622f69956ca57cc9c76791e508de 100644 (file)
@@ -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,
index 4201c1354183604c69eae6166e2748d15de832d0..171982c0bb0c14a0e404d79c2f4f22c04ab312e3 100644 (file)
@@ -66,6 +66,7 @@
 #include <haproxy/lb_map.h>
 #include <haproxy/listener.h>
 #include <haproxy/log.h>
+#include <haproxy/sink.h>
 #include <haproxy/mailers.h>
 #include <haproxy/namespace.h>
 #include <haproxy/quic_sock.h>
@@ -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. */
        /***********************************************************/
index 2eb050a16dabaf277b7d0bfc7915e8fe7025ae45..29c38764db973c9cb8d0bd7e8f0eb4550978dc78 100644 (file)
@@ -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));