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.
This commit is contained in:
Christopher Faulet 2024-11-20 17:20:05 +01:00
parent 63d2760dfa
commit 785e633353
1 changed files with 14 additions and 2 deletions

View File

@ -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;