From: Amaury Denoyelle Date: Wed, 1 Jul 2026 14:19:26 +0000 (+0200) Subject: BUG/MEDIUM: h3: fix parser desync on error with multiple frames X-Git-Url: http://git.kaiwu.me/%22data:,/static/gitweb.js?a=commitdiff_plain;h=7f416252b524d12865f390d123586df322de9d67;p=haproxy.git BUG/MEDIUM: h3: fix parser desync on error with multiple frames On success, h3_rcv_buf() returns the number of parsed STREAM bytes which are removed by the caller afterwards. A success value is mandatory so that the underlying QUIC packet is acknowledged. When H3 parser detects an error during HEADERS or DATA parsing, the stream or the connetcion is flagged for closure. If there is remaining frames, they are simply ignored and h3_rcv_buf() returns the remaining input buffer size. However, this value is wrong in case one or several frames were already parsed before the invalid frame in the same h3_rcv_buf() invokation. This instructs caller to only remove a subset of the data and parsing is restarted on a random boundary. Most of the times this generates again a new final yet invalid error, possibly overwriting a stream error with a full connection closure. This patch fixes the return value in case of an error during HEADERS or DATA parsing by ensuring that total variable is always incremented instead of being directly assigned. This must be backported up to 2.8. --- diff --git a/src/h3.c b/src/h3.c index ed581e26a..9876b6aaf 100644 --- a/src/h3.c +++ b/src/h3.c @@ -2113,12 +2113,12 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin) (h3s->err == H3_ERR_REQUEST_REJECTED) ? 0 : se_tevt_type_proto_err; qcc_abort_stream_read(qcs); qcc_reset_stream(qcs, h3s->err, tevt); - total = b_data(b); + total += b_data(b); goto done; } else if (h3c->err) { qcc_set_error(qcs->qcc, h3c->err, 1, muxc_tevt_type_proto_err); - total = b_data(b); + total += b_data(b); goto done; } else if (unlikely(ret < 0)) {