From: Amaury Denoyelle Date: Wed, 25 Jan 2023 16:44:36 +0000 (+0100) Subject: BUG/MEDIUM: mux-quic: fix crash on H3 SETTINGS emission X-Git-Tag: v2.8-dev3~91 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4d119f0c75ce7c5a977ece18dc975e14f9b460c;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-quic: fix crash on H3 SETTINGS emission A major regression was introduced by following patch commit 71fd03632fff43f11cebc6ff4974723c9dc81c67 MINOR: mux-quic/h3: send SETTINGS as soon as transport is ready H3 finalize operation is now called at an early stage in the middle of qc_init(). However, some qcc members are not yet initialized. In particular the stream tree which will cause a crash when H3 control stream will be accessed. To fix this, qcc_install_app_ops() has been delayed at the end of qc_init(). This ensures that qcc is properly initialized when app_ops operation are used. This must be backported wherever above patch is. For the record, it has been tagged up to 2.7. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index b7b843e357..401ccc0c10 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -875,13 +875,13 @@ int qcc_install_app_ops(struct qcc *qcc, const struct qcc_app_ops *app_ops) { TRACE_ENTER(QMUX_EV_QCC_NEW, qcc->conn); - qcc->app_ops = app_ops; - if (qcc->app_ops->init && !qcc->app_ops->init(qcc)) { + if (app_ops->init && !app_ops->init(qcc)) { TRACE_ERROR("app ops init error", QMUX_EV_QCC_NEW, qcc->conn); goto err; } TRACE_PROTO("application layer initialized", QMUX_EV_QCC_NEW, qcc->conn); + qcc->app_ops = app_ops; /* RFC 9114 7.2.4.2. Initialization * @@ -2100,12 +2100,6 @@ static int qc_init(struct connection *conn, struct proxy *prx, qcc->flags = 0; qcc->app_ops = NULL; - if (qcc_install_app_ops(qcc, conn->handle.qc->app_ops)) { - TRACE_PROTO("Cannot install app layer", QMUX_EV_QCC_NEW, qcc->conn); - /* prepare a CONNECTION_CLOSE frame */ - quic_set_connection_close(conn->handle.qc, quic_err_transport(QC_ERR_APPLICATION_ERROR)); - goto fail_no_tasklet; - } qcc->streams_by_id = EB_ROOT_UNIQUE; @@ -2205,17 +2199,26 @@ static int qc_init(struct connection *conn, struct proxy *prx, } HA_ATOMIC_STORE(&conn->handle.qc->qcc, qcc); + + if (qcc_install_app_ops(qcc, conn->handle.qc->app_ops)) { + TRACE_PROTO("Cannot install app layer", QMUX_EV_QCC_NEW, qcc->conn); + /* prepare a CONNECTION_CLOSE frame */ + quic_set_connection_close(conn->handle.qc, quic_err_transport(QC_ERR_APPLICATION_ERROR)); + goto fail_install_app_ops; + } + /* init read cycle */ tasklet_wakeup(qcc->wait_event.tasklet); TRACE_LEAVE(QMUX_EV_QCC_NEW, qcc->conn); return 0; + fail_install_app_ops: + if (qcc->app_ops && qcc->app_ops->release) + qcc->app_ops->release(qcc->ctx); fail_no_timeout_task: tasklet_free(qcc->wait_event.tasklet); fail_no_tasklet: - if (qcc->app_ops && qcc->app_ops->release) - qcc->app_ops->release(qcc->ctx); pool_free(pool_head_qcc, qcc); fail_no_qcc: TRACE_LEAVE(QMUX_EV_QCC_NEW);