From: Amaury Denoyelle Date: Thu, 20 Jun 2024 12:41:22 +0000 (+0200) Subject: BUG/MINOR: mux-quic: fix crash on qcs SD alloc failure X-Git-Tag: v3.1-dev2~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3aded1d3752a12af9b8e48f445218230e6967a06;p=thirdparty%2Fhaproxy.git BUG/MINOR: mux-quic: fix crash on qcs SD alloc failure Since the following commit, sedesc are created since QCS instantiation in qcs_new(). 086e51017e7731ee9820b882fe6e8cc5f0dd5352 BUG/MEDIUM: mux-quic: Create sedesc in same time of the QUIC stream However, sedesc is initialized before other QCS mandatory fields. If sedesc allocation fails, a crash would occur on qcs_free() invocation for QCS early release. To fix this, delay sedesc allocation until function end. This bug was detected using -dMfail. This should be backported up to 2.6. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 97cfb27ce0..2b408cecf6 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -104,17 +104,6 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type) qcs->st = QC_SS_IDLE; qcs->ctx = NULL; - qcs->sd = sedesc_new(); - if (!qcs->sd) - goto err; - qcs->sd->se = qcs; - qcs->sd->conn = qcc->conn; - se_fl_set(qcs->sd, SE_FL_T_MUX | SE_FL_ORPHAN | SE_FL_NOT_FIRST); - se_expect_no_data(qcs->sd); - - if (!(global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD_QUIC_SND)) - se_fl_set(qcs->sd, SE_FL_MAY_FASTFWD_CONS); - /* App callback attach may register the stream for http-request wait. * These fields must be initialed before. */ @@ -159,6 +148,17 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type) qcs->err = 0; + qcs->sd = sedesc_new(); + if (!qcs->sd) + goto err; + qcs->sd->se = qcs; + qcs->sd->conn = qcc->conn; + se_fl_set(qcs->sd, SE_FL_T_MUX | SE_FL_ORPHAN | SE_FL_NOT_FIRST); + se_expect_no_data(qcs->sd); + + if (!(global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD_QUIC_SND)) + se_fl_set(qcs->sd, SE_FL_MAY_FASTFWD_CONS); + /* 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;