From: Christopher Faulet Date: Wed, 20 Nov 2024 16:20:05 +0000 (+0100) Subject: BUG/MEDIUM: h3: Properly limit the number of headers received X-Git-Tag: v3.1-dev14~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=785e63335374a6db8ef35205cdb36ea726710061;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: h3: Properly limit the number of headers received The number of headers are limited before the decoding but pseudo headers and cookie headers consume extra slots. In practice, this lowers the maximum number of headers that can be received. To workaround this issue, the limit is doubled during the frame decoding to be sure to have enough extra slots. And the number of headers is tested against the configured limit after the HTX message was created to be able to report an error. Unfortunatly no parsing error are reported because the QUIC multiplexer is not able to do so for now. The same is performed on trailers to be consistent with H2. This patch should be backported as far as 2.6. --- diff --git a/src/h3.c b/src/h3.c index 9d8a73e15c..59b632d1d8 100644 --- a/src/h3.c +++ b/src/h3.c @@ -525,7 +525,7 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, struct buffer *tmp = get_trash_chunk(); struct htx *htx = NULL; struct htx_sl *sl; - struct http_hdr list[global.tune.max_http_hdr]; + struct http_hdr list[global.tune.max_http_hdr * 2]; unsigned int flags = HTX_SL_F_NONE; struct ist meth = IST_NULL, path = IST_NULL; struct ist scheme = IST_NULL, authority = IST_NULL; @@ -898,6 +898,12 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, } } + /* Check the number of blocks agains "tune.http.maxhdr" value before adding EOH block */ + if (htx_nbblks(htx) > global.tune.max_http_hdr) { + len = -1; + goto out; + } + if (!htx_add_endof(htx, HTX_BLK_EOH)) { len = -1; goto out; @@ -962,7 +968,7 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf, struct buffer *appbuf = NULL; struct htx *htx = NULL; struct htx_sl *sl; - struct http_hdr list[global.tune.max_http_hdr]; + struct http_hdr list[global.tune.max_http_hdr * 2]; int hdr_idx, ret; const char *ctl; int qpack_err; @@ -1080,6 +1086,12 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf, ++hdr_idx; } + /* Check the number of blocks agains "tune.http.maxhdr" value before adding EOT block */ + if (htx_nbblks(htx) > global.tune.max_http_hdr) { + len = -1; + goto out; + } + if (!htx_add_endof(htx, HTX_BLK_EOT)) { TRACE_ERROR("cannot add trailer", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs); len = -1;