From: Amaury Denoyelle Date: Thu, 22 Oct 2026 13:36:02 +0000 (+0200) Subject: BUG/MEDIUM: h3: prevent conn failure on trailers decoding without space X-Git-Tag: v3.5-dev10~67 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=8020cefc30ceadf61b45130609b90fdbb0741840;p=haproxy.git BUG/MEDIUM: h3: prevent conn failure on trailers decoding without space HTTP/3 trailers are decoded in function h3_trailers_to_htx(). If this fails due to a lack of space, a negative value is returned, resulting in a connection closed with INTERNAL_ERROR. This is incorrect as it could have occurred because of data not yet consumed in HTX output buffer. One solution would be to temporarily block demux when such situation is encountered. However, it is not easily implementable now since the introduction of http_trailers_to_htx() which is shared with HTTP/2 parser. A value HTTP_PRS_TOO_MANY can be caused either due to a transient lack of space. However, it is also used to report a number of decoded trailers exceeding tune.http.maxhdr configuration which is a fatal error. HTTP/2 parser does not have the same problem as it only starts decoding of trailers when output HTX buffer is empty. This is largely due to the fact that HPACK decoding cannot be rolled back after a transient error as it can have side effects related to dynamic table decoding. HTTP/3 is not concerned as QPACK dynamic table capability is not implemented. Thus, apply the same approach in HTTP/3: trailers decoding will be started only after HTX output buffer is emptied. Flag QC_SF_DEM_FULL is set to temporarily block demux if needed and 0 is returned from h3_trailers_to_htx(). Decoding will be retried after a successful read from the stream layer. This solution is in fact already used for HEADERS when dealing with intermediaries HTTP responses. Its impact is minimal given that trailers usage in H3 is rare. Also, it will simplify a future QPACK dynamic table implementation. This must be backported up to 2.8. --- diff --git a/src/h3.c b/src/h3.c index ab49739ba..564b654cd 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1562,6 +1562,14 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf, BUG_ON(!b_size(appbuf)); /* TODO */ htx = htx_from_buf(appbuf); data_ofs = htx->data; + /* Do not decode trailers if there is remaining data left, for similar + * reasons as h3_resp_headers_to_htx(). + */ + if (!htx_is_empty(htx)) { + qcs->flags |= QC_SF_DEM_FULL; + len = 0; + goto out; + } if (!h3s->data_len) { /* Notify that no body is present. This can only happens if