]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: mux-quic: fix crash with app ops install failure
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 19 Apr 2023 15:58:39 +0000 (17:58 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 20 Apr 2023 12:49:32 +0000 (14:49 +0200)
On MUX initialization, the application layer is setup via
qcc_install_app_ops(). If this function fails MUX is deallocated and an
error is returned.

This code path causes a crash before connection has been registered
prior into the mux_stopping_data::list for stopping idle frontend conns.
To fix this, insert the connection later in qc_init() once no error can
occured.

The crash was seen on the process closing with SUGUSR1 with a segfault
on mux_stopping_process(). This was reproduced using -dMfail.

This regression was introduced by the following patch :
  commit b4d119f0c75ce7c5a977ece18dc975e14f9b460c
  BUG/MEDIUM: mux-quic: fix crash on H3 SETTINGS emission

This should be backported up to 2.7.

src/mux_quic.c

index 291f4b3bbb633fed387429a4383b4eda7a0482e0..a74aa95809f3e5912609dcaa052b5151f991bff5 100644 (file)
@@ -2379,13 +2379,6 @@ static int qc_init(struct connection *conn, struct proxy *prx,
        qcc_reset_idle_start(qcc);
        LIST_INIT(&qcc->opening_list);
 
-       if (!conn_is_back(conn)) {
-               if (!LIST_INLIST(&conn->stopping_list)) {
-                       LIST_APPEND(&mux_stopping_data[tid].list,
-                                   &conn->stopping_list);
-               }
-       }
-
        HA_ATOMIC_STORE(&conn->handle.qc->qcc, qcc);
 
        if (qcc_install_app_ops(qcc, conn->handle.qc->app_ops)) {
@@ -2398,6 +2391,10 @@ static int qc_init(struct connection *conn, struct proxy *prx,
        if (qcc->app_ops == &h3_ops)
                proxy_inc_fe_cum_sess_ver_ctr(sess->listener, prx, 3);
 
+       /* Register conn for idle front closing. This is done once everything is allocated. */
+       if (!conn_is_back(conn))
+               LIST_APPEND(&mux_stopping_data[tid].list, &conn->stopping_list);
+
        /* init read cycle */
        tasklet_wakeup(qcc->wait_event.tasklet);