From 8020cefc30ceadf61b45130609b90fdbb0741840 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Thu, 22 Oct 2026 15:36:02 +0200 Subject: [PATCH] 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. --- src/h3.c | 8 ++++++++ 1 file changed, 8 insertions(+) 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 -- 2.47.3