From 97f2c2e56eb8d22b8181253968733e9b80d6cbae Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 20 Nov 2024 17:20:05 +0100 Subject: [PATCH] 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. (cherry picked from commit 785e63335374a6db8ef35205cdb36ea726710061) Signed-off-by: Christopher Faulet --- src/h3.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/h3.c b/src/h3.c index 2898b9e..35b9039 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; -- 1.7.10.4