From: Amaury Denoyelle Date: Wed, 23 Sep 2026 13:28:29 +0000 (+0200) Subject: BUG/MINOR: mux_quic: report conn error on RESET_STREAM fctl violation X-Git-Tag: v3.5-dev9~180 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=1b2bd2aeef08209664585e4b3f230744835257d9;p=haproxy.git BUG/MINOR: mux_quic: report conn error on RESET_STREAM fctl violation When a RESET_STREAM is received, its announced final size must be taken into account in the connection flow control. This patch is a prerequisite prior to implement this accounting. It adds the mandatory check of the final size field to ensure it does not violate either the stream or the connection flow control. In case of invalid value, the connection is closed with FLOW_CONTROL_ERROR. This must be backported up to 2.8, after a period of observation. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index b9ae11551..86585999c 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -2321,6 +2321,7 @@ int qcc_recv_reset_stream(struct qcc *qcc, uint64_t id, uint64_t err, uint64_t f struct qcs *qcs; struct qc_stream_rxbuf *b; int prev_glitches = qcc->glitches; + uint64_t to_consume; TRACE_ENTER(QMUX_EV_QCC_RECV, qcc->conn); @@ -2362,12 +2363,28 @@ int qcc_recv_reset_stream(struct qcc *qcc, uint64_t id, uint64_t err, uint64_t f if (qcs->rx.offset_max > final_size || ((qcs->flags & QC_SF_SIZE_KNOWN) && qcs->rx.offset_max != final_size)) { - TRACE_ERROR("final size error on RESET_STREAM", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs); + TRACE_ERROR("final size error on RESET_STREAM", + QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV|QMUX_EV_PROTO_ERR, qcc->conn, qcs); qcc_set_error(qcc, QC_ERR_FINAL_SIZE_ERROR, 0, muxc_tevt_type_proto_err); goto err; } + /* Discarded data to account for in connection flow control. */ + to_consume = final_size - qcs->rx.offset; + + /* Ensure final size respects the current stream and connection flow control limits. */ + if (final_size > qcs->rx.msd || + qcc->lfctl.offsets_recv + to_consume > qcc->lfctl.md) { + TRACE_ERROR("flow control violation on RESET_STREAM final size", + QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV|QMUX_EV_PROTO_ERR, qcc->conn, qcs); + qcc_set_error(qcc, QC_ERR_FLOW_CONTROL_ERROR, 0, + muxc_tevt_type_proto_err); + goto err; + } + + qcc->lfctl.offsets_recv += to_consume; + qcs->flags |= QC_SF_SIZE_KNOWN|QC_SF_RECV_RESET; qcs_close_remote(qcs); /* Wakeup tasklet if QCS inserted in purge list. May happen after remote closure. */