From: Amaury Denoyelle Date: Tue, 20 Jan 2026 18:00:37 +0000 (+0100) Subject: BUG/MEDIUM: mux-quic: prevent BUG_ON() on aborted uni stream close X-Git-Tag: v3.4-dev3~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7004be9640d6ccb0aa9e1fb15bfa38f6bff1ad3;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-quic: prevent BUG_ON() on aborted uni stream close When a QCS instance is fully closed on qcs_close_remote() invokation, it is moved into purg_list for later cleanup. This reuses list element, so a BUG_ON() ensures that QCS is not already present in send_list. This code is safe for bidirectional streams, as local channel is only closed after FIN or RESET_STREAM emission completion, so such QCS won't be present in the send_list on full closure. However, things are different for remote uni streams. As such streams do not have any local channel, qcs_close_remote() will always proceed to full closure. Most of the time this is fine, but the aformentionned BUG_ON() could be triggered if emission is required on a remote uni stream : this only happens after read was aborted and a STOP_SENDING frame is prepared. Fix this by adding an extra operation in qcs_close_remote() : on full close, STOP_SENDING is cancelled if it was prepared and the QCS instance is removed from send_list. This is safe as STOP_SENDING is unnecessary after the remote channel is closed. This operation is performed before purg_list insertion which prevents the BUG_ON() crash issue. This patch must be backported up to 3.1. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 1f11c4d59..2db2e3320 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -462,6 +462,13 @@ static void qcs_close_remote(struct qcs *qcs) qcs->st = QC_SS_CLO; } + /* Cancel STOP_SENDING emission as it is now unneeded. */ + if (qcs->st == QC_SS_CLO && (qcs->flags & QC_SF_TO_STOP_SENDING)) { + qcs->flags &= ~QC_SF_TO_STOP_SENDING; + /* Remove from send_list. Necessary to ensure BUG_ON() below is not triggered. */ + LIST_DEL_INIT(&qcs->el_send); + } + if (qcs_is_completed(qcs)) { BUG_ON(LIST_INLIST(&qcs->el_send)); TRACE_STATE("add stream in purg_list", QMUX_EV_QCS_RECV, qcs->qcc->conn, qcs);