]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux_quic: fix freeze transfer after QCS rxbuf realign
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 16 Jun 2026 15:10:50 +0000 (17:10 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 16 Jun 2026 16:00:13 +0000 (18:00 +0200)
QCS uses a multiple Rx buffer for incoming data to decode. However this
may cause the app proto layer to block on decoding if some data are
splitted across two buffers. In this case qcs_transfer_rx_data() is used
to move the data in the same current buffer.

However, this function contains a bug as the next Rx buffer is not
reinserted as expected in the QCS tree after the move operation. This
can cause data loss which will cause a transfer freeze. This may affect
POST requests on the frontend side as well as most backend transfers.

This patch fixes the reinsert operation. It is now performed as expected
if the next rxbuf is not fully truncated. In the opposite case, the
rxbuf can simply be freed completely.

This must be backported up to 3.2.

src/mux_quic.c

index 509e3aa7afe1398648eb85ae5521215637bb4366..c8a880450f2d6e4ace38234a6d6a1fcb5dcf5092 100644 (file)
@@ -1268,10 +1268,11 @@ static int qcs_transfer_rx_data(struct qcs *qcs, struct qc_stream_rxbuf *rxbuf)
                rxbuf->off_end = qcs->rx.offset + b_data(&b) + to_copy;
                eb64_insert(&qcs->rx.bufs, &rxbuf->off_node);
 
+               /* Increment next rxbuf offset. This must not exceed off_end. */
                rxbuf_next->off_node.key += to_copy;
                BUG_ON(rxbuf_next->off_node.key > rxbuf_next->off_end);
-
-               if (rxbuf_next->off_node.key == rxbuf_next->off_end) {
+               /* Now reinsert next rxbuf unless it has been completely truncated. */
+               if (rxbuf_next->off_node.key < rxbuf_next->off_end) {
                        eb64_insert(&qcs->rx.bufs, &rxbuf_next->off_node);
                }
                else {