From: Amaury Denoyelle Date: Wed, 11 Oct 2023 15:32:04 +0000 (+0200) Subject: BUG/MINOR: mux-quic: fix free on qcs-new fail alloc X-Git-Tag: v2.9-dev8~73 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10dab4af983630aadb134fc4fcc3f770b8f1a6b9;p=thirdparty%2Fhaproxy.git BUG/MINOR: mux-quic: fix free on qcs-new fail alloc qcs_new() allocates several elements in intermediary steps. All elements must first be properly initialized to be able to free qcs instance in case of an intermediary failure. Previously, qc_stream_desc allocation was done in the middle of qcs_new() before some elements initializations. In case this fails, a crash can happened as some elements are left uninitialized. To fix this, move qc_stream_desc allocation at the end of qcs_new(). This ensures that all qcs elements are initialized first. This should be backported up to 2.6. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 5be382fab4..429b22f9cb 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -112,16 +112,6 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type) qcs->id = qcs->by_id.key = id; eb64_insert(&qcc->streams_by_id, &qcs->by_id); - /* Allocate transport layer stream descriptor. Only needed for TX. */ - if (!quic_stream_is_uni(id) || !quic_stream_is_remote(qcc, id)) { - struct quic_conn *qc = qcc->conn->handle.qc; - qcs->stream = qc_stream_desc_new(id, type, qcs, qc); - if (!qcs->stream) { - TRACE_ERROR("qc_stream_desc alloc failure", QMUX_EV_QCS_NEW, qcc->conn, qcs); - goto err; - } - } - /* If stream is local, use peer remote-limit, or else the opposite. */ if (quic_stream_is_bidi(id)) { qcs->tx.msd = quic_stream_is_local(qcc, id) ? qcc->rfctl.msd_bidi_r : @@ -158,6 +148,16 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type) qcs->err = 0; + /* Allocate transport layer stream descriptor. Only needed for TX. */ + if (!quic_stream_is_uni(id) || !quic_stream_is_remote(qcc, id)) { + struct quic_conn *qc = qcc->conn->handle.qc; + qcs->stream = qc_stream_desc_new(id, type, qcs, qc); + if (!qcs->stream) { + TRACE_ERROR("qc_stream_desc alloc failure", QMUX_EV_QCS_NEW, qcc->conn, qcs); + goto err; + } + } + if (qcc->app_ops->attach && qcc->app_ops->attach(qcs, qcc->ctx)) { TRACE_ERROR("app proto failure", QMUX_EV_QCS_NEW, qcc->conn, qcs); goto err;