From 10dab4af983630aadb134fc4fcc3f770b8f1a6b9 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Wed, 11 Oct 2023 17:32:04 +0200 Subject: [PATCH] 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. --- src/mux_quic.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mux_quic.c b/src/mux_quic.c index 5be382fab..429b22f9c 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;