From: Amaury Denoyelle Date: Fri, 15 Dec 2023 16:32:06 +0000 (+0100) Subject: BUG/MINOR: h3: properly handle alloc failure on finalize X-Git-Tag: v3.0-dev1~75 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7a3602a1f55dacda5a669865e04474f5d503bab7;p=thirdparty%2Fhaproxy.git BUG/MINOR: h3: properly handle alloc failure on finalize If H3 control stream Tx buffer cannot be allocated, return a proper errur through h3_finalize(). This will cause the emission of a CONNECTION_CLOSE with error H3_INTERNAL_ERROR and closure of the whole connection. This should be backported up to 2.6. Note that 2.9 has some difference which will cause conflict. The main one is that qcc_get_stream_txbuf() does not exist in this version. Instead the check in h3_control_send() should be made after mux_get_buf(). Finally, it may be useful to first pick previous commit (MINOR: h3: add traces for connection init stage) to improve context similarity. --- diff --git a/src/h3.c b/src/h3.c index e878beb5bb..9269116640 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1418,7 +1418,11 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin) return -1; } -/* Function used to emit stream data from control uni-stream */ +/* Function used to emit stream data from control uni-stream. + * + * On success return the number of sent bytes. A negative code is used on + * error. + */ static int h3_control_send(struct qcs *qcs, void *ctx) { int ret; @@ -1456,7 +1460,11 @@ static int h3_control_send(struct qcs *qcs, void *ctx) b_quic_enc_int(&pos, h3_settings_max_field_section_size, 0); } - res = qcc_get_stream_txbuf(qcs); + if (!(res = qcc_get_stream_txbuf(qcs))) { + TRACE_ERROR("cannot allocate Tx buffer", H3_EV_TX_FRAME|H3_EV_TX_SETTINGS, qcs->qcc->conn, qcs); + goto err; + } + if (b_room(res) < b_data(&pos)) { // TODO the mux should be put in blocked state, with // the stream in state waiting for settings to be sent @@ -1472,6 +1480,10 @@ static int h3_control_send(struct qcs *qcs, void *ctx) TRACE_LEAVE(H3_EV_TX_FRAME|H3_EV_TX_SETTINGS, qcs->qcc->conn, qcs); return ret; + + err: + TRACE_DEVEL("leaving on error", H3_EV_TX_FRAME|H3_EV_TX_SETTINGS, qcs->qcc->conn, qcs); + return -1; } static int h3_resp_headers_send(struct qcs *qcs, struct htx *htx) @@ -2226,9 +2238,11 @@ static int h3_finalize(void *ctx) goto err; } - h3_control_send(qcs, h3c); h3c->ctrl_strm = qcs; + if (h3_control_send(qcs, h3c) < 0) + goto err; + TRACE_LEAVE(H3_EV_H3C_NEW, qcc->conn); return 0;